Externalizing properties in Spring is easy if you are using an ApplicationContext as your Spring container. You use Spring’s PropertyPlaceholderConfigurer to tell Spring to load certain configuration from an external property file.
single property file
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>jdbc.properties</value>
</property>
</bean>
multi property file
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>jdbc.properties</value>
<value>security.properties</value>
<value>application.properties</value>
</list>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url">
<value>${database.url}</value>
</property>
<property name="driverClassName">
<value>${database.driver}</value>
</property>
<property name="username">
<value>${database.user}</value>
</property>
<property name="password">
<value>${database.password}</value>
</property>
</bean>
The java.beans.PropertyEditor interface provides a means to customize how String values are mapped to non-String types. There is a convenience implementation of this interface—java.beans.PropertyEditorSupport—that has two methods of
interest to us:
■ getAsText()returns the String representation of a property’s value.
■ setAsText(String value) sets a bean property value from the String value passed in.
Spring comes with several custom editors based on PropertyEditorSupport,including org.springframework.beans.propertyeditors.URLEditor, which is the custom editor used to convert Strings to and from java.net.URL objects.Some other custom editors that come with Spring include
■ ClassEditor—Sets a java.lang.Class property from a String value that contain the fully qualified class name
■ CustomDateEditor—Sets a java.util.Date property from a String using a custom java.text.DateFormat object
■ FileEditor—Sets a java.io.File property from a String value that contains a file’s path
■ LocaleEditor—Sets a java.util.Locale property from a String value that contains a textual representation of the locale (i.e., “en_US”)
■ StringArrayPropertyEditor—Converts a comma-delimited String to a String array property
■ StringTrimmerEditor—Automatically trims String properties with an option to convert empty String values to null
To use ResourceBundleMessageSource, add the following to the bean wiring file:
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename">
<value>trainingtext</value>
</property>
</bean>
Locale locale = … ; //determine locale
String text =
context.getMessage("computer", new Object[0], locale);
In the course of an application’s lifetime, the ApplicationContext will publish a handful of events that tell interested listeners what’s going on. These events are all subclasses of the abstract class org.springframework.context.Application-
Event. Three such application events are
■ ContextClosedEvent—Published when the application context is closed
■ ContextRefreshedEvent—Published when the application context is initialized or refreshed
■ RequestHandledEvent—Published within a web application context when a request is handled
If you want a bean to respond to application events, all you need to do is implement the org.springframework.context.ApplicationListener interface.
The only thing you need to do to tell Spring about an application event listener is to simply register it as a bean within the context:
<bean id="refreshListener" class="com.springinaction.foo.RefreshListener"/>
in the case of Spring beans, comes in the form of the BeanNameAware, BeanFactoryAware, and ApplicationContextAware interfaces.
With AOP, you still define the common functionality in one place, but you can declaratively define how and where this functionality is applied without having to modify the class to which you are applying the new feature. Cross-cutting concerns can now be modularized into special objects called aspects. This has two benefits. First, the logic for each concern is now in one place, as opposed to being scattered all over the code base. Second, our service modules are now cleaner since they only contain code for their core functionality and secondary concerns have been moved to aspects.