Spring Managed HST Components - BloomReach Experience - Open Source CMS

This article covers a Hippo CMS version 11. There's an updated version available that covers our most recent release.

26-09-2018

Spring Managed HST Components

Since Hippo CMS 11, HST supports Spring Framework managed HST Component beans without having to use Spring Bean Bridge anymore.
Container Level Integration, a different pattern of integration, is also supported. See HST Container Integration with Other Web Application Frameworks for more information.

Container Level Support for Spring Framework Managed HST Components

Since Hippo CMS 11, HST Container can get a reference to an HST Component bean maintained by Spring Framework ApplicationContext and use the bean, instead of creating an object by itself from hst:componentclassname property value.

Suppose you have the following HST Component configuration in HST configurations in repository:

<sv:node sv:name="content">
  <sv:property sv:name="jcr:primaryType" sv:type="Name">
    <sv:value>hst:component</sv:value>
  </sv:property>
  <sv:property sv:name="hst:componentclassname" sv:type="String">
    <sv:value>org.hippoecm.hst.demo.components.Search</sv:value>
  </sv:property>
  <!-- SNIP -->
</sv:node>

Until Hippo CMS 10.x, HST Container creates an object by the class name (org.hippoecm.hst.demo.components.Search in this example).

Since Hippo CMS 11, HST Container looks up its ComponentManager (internally backed by Spring Framework ApplicationContext) first to find a bean named by the class name (org.hippoecm.hst.demo.components.Search in this example). If a bean by the name is found, then HST Container uses the bean instead of creating a new object. If not found, it creates an HST Component object by itself like it does in Hippo CMS 10.x or earlier versions.

By letting Spring Framework maintain your HST Component beans, you may take advantage of many good features of Spring Framework such as AOP techniques on your HST Components.

How-to with A Simple Example in Hippo Test Suite

If you want to see a demo, build and run the demo in the Hippo Test Suite project. The example is available in our source repository: Hippo Test Suite.

Next, click on the Search link on the left menu of the example website (http://localhost:8080/site/search). You will see a page containing search forms.

HST Component Class with Spring Framework Annotations

For the search page, the following HST Component was implemented in the Hippo Test Suite project:

components/src/main/java/org/hippoecm/hst/demo/components/Search.java

package org.hippoecm.hst.demo.components;

import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

/**
 * This HstComponent is annotated with {@link Component}.
 * <P>
 * Note: HstComponent bean must always be {@link ConfigurableBeanFactory.SCOPE_PROTOTYPE} like this example.
 * Otherwise, thread-safety issue can occur due to a singleton bean instance of HstComponent.
 * Also, the bean name (set by {@link Service} annotation) must be the FQCN of this component class
 * because the component class is scanned for component parameters in many other locations in HST Container.
 * </P>
 */
@Component(DemoConstants.COMPONENT_BASE_PACKAGE + ".Search")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class Search extends AbstractSearchComponent {
  // -->8-->8--
}

The Search class now has several Spring Framework annotations. Those annotations are needed when you want to take advantage of Spring Framework Automatic Component Scanning feature:

  • @Scope annotation is required and it must be set to ConfigurableBeanFactory.SCOPE_PROTOTYPE.
  • @Component annotation is required and it must be set to the FQCN of the class. You must not set to something else different than the FQCN of the HST component class because the raw class is also scanned by other HST Container components (e.g., for ParametersInfo proxy dynamic generation at runtime). In this specific example, DemoConstants.COMPONENT_BASE_PACKAGE + ".Search" is the same as org.hippoecm.hst.demo.components.Search.
NOTE: Again, the Search HST Component example shown above is always scoped to "prototype". By scoping the bean as "prototype", you can set multiple HST Component configurations with different instances to share single bean definition. If you use "singleton" (default) scoped bean, then you should add a different bean definition per HST Component configuration using different hst:componentclassname property values, in order not to have parameter collisions between different component configurations.

Enabling Spring Framework Automatic Component Scanning

Now, we need to enable Spring Framework Automatic Component Scanning in initializing HST Container Component Manager. You can simply add the following in an XML file under site/src/main/resources/META-INF/hst-assembly/overrides/ folder. In the Hippo Test Suite project, it is included in components/src/main/resources/hst-assembly/overrides/components.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
                           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">

  <!-- (HST)Components Annotation Scanning -->
  <context:component-scan base-package="org.hippoecm.hst.demo.components" />

  <-- SNIP -->

</beans>

When HST Container and its ComponentManager are initialized, Spring Framework will scan all the available components under the package org.hippoecm.hst.demo.components and register all the scanned beans. In this specific example, it will register a bean named org.hippoecm.hst.demo.components.Search, and later when HST Container needs to invoke the Search HST Component (as configured in the component configuration in the repository as shown above), it simply gets a reference to the existing bean instead of creating a new object by the class name by itself.

Summary

Since Hippo CMS 11, HST Container can get a reference to a bean maintained by Spring Framework, instead of creating an object by itself. In the perspective of HST Component configurations in the repository, there is no change from the traditional way of configuring component class name with hst:componentclassname property value. However, HST Container looks up a bean by the hst:componentclassname property value first from the ComponentManager (backed by Spring Framework ApplicationContext). If found, it simply uses the bean. Otherwise, it creates a new object like it does in CMS 10 or earlier versions.

When you want to take advantage of Spring Framework Automatic Component Scanning feature, you should use @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) and @Component(<FQCN>) annotations and enable the automatic scanning by adding <context:component-scan base-package="..." /> in an overriding bean assembly XML file.

By letting Spring Framework maintain your HST Component beans, you may take advantage of many good features of Spring Framework such as AOP techniques on your HST Components. See the examples in the Hippo Test Suite project for more detail.

Did you find this page helpful?
How could this documentation serve you better?
On this page
    Did you find this page helpful?
    How could this documentation serve you better?