BeanFactory的XML配置
格式限定
所有使用 XML 文件进行配置信息加载的 Spring IoC 容器,包括 BeanFactory 和 ApplicationContext的所有XML相应实现,都使用统一的XML格式。
- DTD(DOCTYPE)(Spring2.0前)
- XSD(XML Schema)(Spring2.0后)
自动绑定和手动明确绑定各有利弊。自动绑定的优点有如下两点。
(1) 某种程度上可以有效减少手动敲入配置信息的工作量。
(2) 某些情况下,即使为当前对象增加了新的依赖关系,但只要容器中存在相应的依赖对 象,就不需要更改任何配置信息。
自动绑定的缺点有如下几点。
(1) 自动绑定不如明确依赖关系一目了然。我们可以根据明确的依赖关系对整个系统有一 个明确的认识,但使用自动绑定的话,就可能需要在类定义以及配置文件之间,甚至各个配置 文件之间来回转换以取得相应的信息。
(2) 某些情况下,自动绑定无法满足系统需要,甚至导致系统行为异常或者不可预知。根 据类型(byType)匹配进行的自动绑定,如果系统中增加了另一个相同类型的bean定义,那么 整个系统就会崩溃;根据名字(byName)匹配进行的自动绑定,如果把原来系统中相同名称的 bean定义类型给换掉,就会造成问题,而这些可能都是在不经意间发生的。
(3) 使用自动绑定,我们可能无法获得某些工具的良好支持,比如Spring IDE。
bean 的 scope
- spring2.0前
- singleton
- prototype
- spring2.0后(仅适用于web项目)
- request
- session
- global session
后三个scope只有在支持Web应用的ApplicationContext(如XmlWebApplicationContext)中使用才是合理的。
如前所述,由于XML格式两种版本原因,的scope指定属性有所差异,我们可以通过使用的singleton或者scope属性来指定相应对象的scope,其中,scope属性只能在XSD格式的文档声明中使用,如:
DTD:
<bean id="mockObject1" class="...MockBusinessObject" singleton="false"/>
XSD:
<bean id="mockObject2" class="...MockBusinessObject" scope="prototype"/>
复制代码
各scope作用:
- singleton:由容器来保证这种类型的bean在同一个容器中只存在一个共享实例,bean默认为此类型。
- 对象实例数量:在一个容器中只存在一个共享实例。
- 对象存活时间:从它第一次被请求而实例化开始到容器不销毁或者退出。
- prototype:容器在接到该类型对象的请求的时候,会每次都重新生成一个新的对象实例给请求方,并且失去引用(不再管理此bean),用于请求方不能共享的使用的对象实例。
- request:容器XmlWebApplicationContext为每个HTTP请求创建一个RequestProcessor并在请求结束后销毁(可看做prototype的一种特例)。
- session:比request的bean存活时间长以外并无差别。
- global session:只有应用在基于portlet的Web应用程序中才有意义,它映射到portlet的global范围的session;在的基于servlet的Web应用中相当于session。
自定义scope
需要实现org.springframework.beans.factory.config.Scope接口,且request、session、global session也是实现了此接口的类型,而singleton和prototype则是硬编码到代码中的。
该接口如下:
public interface Scope {
Object get(String name, ObjectFactory objectFactory);
Object remove(String name);
void registerDestructionCallback(String name, Runnable callback);
String getConversationId();
}
复制代码
Scope的实现类需要注册到容器中才能为相应的bean提供定义,如ConfigurableBeanFactory的一下方法:
void registerScope(String scopeName, Scope scope);
复制代码
其中是scopeName为bean指定scope时的类型名,如:request、session。
scope的注册方式:
- 硬编码,如:
Scope threadScope = new ThreadScope();
beanFactory.registerScope("thread",threadScope);
复制代码
- 配置文件配置,如:
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="thread" value="com.foo.ThreadScope"/>
</map>
</property>
</bean>
复制代码