Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (5.49 MB, 753 trang )
9799ch03.qxd
42
5/5/08
4:50 PM
Page 42
CHAPTER 3 ■ BEAN CONFIGURATION IN SPRING
How It Works
Suppose you are going to develop an application for generating sequence numbers. In this
application, there may be many series of sequence numbers to generate for different purposes. Each one of them will have its own prefix, suffix, and initial value. So, you have to create
and maintain multiple generator instances in your application.
Creating the Bean Class
In accordance with the requirements, you create the SequenceGenerator class that has three
properties, prefix, suffix, and initial, that can be injected via setter methods or a constructor. The private field counter is for storing the current numeric value of this generator. Each
time you call the getSequence() method on a generator instance, you will get the last sequence
number with the prefix and suffix joined. You declare this method as synchronized to make it
thread-safe.
package com.apress.springrecipes.sequence;
public class SequenceGenerator {
private
private
private
private
String prefix;
String suffix;
int initial;
int counter;
public SequenceGenerator() {}
public SequenceGenerator(String prefix, String suffix, int initial) {
this.prefix = prefix;
this.suffix = suffix;
this.initial = initial;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public void setSuffix(String suffix) {
this.suffix = suffix;
}
public void setInitial(int initial) {
this.initial = initial;
}
public synchronized String getSequence() {
StringBuffer buffer = new StringBuffer();
buffer.append(prefix);
buffer.append(initial + counter++);
9799ch03.qxd
5/5/08
4:50 PM
Page 43
CHAPTER 3 ■ BEAN CONFIGURATION IN SPRING
buffer.append(suffix);
return buffer.toString();
}
}
As you see, this SequenceGenerator class applies both constructor injection and setter
injection for the properties prefix, suffix, and initial.
Creating the Bean Configuration File
To declare beans in the Spring IoC container via XML, you first have to create an XML bean
configuration file with an appropriate name, such as beans.xml. You can put this file in the
root of the classpath for easier testing within an IDE. At the beginning of this XML file, you
can specify the Spring 2.0 DTD to import the valid structure of a bean configuration file for
Spring 2.x. In this configuration file, you can define one or more beans under the root element
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
...
The configuration of Spring is backward compatible, so you can continue to use your
existing 1.0 configuration files (with the Spring 1.0 DTD) in Spring 2.x. But in this way, you will
not be able to use the new configuration facilities introduced in Spring 2.x. The usage of the
old configuration files is mainly for transitional purposes.
Spring 2.x also supports using XSD to define the valid structure of an XML bean configuration file. XSD has many advantages over the traditional DTD. The most significant advantage
in Spring 2.x is that it allows you to use custom tags from different schemas to make the bean
configuration simpler and clearer. So, I strongly recommend using Spring XSD instead of DTD
whenever possible. Spring XSD is version specific but backward compatible. If you are using
Spring 2.5, you should define the Spring 2.5 XSD to make use of the new 2.5 features.
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
...
Declaring Beans in the Bean Configuration File
Each bean should provide a unique name and a fully qualified class name for the Spring IoC
container to instantiate it. For each bean property of simple type (e.g., String and other primitive types), you can specify a
into the declaring type of this property. To configure a property via setter injection, you use
the
43
9799ch03.qxd
44
5/5/08
4:50 PM
Page 44
CHAPTER 3 ■ BEAN CONFIGURATION IN SPRING
class="com.apress.springrecipes.sequence.SequenceGenerator">
You can also configure bean properties via constructor injection by declaring them in the
class="com.apress.springrecipes.sequence.SequenceGenerator">
In the Spring IoC container, each bean’s name should be unique, although duplicate
names are allowed for overriding bean declaration. A bean’s name can be defined by the name
attribute of the
through the standard XML id attribute, whose purpose is to identify an element within an
XML document. In this way, if your text editor is XML aware, it can help to validate each bean’s
uniqueness at design time.
class="com.apress.springrecipes.sequence.SequenceGenerator">
...
However, XML has restrictions on the characters that can appear in the XML id attribute,
but usually you won’t use those special characters in a bean name. Moreover, Spring allows
you to specify multiple names, separated by commas, for a bean in the name attribute. But you
can’t do so in the id attribute, as commas are not allowed there.
In fact, neither the bean name nor the bean ID is required for a bean. A bean that has no
name defined is called an anonymous bean.
9799ch03.qxd
5/5/08
4:50 PM
Page 45
CHAPTER 3 ■ BEAN CONFIGURATION IN SPRING
Defining Bean Properties by Shortcut
Spring supports a shortcut for specifying the value of a simple type property. You can present a
value attribute in the
class="com.apress.springrecipes.sequence.SequenceGenerator">
This shortcut also works for constructor arguments.
class="com.apress.springrecipes.sequence.SequenceGenerator">
Spring 2.x provides another convenient shortcut for you to define properties. It’s by using
the p schema to define bean properties as attributes of the
the lines of XML configuration.
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
class="com.apress.springrecipes.sequence.SequenceGenerator"
p:prefix="30" p:suffix="A" p:initial="100000" />
3-2. Instantiating the Spring IoC Container
Problem
You have to instantiate the Spring IoC container for it to create bean instances by reading their
configurations. Then you can get the bean instances from the IoC container to use.
Solution
Spring provides two types of IoC container implementation. The basic one is called bean factory. The more advanced one is called application context, which is a compatible extension to
the bean factory. Note that the bean configuration files for these two types of IoC container are
identical.
45
9799ch03.qxd
46
5/5/08
4:50 PM
Page 46
CHAPTER 3 ■ BEAN CONFIGURATION IN SPRING
The application context provides more advanced features than the bean factory while
keeping the basic features compatible. So, I strongly recommend using the application context for every application unless the resources of this application are restricted, such as when
running in an applet or a mobile device.
The interfaces for the bean factory and the application context are BeanFactory and
ApplicationContext, respectively. The interface ApplicationContext is a subinterface of
BeanFactory for maintaining compatibility.
How It Works
Instantiating a Bean Factory
To instantiate a bean factory, you have to load the bean configuration file into a Resource
object first. For example, the following statement loads your configuration file from the root of
the classpath:
Resource resource = new ClassPathResource("beans.xml");
Resource is only an interface, while ClassPathResource is one of its implementations for
loading a resource from the classpath. Other implementations of the Resource interface, such
as FileSystemResource, InputStreamResource, and UrlResource, are used to load a resource
from other locations. Figure 3-1 shows the common implementations of the Resource interface in Spring.
Figure 3-1. Common implementations of the Resource interface
Next, you can use the following statement to instantiate a bean factory by passing in a
Resource object with the configuration file loaded:
BeanFactory factory = new XmlBeanFactory(resource);
As mentioned, BeanFactory is only an interface for abstracting the operations of a bean
factory, while XmlBeanFactory is the implementation that builds a bean factory from an XML
configuration file.