Spring IOC简介
beans和context包是IOC容器的基础,BeanFactory 提供的高级配置机制,使得管理各种对象成为可能。 ApplicationContext 是BeanFactory的扩展,功能得到了进一步增强,比如更易 与Spring AOP集成、资源处理(国际化处理)、事件传递及各种不同应用层的context实现 (如针对web应用的WebApplicationContext)。总之,在实际应用更多会选择ApplicationContext,原因是ApplicationContext即继承了BeanFactory的功能,同时又增加的更多支持企业核心内容的支持。
Spring IOC关键概念理解
IOC(Inversion of Control):控制反转,即指获取对象的方式被反转了,我们只需要在applicationContext.xml(Spring的配置文件)文件配置元数据(即指xml)中的bean指定相应class(类)的全路径,Spring中的容器(BeanFactory)会负责类对象的创建、配置和管理这些对象及它们之间的依赖关系,而且这些对象和我们通过new Object()的对象没有区别,这样最终会达到解耦的目的(即减少代码之间的依赖);
Bean:在Spring中,那些组成你应用程序的主体(backbone)及由Spring IoC容器所管理的对象,被称之为bean。 简单地讲,bean就是由Spring容器初始化、装配及管理的对象,除此之外,bean就与应用程序中的其他对象没有什么区别了。 而bean定义以及bean相互间的依赖关系将通过配置元数据来描述。
容器:即指Spring IOC容器,BeanFactory是容器的实际代表者,他负责bean对象的创建,配置和容纳创建的bean描述并且管理bean;Spring为我们提供了许多易用的BeanFactory实现, XmlBeanFactory就是最常用的一个。该实现将以XML方式描述组成应用的对象以及对象间的依赖关系。XmlBeanFactory类将获取此XML配置元数据,并用它来构建一个完全可配置的系统或应用。
Spring IOC 容器
元数据:我们通常配置的Spring配置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-2.5.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>
<!-- more bean definitions go here -->
</beans>
注入依赖:
依赖注入(DI)背后的基本原理是对象之间的依赖关系(即一起工作的其它对象)只会通过以下几种方式来实现:构造器的参数、工厂方法的参数,或给由构造函数或者工厂方法创建的对象设置属性。因此,容器的工作就是创建bean时注入那些依赖关系。相对于由bean自己来控制其实例化、直接在构造器中指定依赖关系或者类似服务定位器(Service Locator)模式这3种自主控制依赖关系注入的方法来说,控制从根本上发生了倒转,这也正是控制反转(Inversion of Control, IoC) 名字的由来。
Spring的IOC关键配置
1.如何定义(创建)一个bean
Spring IoC容器将管理一个或多个bean,这些bean 将通过配置文件中的bean定义被创建(在XML格式中为<bean/> 元素)。
在容器内部,这些bean定义由BeanDefinition 对象来表示,该定义将包含以下信息:
- 全限定类名:这通常就是已定义bean的实际实现类。
- bean行为的定义,这些定义将决定bean在容器中的行为(作用域、生命周期回调等等)
- 对其他bean的引用,这些引用bean也可以称之为协作bean(collaborators) 或依赖bean(dependencies).
- 创建bean实例时的其他配置设置。比如使用bean来定义连接池,可以通过属性或者构 造参数指定连接数,以及连接池大小限制等。
上述内容直接被翻译为每个bean定义包含的一组properties。具体的properties属性参考下面的:Spring官方的翻译文档;
2.bean如何实例化
从本质上来说,bean定义描述了如何创建一个或多个对象实例。当需要的时候, 容器会从bean定义列表中取得一个指定的bean定义,并根据bean定义里面的配置元数据 使用反射机制来创建(或取得)一个实际的对象。
当采用XML描述配置元数据时,将通过<bean/>元素的 class属性来指定实例化对象的类型。class 属性 (对应BeanDefinition实例的 Class属性)通常是必须的(不过也有两种例外的情形,见 Section 3.2.3.2.3, “使用实例工厂方法实例化”和 Section 3.6, “bean定义的继承”)。class属性主要有两种用途 :在大多数情况下,容器将直接通过反射调用指定类的构造器来创建bean(这有点类似于 在Java代码中使用new操作符);在极少数情况下,容器将调用 类的静态工厂方法来创建bean实例,class 属性将用来指定实际具有静态工厂方法的类(至于调用静态工厂 方法创建的对象类型是当前class还是其他的class则无关紧要)。
实例化主要有三种方式:用构造器来实例化,使用静态方法实例化,使用实例工厂来实例化;
3.DI-注入依赖(指的就是对象与对象之间的依赖关系通过配置的方式建立) 通过以下几种方式来实现:构造器的参数、工厂方法的参数,或给由构造函数或者工厂方法创建的对象设置属性。DI主要有两种注入方式,即 Setter注入和 构造器注入;
3.1(Setter)首先是一个用XML格式定义的Setter DI例子。相关的XML配置如下:
<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"/>
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;
}
}
3.2(构造器参数的方式)正如你所看到的,bean类中的setter方法与xml文件中配置的属性是一一对应的。接着是构造器注入的例子:
<bean id="exampleBean" class="examples.ExampleBean">
<!-- constructor injection using the nested <ref/> element -->
<constructor-arg>
<ref bean="anotherExampleBean"/>
</constructor-arg>
<!-- constructor injection using the neater 'ref' attribute -->
<constructor-arg ref="yetAnotherBean"/>
<constructor-arg type="int" value="1"/>
</bean>
<bean id="anotherExampleBean" class="examples.AnotherBean"/>
<bean id="yetAnotherBean" class="examples.YetAnotherBean"/>
public class ExampleBean {
private AnotherBean beanOne;
private YetAnotherBean beanTwo;
private int i;
public ExampleBean(
AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) {
this.beanOne = anotherBean;
this.beanTwo = yetAnotherBean;
this.i = i;
}
}
4.Bean的生命周期回调 在Bean的创建之前或销毁的时候,我们可能做一些初始化处理或者释放资源的操作;
Spring提供了几个标志接口(marker interface),这些接口用来改变容器中bean的行为;它们包括InitializingBean和DisposableBean。实现这两个接口的bean在初始化和析构时容器会调用前者的afterPropertiesSet()方法,以及后者的destroy()方法。
Spring在内部使用BeanPostProcessor实现来处理它能找到的任何标志接口并调用相应的方法。如果你需要自定义特性或者生命周期行为,你可以实现自己的 BeanPostProcessor。关于这方面更多的内容可以看Section 3.7, “容器扩展点”。
以上仅仅是我基于学习Spring官方翻译文档的一些关键内容记录,具体的学习请参考官方翻译文档
参考:
Spring官方翻译文档:http://shouce.jb51.net/spring/beans.html