Tuesday, December 13, 2011

Spring 3 to the rescue

If you use Spring in your applications, you may need to pass some settings to a spring bean. Your settings can be defined in properties files, in system properties or inside an internal storage.

Let's say we want to use a property inside a spring bean like the following:
<bean id="myBean" class="com.mypackage.MyClass">
        <property name="myProperty">
            <value>${propertyValue}</value>
        </property>
</bean>

If propertyValue is defined inside a properties file we should define a propertyConfigurer bean:
<bean id="propertyConfigurer" 
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location">
            <value>classpath:myfile.properties</value>
        </property>
</bean>

If we want propertyValue to be overridden by system properties we can specify  systemPropertiesModeName :
<bean id="propertyConfigurer" 
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location">
            <value>classpath:myfile.properties</value>
        </property>
        <property name="systemPropertiesModeName">
            <value>SYSTEM_PROPERTIES_MODE_OVERRIDE</value>
        </property>
</bean>

If our settings   are defined inside a storage system (database, content repository), spring 3 will help us a lot with its new expression language SpEL. This allows for calling methods from a defined spring bean.

Lets say we have a settings bean like the following, were storageService  can be any storage you need:
<bean id="settings" class="com.mypackage.SettingsBean">
        <property name="storageService" ref="storageService"></property>
</bean>

SettingBean will offer us the propertyValue we need :

public class SettingsBean {
    
    private StorageService storageService;    
    
    public Settings getSettings() {
        return storageService.getSettings();
    }    

    @Required
    public void setStorageService(StorageService storageService) {
        this.storageService = storageService;        
    }
    
    // helper methods used in Spring with SpEL    
    public String getPropertyValue() {
        Settings settings = getSettings();
        return settings.getPropertyValue();
    }
}

With SpEL we can use the propertyValue in our bean like this:
<bean id="myBean" class="com.mypackage.MyClass">
        <property name="myProperty" value="#{settings.getPropertyValue()}"/>
</bean>

If the bean, which needs some settings from a storage, is a bean from the spring api, then it's very easy to set the properties using SpEL . Otherwise we would have had to extend that class to inject our storage. For example a Spring ThreadPoolTaskExecutor can be defined like this :

<bean id="schedulingTaskExecutor"
    class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <property name="threadNamePrefix" value="Scheduler-"/>
        <property name="corePoolSize" value="#{settings.getSchedulerCorePoolSize()}"/>
        <property name="maxPoolSize" value="#{settings.getSchedulerMaxPoolSize()}"/>
        <property name="queueCapacity" value="#{settings.getSchedulerQueueCapacity()}"/>
</bean>

No comments: