Alternatives to XML


The previous chapter and most of this one have focused on XML as the configuration format for Spring bean factories and application contexts. This is appropriate because this is the format used in the great majority of cases to configure the containers. However, the capabilities of the containers, and the configuration format used to read in bean definitions, are really two separate things; there are, in fact, two other existing ways you can get definitions into the containers, along with the possibility of rolling your own.

Definitions from Properties Files

An alternative declarative definition format is the use of Java Properties files, and their close cousins, ResourceBundles. The Properties definition format is not as expressive as XML; there are a number of container capabilities that cannot be expressed using this format, including constructor-injection, method-injection, nested beans, or setting of complex collection types. However, for simple basic bean definitions with Setter Injection, it's fairly concise, and it might also be useful in an environment where it's not desirable to bring in an XML parser. An example might be an applet using only basic BeanFactory functionality, and trying to keep code size and memory use down. One Spring class that uses this format itself is ResourceBundleViewResolver, part of Spring's web MVC layer. The use there is well-suited because view definitions are fairly simple, with no nesting needed, and the class is able to take advantage of ResourceBundles to load views appropriate to various locales.

Let's see how our Setter Injection configuration sample from the previous chapter would look in Properties format. The XML variant:

 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"     "http://www.springframework.org/dtd/spring-beans.dtd">      <beans>   <bean  >     <property name="weatherDao">       <ref local="weatherDao"/>     </property>   </bean>   <bean  /> </beans> 

translated to Properties format would be:

 weatherService.class=ch02.sample2.WeatherServiceImpl  weatherService.weatherDao(ref)=weatherDao      weatherDao.class=ch02.sample2.StaticDataWeatherDaoImpl 

Even taking out the XML header, which is needed only once, this is obviously more concise than the XML format. However, this has to be traded off against the lack of some capabilities. For the Properties file format, there is no one-step bean factory or application context constructor; initializing the container becomes a multistep process, using the PropertiesBeanDefinitionReader to actually parse this format. Here's a test case for a bean factory, showing the steps:

 public void testBeanFactoryLoadedFromProperties() throws Exception {        DefaultListableBeanFactory bf = new DefaultListableBeanFactory();   PropertiesBeanDefinitionReader bdReader =     new PropertiesBeanDefinitionReader(bf);   Resource def = new ClassPathResource("ch03/sample4/beans.properties");   bdReader.loadBeanDefinitions(def); } 

Here's an equivalent test for an application context. Note that refresh() must be called on the GenericApplicationContext to fully initialize it after all definitions have been loaded:

 public void testApplicationContextLoadedFromProperties() throws Exception {        GenericApplicationContext ctx = new GenericApplicationContext();   PropertiesBeanDefinitionReader bdReader =       new PropertiesBeanDefinitionReader(ctx);   Resource def = new ClassPathResource("ch03/sample4/beans.properties");   bdReader.loadBeanDefinitions(def);   ctx.refresh(); } 

We'll direct you to the JavaDoc for PropertiesBeanDefinitionReader for an actual description of the exact syntax in Properties format, which is fairly simple.

Programmatic Bean Definitions

The functionality of the containers, and the XML and Properties definition formats, are built on a pro- grammatic API for creating and using bean definition metadata, which is fully user accessible. There are a number of classes involved in specifying definition metadata, including:

  • RootBeanDefinition: Used to specify a definition for a bean with no parent bean

  • ChildBeanDefinition: Allows definitions for beans that inherit settings from their parents

  • MutablePropertyValues: Allows simple manipulation of properties, as used in a definition

  • ConstructorArgumentValues: Holder for constructor argument values for a bean

Here's a test case showing the previous bean factory definition, handled completely programmatically:

 public void testBeanFactoryLoadedProgrammatically() throws Exception {        DefaultListableBeanFactory bf = new DefaultListableBeanFactory();        MutablePropertyValues mpv = new MutablePropertyValues();   mpv.addPropertyValue("weatherDao", new RuntimeBeanReference("weatherDao"));   RootBeanDefinition weatherService =       new RootBeanDefinition(WeatherServiceImpl.class, mpv);   bf.registerBeanDefinition("weatherService", weatherService);        mpv = new MutablePropertyValues();   RootBeanDefinition weatherDao =       new RootBeanDefinition(StaticDataWeatherDaoImpl.class, mpv);   bf.registerBeanDefinition("weatherDao", weatherDao); } 

Other Formats

At the time of the writing of this book, the Spring team is already thinking about how to simplify bean configuration even further. This may include specialized XML dialects to handle specialized concerns such as AOP, smaller tweaks to the existing generic XML format, or the inclusion of completely alternate mechanisms such as definition builders for the Groovy JVM scripting language. However, regardlessof the format of the container definition and how it's parsed, clients of the containers are generally unaware of any of these aspects. They deal with the container via the BeanFactory and ApplicationContext interfaces, and their sub-interfaces, to obtain configured objects in a consistent and predictable manner. Only a small amount of code needs to know or care about how the container is configured. Just as importantly, the containers themselves are unaware of the configuration format; the internal use of bean definition readers, which use the programmatic API to configure the container, is what actually makes it possible to implement other formats relatively easily.



Professional Java Development with the Spring Framework
Professional Java Development with the Spring Framework
ISBN: 0764574833
EAN: 2147483647
Year: 2003
Pages: 188

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net