Content Application Developer Manual / Version 2406.0
Table Of Contents
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 startup of the
ApplicationContext
.
The recommended way is to use Spring Java configuration and to annotate beans acting as customization sources
using the annotation class
com.coremedia.springframework.customizer.Customize
.
However, a customizer can also be declared in a Spring XML file.
Examples
@Configuration(proxyBeanMethods = false) static class AddEntriesToSomeMap { @Bean @Customize("someMap") Map<String, String> append() { return ImmutableMap.of("key1", "value1", "key2", "value2"); } }
Here, two more entries key1
and key2
are added to a bean from the type
Map
.
Although the recommended way to replace a predefined way is to use Spring Primary
annotation
(or XML attribute), there is also a customizer to replace the target bean:
@Configuration(proxyBeanMethods = false) static class ReplaceLoginInterceptor { @Bean @Customize(value = "loginInterceptor", mode = Customize.Mode.REPLACE) MyLoginInterceptor myLoginInterceptor() { return new MyLoginInterceptor(); } }
Here, a predefined bean loginInterceptor
is replaced with the bean
myLoginInterceptor
.
XML Syntax
Note
Important: The recommended way to customize beans provided by CoreMedia applications is to use the first mechanism of the following list that can be applied to the target bean.
Use external configuration (for example, system properties) to configure the bean.
Override injection of the target bean by using Spring's
Primary
annotation (or XML attribute).Define a source bean in Spring Java configuration style (for example, using
Component
/ComponentScan orConfiguration
/Bean
) and add theCustomize
annotation.- Only use the XML customizers if none of the above can be used in your project.
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" intoWrapperService
.:
<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.