转自http://www.blogjava.net/103335460/articles/260845.html
Spring是一个强有力的java程序框架,其被广泛应用于java的程序中。它用POJO提供了企业级服务。 Spring利用依赖注入可以获得简单而有效的测试能力。Spring beans,依赖关系,以及服务所需要的bean都将在配置文件中予以描述,配置文件一般采用XML格式。然而XML配置文件冗长而不易使用,在你进行一 个使用了大量bean的大项目中它将变得难以阅读和控制。
<bean id="orderService"
class="com.lizjason.spring.OrderService">
<property name="companyName">
<value>lizjason</value>
</property>
<constructor-arg>
<ref bean="orderDAO">
</constructor-arg>
</bean>
<bean id="orderService"
class="com.lizjason.spring.OrderService">
<property name="companyName"
value="lizjason"/>
<constructor-arg ref="orderDAO"/>
</bean>
<bean id="billingService"
class="com.lizjason.spring.BillingService">
<constructor-arg index="0" value="lizjason"/>
<constructor-arg index="1" value="100"/>
</bean>
<bean id="billingService"
class="com.lizjason.spring.BillingService">
<constructor-arg type="java.lang.String"
value="lizjason"/>
<constructor-arg type="int" value="100"/>
</bean>
<bean id="abstractService" abstract="true"
class="com.lizjason.spring.AbstractService">
<property name="companyName"
value="lizjason"/>
</bean>
<bean id="shippingService"
parent="abstractService"
class="com.lizjason.spring.ShippingService">
<property name="shippedBy" value="lizjason"/>
</bean>
6.
尽量使用ApplicationContext
装配bean,而不是用import
像Ant脚本中imports一样,
Spring的import
元素对于模块化bean的装配非常有用,例如: <beans>
<import resource="billingServices.xml"/>
<import resource="shippingServices.xml"/>
<bean id="orderService"
class="com.lizjason.spring.OrderService"/>
<beans>
<bean id="orderService"
class="com.lizjason.spring.OrderService"
dependency-check="objects">
<property name="companyName"
value="lizjason"/>
<constructor-arg ref="orderDAO"/>
</bean>
description
元素中加入描述信息。例如:
<beans>
<description>
This file defines billing service
related beans and it depends on
baseServices.xml,which provides
service bean templates...
</description>
...
</beans>
description
元
素的一个好处就是工具可以很容易的把描述信息从这个元素中提取出来。
10.
和team members沟通变更
当你修改java源码后,要确保更改了配置文件中的相应部分并把这个情况告知你的team members。XML配置文件也是代码,它们是程序的重要组成部分,但它们很难阅读和维护。大多数时间里,你需要同时看XML配置文件和java代码才能知道是怎么回事。
11.
setter
注入和构造函数注入,优先使用前者
<bean id="orderService"
class="com.lizjason.spring.OrderService">
<constructor-arg ref="orderDAO"/>
</bean>
<bean id="billingService"
class="com.lizjason.spring.BillingService">
<property name="billingDAO"
ref="billingDAO">
</bean>
BillingService
bean用了setter注入。构造函数注入可以确保bean正确地构建,但是setter注入更加的灵活和易于控制,特别是当class有多个属性并且它们中的一些是可选的情况是更是如此。ApplicationContextEclipse and IntelliJ,java代码更加的易于阅读,维护和管理比使XML文件
可以替你创建
java
对象
,
但不是所有的
java
对象都应该通过注入创建。例如
,
域对象就不应该通过
ApplicationContext
创建。Spring是一个优秀的框架,但是考虑到可读性和可操控性,基于XML配置的配置会在定义很多bean的时候出现麻烦。过渡使用依赖注入将会使XML配置更加的复杂和冗长。切记,当使用高效的IDE时,例如
<bean
id="beanId"(1)
name="beanName"(2)
class="beanClass"(3)
parent="parentBean"(4)
abstract="true | false"(5)
singleton="true | false"(6)
lazy-init="true | false | default"(7)
autowire="no | byName | byType | constructor | autodetect | default"(8)
dependency-check = "none | objects | simple | all | default"(9)
depends-on="dependsOnBean"(10)
init-method="method"(11)
destroy-method="method"(12)
factory-method="method"(13)
factory-bean="bean">(14)
</bean>
(1)、id: Bean的唯一标识名。它必须是合法的XML ID,在整个XML文档中唯一。
(2)、name: 用来为id创建一个或多个别名。它可以是任意的字母符合。多个别名之间用逗号或空格分开。
(3)、class: 用来定义类的全限定名(包名+类名)。只有子类Bean不用定义该属性。
(4)、parent: 子类Bean定义它所引用它的父类Bean。这时前面的class属性失效。子类Bean会继承父类Bean的所有属性,子类Bean也可以覆盖父类Bean的属性。注意:子类Bean和父类Bean是同一个Java类。
(5)、abstract(默认为”false”):用来定义Bean是否为抽象Bean。它表示这个Bean将不会被实例化,一般用于父类Bean,因为父类Bean主要是供子类Bean继承使用。
(6)、singleton(默认为“true”):定义Bean是否是Singleton(单例)。如果设为“true”,则在BeanFactory作用范围内,只维护此Bean的一个实例。如果设为“flase”,Bean将是Prototype(原型)状态,BeanFactory将为每次Bean请求创建一个新的Bean实例。
(7)、lazy-init(默认为“default”):用来定义这个Bean是否实现懒初始化。如果为“true”,它将在BeanFactory启动时初始化所有的Singleton Bean。反之,如果为“false”,它只在Bean请求时才开始创建Singleton Bean。
(8)、autowire(自动装配,默认为“default”):它定义了Bean的自动装载方式。
1、“no”:不使用自动装配功能。
2、“byName”:通过Bean的属性名实现自动装配。
3、“byType”:通过Bean的类型实现自动装配。
4、“constructor”:类似于byType,但它是用于构造函数的参数的自动组装。
5、“autodetect”:通过Bean类的反省机制(introspection)决定是使用“constructor”还是使用“byType”。
(9)、dependency-check(依赖检查,默认为“default”):它用来确保Bean组件通过JavaBean描述的所以依赖关系都得到满足。在与自动装配功能一起使用时,它特别有用。
1、 none:不进行依赖检查。
2、 objects:只做对象间依赖的检查。
3、 simple:只做原始类型和String类型依赖的检查
4、 all:对所有类型的依赖进行检查。它包括了前面的objects和simple。
(10)、depends-on(依赖对象):这个Bean在初始化时依赖的对象,这个对象会在这个Bean初始化之前创建。
(11)、init-method:用来定义Bean的初始化方法,它会在Bean组装之后调用。它必须是一个无参数的方法。
(12)、destroy-method:用来定义Bean的销毁方法,它在BeanFactory关闭时调用。同样,它也必须是一个无参数的方法。它只能应用于singleton Bean。
(13)、factory-method:定义创建该Bean对象的工厂方法。它用于下面的“factory-bean”,表示这个Bean是通过工厂方法创建。此时,“class”属性失效。
(14)、factory-bean:定义创建该Bean对象的工厂类。如果使用了“factory-bean”则“class”属性失效。
下面列出<ref>元素的所有可用的指定方式:
bean:可以在当前文件中查找依赖对象,也可以在应用上下文(ApplicationContext)中查找其它配置文件的对象。
local:只在当前文件中查找依赖对象。这个属性是一个XML IDREF,所以它指定的对象必须存在,否则它的验证检查会报错。
external:在其它文件中查找依赖对象,而不在当前文件中查找。
总的来说,<ref bean="..."/>和<ref local="..."/>大部分的时候可以通用。“bean”是最灵活的方式,它允许你在多个文件之间共享Bean。而“local”则提供了便利的XML验证。
getBean()
方法)都会产生一个新的bean实例,相当与一个new的操作,对于prototype作用域的bean,有一点非常重要,那就是Spring不能对一个prototype bean的整个生命周期负责,容器在初始化、配置、装饰或者是装配完一个prototype实例后,将它交给客户端,随后就对该prototype实例不闻不问了。不管何种作用域,容器都会调用所有对象的初始化生命周期回调方法,而对prototype而言,任何配置好的析构生命周期回调方法都将不会被调用。 清除prototype作用域的对象并释放任何prototype bean所持有的昂贵资源,都是客户端代码的职责。(让Spring容器释放被singleton作用域bean占用资源的一种可行方式是,通过使用 bean的后置处理器,该处理器持有要被清除的bean的引用。)...
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
...
</web-app>
,如果是Servlet2.4以前的web容器,那么你要使用一个javax.servlet.Filter的实现:
..
<filter>
<filter-name>requestContextFilter</filter-name>
<filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>requestContextFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
...
</web-app>
接着既可以配置bean的作用域了:
privatefinal ThreadLocal threadScope = new ThreadLocal() {
protected Object initialValue() {
returnnew HashMap();
}
};
public Object get(String name, ObjectFactory objectFactory) {
Map scope = (Map) threadScope.get();
Object object = scope.get(name);
if(object==null) {
object = objectFactory.getObject();
scope.put(name, object);
}
return object;
}
public Object remove(String name) {
Map scope = (Map) threadScope.get();
return scope.remove(name);
}
publicvoid registerDestructionCallback(String name, Runnable callback) {
}
public String getConversationId() {
// TODO Auto-generated method stub
returnnull;
}
}