一 容纳Bean
1 Spring 容器
在基于Spring的应用中,应用组件在Spring中是激活的。容器可以创建组件,装配和配置组件,以及管理它们的整个生
命周期。
容器是Spring 框架的核心,Spring容器使用DI管理所有组成应用系统的组件。Spring容器提供多个Spring 容器。Spring容器提供了多种容器,并分为两类。Bean工厂是最简单的容器,提供了基础的依赖注入的支持。应用上下文建立在Bean工厂基础之上,提供了系统架构服务。
2 BeanFactory
Bean 工厂是一个通用的工厂,可以创建和分发各种类型的Bean。最常用的beanFactory 是XmlBeanFactory,它从
xml文件中读取bean的信息。 为从BeanFactory得到一个bean,只要简单的调用getBean() 方法,把你需要的bean的
名字,当做参数传递过去。
3 使用上下文
ApplicationContext 和 BeanFactory 相比,但是前者有着更多的功能。几乎所有的系统会选择ApplicationContext
有以下三种实现:
(1) ClassPathXmlApplication 从类路径的xml文件载入上下文定义信息,把上下文定义文件当成类路径信息。
(2)FileSystemXmlApplicationContext 从文件系统中的xml文件导入。
(3) XmlWebApplicationContext 从web系统中的xml文件载入上下文定义信息。
4 配置Bean的方法
(1) 构造函数配置
(2) Setter方法(个人喜欢用)
5 注入Bean属性
(1) 定义了一个天才的演奏家 ,
public class Instrumentalist implements Performer{
private Instrument instrument ;
private String song ;
public Instrumentalist(){
}
public void performer() throws Exception {
// TODO Auto-generated method stub
System.out.println("playing the song");
this.instrument.play() ;
}
public void setInstrument(Instrument instrument) {
this.instrument = instrument;
}
public void setSong(String song) {
this.song = song;
}
(2) 其中Instrument 为一个接口
public interface Instrument {
void play() ;
}
(3) 定义一个类Dumb 实现了Instrument类接口
public class Dumb implements Instrument {
public void play() {
// TODO Auto-generated method stub
System.out.println("this dumb is singing");
}
}
(4)配置文件
<bean id="dumb" class="cn.bupt.duming.bean.Dumb">
</bean>
<bean id="kenny" class="cn.bupt.duming.bean.Instrumentalist">
通过set方法属性,替代构造函数
<property name="song" value="brave heart"></property>
若参数为一个类的势力,则采用下面的方法,植入参数
<property name="instrument" ref="dumb"></property>
</bean>
(5) 注意事项
关于value属性的使用,字段String 和 int 之间是没有区别的,Spring 能够根据字段属性来自动决定正确的类型。
6 注入内部Bean
内部Bean------------即在其他类的范围内所定义的类。内部bean就是在其他Bean的范围内所定义的bean ,考虑
上面实例的一个特殊情况,将dumb作为 kenny的一个内部bean ,代码如下:
<bean id="kenny" class="cn.bupt.duming.bean.Instrumentalist">
<property name="song" value="brave heart"></property>
<property name="instrument" >
<bean class="cn.bupt.duming.bean.Dumb"></bean>
</property>
</bean>
(2) 内部类的最大的缺点是:它们不能复用。内部bean只用于注入,不能被其他bean所使用。
7 装配集合
上面介绍了Spring配置的基本类型通过value ,而其他类通过ref,但是value和ref只有在属性是单一的时候才有效。
Spring 提供了4个类型的集合配置元素。
集合元素 用途
<list> 装配一列值 , 可以重复
<set> 装配值集 , 确保无复制
<map> 装配名称-值对的集合,名称和值可以是任意类型
<props> 装配名称-值对的集合,名称和值都是String类型
实例如下
(1) 构造OneManBand 实例 ,并且实现performer实例
public class OneManBand implements Performer {
private Collection <Instrument> instruments ;
public void performer() throws Exception {
// TODO Auto-generated method stub
for(Instrument instrument : instruments){
instrument.play() ;
}
}
public OneManBand(){
}
public void setInstruments(Collection<Instrument> instruments) {
this.instruments = instruments;
}
}
配置文件如下:
<bean id="guitar" class="cn.bupt.duming.bean.Guitar"></bean>
<bean id="cymbal" class="cn.bupt.duming.bean.Cymbal"></bean>
<bean id="harmonica" class="cn.bupt.duming.bean.Harmonica"></bean>
<bean id = "hank" class="cn.bupt.duming.bean.OneManBand">
<property name="instruments">
<list>
<ref bean="guitar"/>
<ref bean="cymbal"/>
<ref bean="harmonica"/>
</list>
</property>
</bean>
(2)改用Maps 实现上述实例
public class OneManBandDemo2 implements Performer {
private Map<String , Instrument> instruments ;
public OneManBandDemo2(){
}
public void performer() throws Exception {
// TODO Auto-generated method stub
for(String key : instruments.keySet()){
System.out.println(key + ":");
Instrument instrument = instruments.get(key) ;
instrument.play() ;
}
}
public void setInstruments(Map<String, Instrument> instruments) {
this.instruments = instruments;
}
}
配置文件如下:
<bean id="jake" class="cn.bupt.duming.bean.OneManBandDemo2">
<property name="instruments">
<map>
<entry key="GUITAR" value-ref="guitar"> </entry>
<entry key="CYMBAL" value-ref="cymbal"></entry>
<entry key="HARMONICA" value-ref="harmonica"></entry>
</map>
</property>
</bean>
(3)利用Properties 重写代码
public class OneManBandDemo3 implements Performer {
private Properties instruments ;
public OneManBandDemo3(){
}
public void setInstruments(Properties instruments) {
this.instruments = instruments;
}
public void performer() throws Exception {
// TODO Auto-generated method stub
for(Iterator iter = instruments.keySet().iterator() ;iter.hasNext();){
String key = (String)iter.next() ;
System.out.println(key + ":" + instruments.getProperty(key));
}
}
}
配置代码如下:
<bean id="jake" class="cn.bupt.duming.bean.OneManBandDemo3">
<property name="instruments">
<props>
<prop key="GUITAR">STRUM</prop>
<prop key="CYMBAL">CRASH</prop>
<prop key="HARMONICA">HUM</prop>
</props>
</property>
</bean>
(4) 装配空值
<property name="instruments"><null/></property>
8 自动装配
按照上面的方法,来装载bean的属性,通常会带来大量的xml,可以让Spring自动装配,只要设置需要自动装配<bean>中的autowrite属性。
(1) byName 试图在容器中寻找和需要自动装配的属性名相同的bean。如果没有找到到相符的Bean ,这个属性就
没有装配。
(2)byType 试图在容器中寻找和需要自动装配的属性类型相同的bean 。
(3)constructor 试图在容器中查找与需要自动装配的bean的构造函数参数一致的一个或多个bean。
(4)autodetect 首先尝试用constructor来自动装配,然后用byType方式。
9 控制bean创建
(1) bean的范围化
在Spring中声明<bean>时,有声明bean范围的选项,为了使每次都能产生一个新的实例,可以声明bean的
scope属性为prototype。
<bean id="harmonica" class="cn.bupt.duming.bean.Harmonica" scope="prototype"></bean>
默认的范围是singleton ,即单例模式。
(2)利用工厂方法来创建bean
public class Stage {
private Stage(){
}
private static class StageSingletonHolder{
static Stage instance = new Stage();
}
// 利用静态方法返回实例。
public static Stage getInstance(){
return StageSingletonHolder.instance ;
}
public void perform(){
System.out.println("perform");
}
}
在配置文件中,可以使用factory-method来配置。
<bean id="stage" class="cn.bupt.duming.scope.Stage"
factory-method ="getInstance">
</bean>
(3)初始化和销毁bean
当实例化bean,有必要执行一些初始化的工作使其处于可用的状态。再其不需要再从容器中删除,有些清除工作是有
顺序的。spring提供了 bean生命周期的钩子。 要建立bean初始化时,要调用init-method和destroy-method参数来
声明bean 。
<bean id="kenny" class="cn.bupt.duming.bean.Instrumentalist"
init-method="tuneInstrument" destroy-method="cleanInstrument">
还可以实现两个特定的spring 接口,InitializingBean , DisposableBean 是spring的接口。