首先定义几个关键性的概念:
Beans
:在Spring
中,组成程序主体的并由Spring IoC
容器管理的对象,称为Beans
。Beans
以及任何与之存在依赖关系的物件,均被反射在由容器使用的Configuration Metadata
中。
IoC容器的核心
org.springframework.beans和
org.springframework.context这两个包构成了Spring框架的IoC容器的核心。其中BeanFactory接口提供了能管理任何对象的高级配置机制。但是目前一般不直接使用BeanFactory类,而是用ApplicationContext替代之。ApplicationContext是BeanFactory接口的派生,可以看作是BeanFactory的超集。它能够更容易的与Spring AOP特性集成,拥有消息资源处理(Message Resources Handling)和事件发布(Event Publication)等功能。
ApplicationContext接口代表了Spring IoC容器。主要负责初始化,配置,组装Beans。这个容器从Configuration Metadata
中得到相关的指令。Configuration Metadata
一般是一个XML,JAVA
注解,或者JAVA
代码。
下面是一个典型的XML
配置文件:
<
?xml
version
="1.0"
encoding
="UTF-8"?
>
<beans xmlns="http://www.springframework.org/schema/beans"
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-3.0.xsd">
< bean id ="..." class ="..." >
<! -- collaborators and configuration for this bean go here -- >
</bean>
< bean id ="..." class ="..." >
<! -- collaborators and configuration for this bean go here -- >
</bean>
</beans>
<beans xmlns="http://www.springframework.org/schema/beans"
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-3.0.xsd">
< bean id ="..." class ="..." >
<! -- collaborators and configuration for this bean go here -- >
</bean>
< bean id ="..." class ="..." >
<! -- collaborators and configuration for this bean go here -- >
</bean>
</beans>
ApplicationContext接口主要有两种实现类,分别是
ClassPathXmlApplicationContext和FileSystemXmlApplicationContext。
从命名上很容易看出它们的适用范围。
初始化一个
ApplicationContext是极其容易的事情。下面是一般的初始化方式:
ApplicationContext context =
new ClassPathXmlApplicationContext( new String[] { "services.xml", "daos.xml"});
new ClassPathXmlApplicationContext( new String[] { "services.xml", "daos.xml"});
从以上代码可以很容易看出,应用程序可以使用多个
配置文件,这样做的好处是显而易见的。另外,还可以在某一个配置文件中引入其它的配置文件,如下所示:
<
beans
>
< import resource ="services.xml" />
< import resource ="resources/messageSource.xml" />
< import resource ="/resources/themeSource.xml" />
< bean id ="bean1" class ="..." />
< bean id ="bean2" class ="..." />
</beans>
< import resource ="services.xml" />
< import resource ="resources/messageSource.xml" />
< import resource ="/resources/themeSource.xml" />
< bean id ="bean1" class ="..." />
< bean id ="bean2" class ="..." />
</beans>
Beans
还可以通过静态工厂方法来初始化,例如:类的定义代码是:
public
class ClientService {
private static ClientService clientService = new ClientService();
private ClientService() {}
public static ClientService createInstance() {
return clientService;
}
}
private static ClientService clientService = new ClientService();
private ClientService() {}
public static ClientService createInstance() {
return clientService;
}
}
<bean id="clientService"
class="examples.ClientService"
factory-method="createInstance"/>
class="examples.ClientService"
factory-method="createInstance"/>
Beans
在容器内部,Beans
由BeanDefinition
对象表示。BeanDefinition
对象包含了以下一些信息:
-
完整的类名称,包含包的路径。
-Bean
行为的相关元素,说明了Bean
在容器内的行为。
-Bean
相关的引用,也就是依赖的其它的类。
-Bean
其它的设置信息。
依赖注入
(Dependency Injection)
Spring
中DI
主要有两种形式:基于构造方法的和基于Setter
方法的。
对于基于构造方法的,例如下面这个类:
package x.y;
public class Foo {
public Foo(Bar bar, Baz baz) {
// ...
}
}
public class Foo {
public Foo(Bar bar, Baz baz) {
// ...
}
}
则配置文件应做如下配置:
<
beans
>
< bean id ="foo" class ="x.y.Foo" >
< constructor-arg ref ="bar" />
< constructor-arg ref ="baz" />
</ bean >
< bean id ="bar" class ="x.y.Bar" />
< bean id ="baz" class ="x.y.Baz" />
</ beans >
< bean id ="foo" class ="x.y.Foo" >
< constructor-arg ref ="bar" />
< constructor-arg ref ="baz" />
</ bean >
< bean id ="bar" class ="x.y.Bar" />
< bean id ="baz" class ="x.y.Baz" />
</ beans >
对于参数是Bean
的时候,这种方法是可以的。但是如果参数里面含有基本数据类型,比如int
或者String
,那么Spring
便无法确定如何解析。必须采用以下的方法对待:
package examples;
public class ExampleBean {
// No. of years to the calculate the Ultimate Answer
private int years;
// The Answer to Life, the Universe, and Everything
private String ultimateAnswer;
public ExampleBean( int years, String ultimateAnswer) {
this.years = years;
this.ultimateAnswer = ultimateAnswer;
}
}
public class ExampleBean {
// No. of years to the calculate the Ultimate Answer
private int years;
// The Answer to Life, the Universe, and Everything
private String ultimateAnswer;
public ExampleBean( int years, String ultimateAnswer) {
this.years = years;
this.ultimateAnswer = ultimateAnswer;
}
}
在配置文件中配置:
<
bean
id
="exampleBean"
class
="examples.ExampleBean"
>
< constructor-arg type ="int" value ="7500000" />
< constructor-arg type ="java.lang.String" value ="42" />
</ bean >
< constructor-arg type ="int" value ="7500000" />
< constructor-arg type ="java.lang.String" value ="42" />
</ bean >
或者
<
bean
id
="exampleBean"
class
="examples.ExampleBean"
>
< constructor-arg index ="0" value ="7500000" />
< constructor-arg index ="1" value ="42" />
</ bean >
< constructor-arg index ="0" value ="7500000" />
< constructor-arg index ="1" value ="42" />
</ bean >
对于基于Setter
方法的:
例如下面这个类:
public
class ExampleBean {
private AnotherBean beanOne;
private YetAnotherBean beanTwo;
private int i;
public void setBeanOne(AnotherBean beanOne) {
this.beanOne = beanOne;
}
public void setBeanTwo(YetAnotherBean beanTwo) {
this.beanTwo = beanTwo;
}
public void setIntegerProperty( int i) {
this.i = i;
}
}
private AnotherBean beanOne;
private YetAnotherBean beanTwo;
private int i;
public void setBeanOne(AnotherBean beanOne) {
this.beanOne = beanOne;
}
public void setBeanTwo(YetAnotherBean beanTwo) {
this.beanTwo = beanTwo;
}
public void setIntegerProperty( int i) {
this.i = i;
}
}
则在配置文件中应做如下配置:
<
bean
id
="exampleBean"
class
="examples.ExampleBean"
>
<!-- setter injection using the nested <ref/> element -->
< property name ="beanOne" > < ref bean ="anotherExampleBean" /> </ property >
<!-- setter injection using the neater 'ref' attribute -->
< property name ="beanTwo" ref ="yetAnotherBean" />
< property name ="integerProperty" value ="1" />
</ bean >
< bean id ="anotherExampleBean" class ="examples.AnotherBean" />
< bean id ="yetAnotherBean" class ="examples.YetAnotherBean" />
<!-- setter injection using the nested <ref/> element -->
< property name ="beanOne" > < ref bean ="anotherExampleBean" /> </ property >
<!-- setter injection using the neater 'ref' attribute -->
< property name ="beanTwo" ref ="yetAnotherBean" />
< property name ="integerProperty" value ="1" />
</ bean >
< bean id ="anotherExampleBean" class ="examples.AnotherBean" />
< bean id ="yetAnotherBean" class ="examples.YetAnotherBean" />
以上例子均摘自
Spring
官方参考文档。
附Spring 3框架结构图
本文转自 kevx 51CTO博客,原文链接:http://blog.51cto.com/spinlock/323821,如需转载请自行联系原作者