loading table of contents...

5.1. Customizer

A Customizer is a mechanism, which enables you to change an existing bean definition without touching the actual configuration file of the bean. Technically speaking, a Customizer is a BeanPostProcessor bean, which adjusts the bean during creation of the ApplicationContext. The declaration of a Customizer uses the "Extensible XML Authoring" (see http://docs.spring.io/spring/docs/current/spring-framework-reference/html/extensible-xml.html for details) which enables you to write compact bean definitions.

Examples:
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:customize="http://www.coremedia.com/2007/
      coremedia-spring-beans-customization
  xsi:schemaLocation="
      http://www.coremedia.com/2007/
       coremedia-spring-beans-customization
      http://www.coremedia.com/2007/
       coremedia-spring-beans-customization.xsd">

 <bean id="someService" class="com.mycompany.Service">
  <property name="enable" value="false"/>
 </bean>
 <customize:replace id="enableSomeService" bean="someService"
                    property="enable"
                    custom-value="true"/>
</beans>

Here, the property enable of the bean someService is set to "true".

…
<customize:append id="addEntriesToSomeMap" bean="someMap">
<map>
  <entry key="key1" value="value1"/>
  <entry key="key2" value="value2"/>
</map>
</customize:append>
…

Here, two more entries key1 and key2 are added to a bean from the type Map.

<bean id="myLoginInterceptor"
      class="my.interceptors.MyLoginInterceptor/>
  ...
<customize:replace id="registerMyLoginInterceptor"
                   bean="loginInterceptor"
                   custom-ref="myLoginInterceptor"/>

Here, a predefined bean loginInterceptor is replaced with the bean myLoginInterceptor.

Syntax

The syntax to define a Customizer are as follows (id attribute omitted):

<customize:operation
              bean="beanname" [property="propertyname"]
              custom-value="value"/>

or

<customize:operation
              bean="beanname" [property="propertyname"]
              custom-ref="custom-beanname"/>

or

<customize:operation bean="beanname" [property="propertyname"]>
    <bean, map, set, list or properties>
</customize:operation>

Basically, an operation (<customize:operation>) is performed on a bean (bean="...") or on a property of a bean (bean=".." property="..."). As a parameter of an operation, you can use a value (custom-value="...") or a reference to a bean (custom-ref="..."). Instead of a bean reference, you can also use an element <map>, <list>, <set>, <properties> or <bean> as a parameter. The customizer can be disabled by an attribute enabled="false".

The following operations are supported:

  • Replace - Depending on the context, a bean will be replaced by another bean with the same name or a bean property will be set to another value.

  • Append/Prepend - This operation works on beans or properties which are comprised of multiple elements, thus are of type List, Set, Map, String array and the like. The elements you add must be wrapped with the type of the property or bean that you modify (such as list, map or set). As you can see in the listing beneath you can not add an element directly, but instead, even if it is only one element that you wish to add, you have to wrap it. You can add elements to the start ("prepend") or end ("append").

<customize:append id="registerMyService" bean="myServices"
                  property="serviceList">
  <list>
    <ref bean="myServiceBeanId">
  </list>
</customize:append>
  • Wrap - This operation wraps a bean by another bean: It replaces a bean and injects the original bean into the new bean. The following example replaces the bean "service" by an instance of WrapperService and injects the original "service" bean as a property "delegate" into WrapperService.:

<customize:wrap id="wrapService" bean="service"
                wrapper-property="delegate">
  <bean class="com.mycompany.WrapperService"/>
</customize:wrap>

If different customizers work on the same bean or property, conflicts may arise. Therefore, you can use the attribute order to define the order of execution of the customizers.

<customize:replace id="registerMyService-1" bean="myService"
                   property="name"
                   custom-value="myService-1"
                   order="10"/>
<customize:replace id="registerMyService-2" bean="myService"
                   property="name"
                   custom-value="myService-2"
                   order="20"/>

The example shows two customizers, both working on the property name of the bean myService. Due to the lower order value (10), the first customizer has a higher priority and is executed first. Afterwards, the second customizer overwrites this setting again.