您的位置:首页 > 编程语言 > Java开发

Spring 学习笔记2—— IoC容器

2017-01-10 22:57 525 查看
-本文大部分内容来源于《SPRING攻略++第2版》学习过程-

必须实例化SpringIoC容器,读取其配置来创建bean实例,然后从Spring IoC容器中得到可用的bean实例。

Spring提供两种IoC容器实现类型。

Bean factory

Application contet

应用程序上下文提供比Bean工厂更高级的特性,两种类型配置文件相同。

Bean工厂接口是:BeanFactory

应用程序上下文接口:ApplicationContext

ApplicationContext接口是用于保持兼容性的BeanFactory子接口。

实例化应用程序上下文

ApplicationContext仅仅是一个接口,必须实例化一个接口的实现。ClassPathXml ApplicationContext实现从classpath中装入一个XML配置文件,构建一个应用程序上下文。也可以为其指定多个配置文件。

ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");


除了ClassPathXmlApplicationContext,Spring还提供多种其它的ApplicationContext实现。

FileSystemXmlApplicationContext

XmlWebApplicationContet

XmlPortletApplicationContext

从IoC容器中得到Bean

为了从Bean工厂或者应用程序上下文中得到已声明的bean,只需要调用getBean()方法并且传递唯一的bean名称。getBean()方法的返回类型为java.lang.Object,在使用前必须将其转换为实际的类型。

SequenceGenerator generator=(SequenceGenerator)context.getBean("sequenceGenerator");


到这一步,就能像使用任何使用构造函数创建的对象一样,自由使用bean了。

配置Spring IoC容器中的Bean

Spring提供了一个强大的IoC容器来管理组成应用的bean。为了利用容器服务,必须配置运行于Spring IoC容器中的Bean。

可以通过Xml文件、属性文件、注释甚至API来配置Spring IoC容器中的Bean。

Spring允许在一个或多个bean配置文件中配置bean。对于简单的应用程序,可以在单个配置文件中集中配置bean。但对于有多个bean的大型应用,应根据功能分割到多个配置文件中。

假定开发一个生成序列号的应用程序,为不同用途生成许多系列的序列号,每个系列都有自己的前缀、后缀和初始值。因此,需要在应用程序中创建和维护多个生成器实例。

创建Bean类

按照需求,创建具有prefix、suffix和initial3个属性的SequenceGenerator类,这可以通过setter或构造函数注入。私有字段counter用于保存这个生成器的当前数值。每当在生成实例上调用getSequence()方法,都将得到加上前缀和后缀的最新序列号。将这个方法声明为同步(synchronized),使其成为线程安全的方法。

package com.apress.springprcipes.sequence;

public class SequenceGenerator {
private String prefix;
private String suffix;
private int initial;
private int counter;

public SequenceGenerator(){}

public SequenceGenerator(String prefix,String suffix,int initial){
this.prefix=prefix;
this.suffix=suffix;
this.initial=initial;
}

public void setPrefix(String prefix){
this.prefix=prefix;
}
public void setSuffix(String suffix){
this.suffix=suffix;
}
public void setInitial(int initial){
this.initial=initial;
}
public synchronized String getSequence(){
StringBuffer buffer=new StringBuffer();
buffer.append(prefix);
buffer.append(initial+counter++);
buffer.append(suffix);
return buffer.toString();
}
}


这个SequenceGenerator类可以由取值/设值方法或者构造函数配置。

使用容器进行配置时,这种方法被称为构造函数注入和设值方法注入。

创建Bean配置文件。

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/springbeans-3.0.sd"> ...
</beans>


在Bean配置文件中声明bean

每个bean都应该提供一个唯一的名称或者id,以及一个完全限定的类名,用来让Spring IoC容器对其进行实例化。对于简单类型的每个bean属性,可以为其指定一个元素。Spring会试图将指定的值转换为该属性的声明类型。为了通过设值方法注入配置一个属性,可以使用元素,并在其name特性中指定属性名称。每个要求bean包含对应的一个设值方法。

<bean name="sequenceGenerator"
class="com.apress.springrecipes.sequence.SequenceGenerator">
<property name="prefix">
<value>30</value>
</property>
<property name="suffix">
<value>A</value>
</property>
<property name="initial">
<value>10000</value>
</property>
</bean>


也可以在元素中声明,通过构造函数来配置Bean属性。中没有name属性,参数是基于位置的。

<bean name=...>
<constructor-arg><value>30</value></constructor-arg>
<constructor-arg><value>A</value></constructor-arg>
<constructor-arg><value>10000</value></construcor-arg>
</bean>


在 Spring中,如果装入了超过一个上下文,允许重复的名称覆盖Bean声明。Bean名称可由的name属性定义。但首先的方法是通过id属性。

XML在id属性有字符限制,比如不能用一些特殊字符。 name里允许用逗号,但id不允许。

Spring支持指定简单类型属性值的一个简写。如:

<property name="prefix" value="30" />


从Spring2.0开始,添加了这样一种简写:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/springbeans-3.0.sd"> <bean id="sequenceGenerator" class="..." p:prefix="30" p:suffix="A" p:initial="100000" />
</beans>


为Bean配置集合

Java的主要集合类型:List/Set/Map。

例如 : 允许序列生成器具有超过一个后缀,这些后缀将附加在序列号后面,以连字号分隔。

package com.apress.springprcipes.sequence;

import java.util.List;

public class SequenceGenerator {
private String prefix;
private List<Object>suffixes;
private int initial;
private int counter;

public SequenceGenerator(){}

public SequenceGenerator(String prefix,String suffix,int initial){
this.prefix=prefix;
this.initial=initial;
}

public void setPrefix(String prefix){
this.prefix=prefix;
}
public void setInitial(int initial){
this.initial=initial;
}
public synchronized String getSequence(){
StringBuffer buffer=new StringBuffer();
buffer.append(prefix);
buffer.append(initial+counter++);
for(Object suffix:suffixes){
buffer.append("-");
buffer.append(suffix);
}
return buffer.toString();
}

public void setSuffixes(List<Object>suffixes){
this.suffixes=suffixes;
}
}


bean定义

<bean id="sequenceGenerator"
class="com.apress.springrecipes.sequence.SequenceGenerator">
<property name="initial" value="100000" />
<property name="suffixes">
<list>
<value>A</value>
<bean class="java.net.URL">
<constructor-arg value="http" />
<constructor-arg value="www.apress.com" />
<constructor-arg value="/" />
</bean>
<null />
</list>
</property>
</bean>


另外set接口、Map、Properties详情可见原书《SPRING攻略++第2版》 P9。

合并父Bean集合

原书P12 略……

调用构造函数创建Bean

原书P14 略……

Spring IoC容器中Bean的生命周期

本部分学习资源来源于《尚硅谷 玩转JAVA系列》

Spring IoC 容器可以管理Bean的生命周期,Spring允许在Bean生命周期的特定点执行定制的任务。

Spring IoC容器中Bean的生命周期如下:

通过构造函数或工厂方法创建Bean实例:调用构造函数

为Bean的属性设置值和对其他Bean的引用:调用setter

将Bean实例传递给Bean后置处理器的postProcessBeforeInitialization方法

调用Bean的初始化方法init-method

将Bean实例传递给Bean后置处理器的postProcessAfterInitialization方法

Bean可以使用了

当容器关闭时,调用Bean的销毁方法:destroy-method。

Bean的初始化和销毁方法:可以通过bean节点的init-method和destroy-method来配置Bean的初始化方法和销毁方法:

<bean id="person" class="com.atguigu.spring.lifecycle.Person" init-method="init"
destroy-method="destroy">
<property name="name" value="abcd"></property>
</bean>


ApplicationContext接口中没有关闭容器的方法,所以使用ApplicationContext接口作为IoC容器的引用,destroy-method将不会起作用,需要使用ApplicationContext的子接口ConfigurableApplicationContext。

Bean 后置处理器

允许在调用初始化方法(即:bean节点init-method属性对应的方法的前后)对Bean进行额外的处理

Bean后置处理器对IoC容器里的所有Bean实例逐一处理,而非单一实例。其典型应用是:检查Bean属性的正确性或根据特定的标准更改Bean的属性。

对Bean后置处理器而言,需要实现BeanPostProcessor接口
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: