Dependency Injection with Spring

Spring's support for Dependency Injection is comprehensive and, as you will see in

Beans and BeanFactories

The core of Spring's Dependency Injection container is the BeanFactory. A BeanFactory is responsible for managing components and their dependencies. In Spring, the term bean is used to refer to any component managed by the container. Typically your beans adhere, at some level, to the JavaBeans specification, but this is not required, especially if you plan to use Constructor Injection to wire your beans together.

Your application interacts with the Spring DI container via the BeanFactory interface. At some point, your application must create an instance of a class that implements the BeanFactory interface and configure it with bean and dependency information. After this is complete, your application can access the beans via the BeanFactory and get on with its processing. In some cases, all of this setup is handled automatically, but in many cases, you need to code the setup yourself. All of the examples in this chapter require manual setup of the BeanFactory implementation.

Although a BeanFactory can be configured programmatically, it is more common to see it configured externally using some kind of configuration file. Internally, bean configuration is represented by instances of classes that implement the BeanDefinition interface. The bean configuration stores not only information about a bean itself, but also about the beans that it depends on. For any BeanFactory class that also implements the BeanDefinitionRegistry interface, you can read the BeanDefinition data from a configuration file, using either PropertiesBeanDefinitionReader or XmlBeanDefinitionReader. The two main BeanFactory implementations that come with Spring implement BeanDefinitionRegistry.

So you can identify your beans within the BeanFactory, each bean is assigned a name. Each bean has at least one name but can have any number. Any names after the first are considered aliases for the same bean. You use bean names to retrieve a bean from the BeanFactory and also to establish dependency relationships—that is, bean X depends on bean Y.

BeanFactory Implementations

The description of the BeanFactory might make using it seem overly complex, but in practice, this is not the case. In fact, we discussed all of the concepts in the previous section and in the simple example in

Listing 4-9: Using the BeanFactory

image from book
package com.apress.prospring.ch2;      import java.io.FileInputStream; import java.util.Properties;      import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader;      public class HelloWorldSpringWithDI {          public static void main(String[] args) throws Exception {              // get the bean factory         BeanFactory factory = getBeanFactory();              MessageRenderer mr = (MessageRenderer) factory.getBean("renderer");         mr.render();     }          private static BeanFactory getBeanFactory() throws Exception {         // get the bean factory         DefaultListableBeanFactory factory = new DefaultListableBeanFactory();              // create a definition reader         PropertiesBeanDefinitionReader rdr = new PropertiesBeanDefinitionReader(                 factory);              // load the configuration options         Properties props = new Properties();         props.load(new FileInputStream("./ch2/src/conf/beans.properties"));              rdr.registerBeanDefinitions(props);              return factory;     } }
image from book

In this example, you can see that we are using the DefaultListableBeanFactory—one of the two main BeanFactory implementations supplied with Spring—and that we are reading in the BeanDefinition information from a properties file using the PropertiesBeanDefinitionReader. Once the BeanFactory implementations is created and configured, we retrieve the MessageRenderer bean using its name, renderer, which is configured in the properties file.

In addition to the PropertiesBeanDefinitionReader, Spring also provides XmlBeanDefinitionReader, which allows you to manage your bean configuration using XML rather than properties. Although properties are ideal for small, simple applications, they can quickly become cumbersome when you are dealing with a large number of beans. For this reason, it is preferable to use the XML configuration format for all but the most trivial of applications. This leads nicely to a discussion of the second of the two main BeanFactory implementations: XmlBeanFactory.

The XmlBeanFactory is derived from DefaultListableBeanFactory and simply extends it to perform automatic configuration using the XmlBeanDefinitionReader. So rather than create some code like this:

package com.apress.prospring.ch4;      import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.core.io.FileSystemResource;      public class XmlConfig {          public static void main(String[] args) {         DefaultListableBeanFactory factory = new DefaultListableBeanFactory();         XmlBeanDefinitionReader rdr = new XmlBeanDefinitionReader(factory);         rdr.loadBeanDefinitions(new FileSystemResource("ch4/src/conf/beans.xml"));         Oracle oracle = (Oracle)factory.getBean("oracle");     } }

you can do this instead:

package com.apress.prospring.ch4;      import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.FileSystemResource;      public class XmlConfigWithBeanFactory {          public static void main(String[] args) {         XmlBeanFactory factory = new XmlBeanFactory(new FileSystemResource(                 "ch4/src/conf/beans.xml"));         Oracle oracle = (Oracle)factory.getBean("oracle");     } }

For the rest of this book, including the sample application, we will be using the XML configuration format exclusively. You are free to investigate the properties format yourself— you will find plenty of examples throughout the Spring codebase.

Of course, you are free to define your own BeanFactory implementations, although be aware that doing so is quite involved; you need to implement a lot more interfaces than just BeanFactory to get the same level of functionality you have with the supplied BeanFactory implementations. If all you want to do is define a new configuration mechanism, then create your definition reader and wrap this in a simple BeanFactory implementation derived from DefaultListableBeanFactory. This is the approach the XmlBeanFactory class takes; check the Spring code for more details.



Pro Spring
Pro Spring
ISBN: 1590594614
EAN: 2147483647
Year: 2006
Pages: 189

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