chapter02 Spring的IoC
一、IoC的概念
IoC,Inversion of Control,控制反转。
对象的协作关系由对象自己负责。
依赖注入:对象的协作关系由容器来建立。
二、IoC的类型
(1) 基于特定接口(侵入式方案)
(2) 基于set方法
(3) 基于构造器
IOC的基本使用,依赖注入的基本使用?
1、set方式的装配。
2、构造器的方式
三、Spring容器
Spring容器负责生成、组装、销毁组件,并负责事件处理、国际化等功能。
(1) BeanFactory<interface>
① 核心容器,负责组件生成和装配
② 实现主要包括Xml BeanFactory
(2) ApplicationContext
(3) WebApplicationContext
(4) ……
四、IoC的使用
Resource:interface,用来包装资源
xmlBeanFactory:BeanFactory的一个实现,使用Resource对象来查找配置文件
BeanFactory.gerBean(“BeanId”):取得以参数命名,或者Id等于参数值的一个Bean实例。
BeanFactory(容器)在默认情况下,会采用单例方式返回对象。容器只到调用getBean方法时,才会实例化某个对象。
(1) Spring可以采用XML或者.properties文件作配置
(2) 配置文件(XML)
根元素<beans>可以有多个<bean>子元素,每个<bean>代表一个需要装配的对象。
1、setter注入
(1) 注入简单属性(String和8中基本类型)
<beans>
<bean id=”BeanId用来区别bean” class=”classpath” autowire=” ” dependency-check=” ”>
<property name=”parameterName”>
<value>parameterValue</value>
</property>
</bean>
</beans>
对于基本类型,Spring容器会自动作类型转换,以便赋值。
获得bean的方法:
1)首先解析配置文件
ApplicationContext ac =
new ClassPathXmlApplicationContext("ioc1\\applicationContext.xml");
构造spring容器并加载配置文件及其内容,并不加载bean实例
2)使用上下文对象的getBean("beanid")方法来获得装配的bean对象
找到配置文件中对应id的bean标签,然后对属性调用相应的set方法。然后返回该bean的实例。
使用set方式注入要有一个缺省的构造器
(2) 注入对象
<bean id="otherBean" class="ioc2.OtherBean">
<property name="str1">
<value>string1</value>
</property>
</bean>
<bean id="someBean" class="ioc2.SomeBean">
<property name="ob">
<ref bean="otherBean"/>
或者用<ref local=”otherBean”>只能在当前的配置文件中找otherBean,而用ref bean会搜索所有已加载的配置文件
</property>
<!-- 对象的注入方式3-->
<!-- <property name="ob">
<bean id="otherBean" class="ioc3.OtherBean">
<property name="s">
<value>hello world</value>
</property>
</bean>
</property> -->
</bean>
A、让Spring容器在当前配置文件中找到相应的Bean,并调用set方法,注入该Bean。
B、将一个Bean的定义嵌套在另一个Bean中(可读性差),被嵌套的Bean不能采用getBean()返回
C、采用<ref bean=” ”>搜索多个配置文件来注入
(3) 注入集合类型
① Set
Set中存放字符串,对象,集合,不允许重复
② List
List中可以放入字符串,对象,List
③ Map
Map 有<entry>子元素来存取key,value,key只能为String
④ Properties
Properties有<props>子元素 key和value都只能是字符串
2、consctructor注入
要提供初始化属性的构造器
<bean>
<constructor-arg>
<value>基本类型的装配</value>
</constructor-arg>
<constructor-arg index="从0开始" type="参数的类型">
<ref bean= “ ” />
</constructor-arg>
默认情况装配的顺序要跟构造器的参数顺序相对应,如果加了index属性,则可以为指定位置的属性赋值
</bean>
如果Bean属性不多,并且属性值必须要注入才能使用,则应该采用constructor注入,其他情况就要set方法注入。因为他存在循环依赖问题,例如A,B两个对象如果互相持有对方的对象。在构造对象的时候就会出现循环依赖的问题
3.复杂装配:
(1)自动装配(Autowring Properties)
<bean id="" class="" autowire="?">
注意要为属性提供set方法
让容器依据某种规则,自动地对组件实施装配
autowire=""下面是它的取值
byName:匹配属性名与bean的id名字
byType:寻找配置文件,匹配属性的类型与bean 的类型,成功就设置
如果匹配的个数超过一个,(尤其是父子类都存在配置的情况)报错。
constructor:匹配构造器,看构造器的参数类型与bean的类型是否一致
,成功就设置,如果匹配的个数超过一个,报错。
autodetect:先按照constructor,然后byType
自动装配容易出错,一般用于快速建立代码原型,建议少用自动装配
(2)检查装配情况:
dependency-check=""
simple:检查基本类型属性是否装配成功
object:检查Object类型装配是否成功
all:全检查
(3)Bean的范围(ppt22):bean的获得方式与生存范围
scope=""
singleton单例(spring默认的情况下获得的都是同一个实例),
prototype,原型的方式获得bean
request,session,global-session,只用在webApplicationContext的情况下
(4)Bean定义的继承:
继承抽象:abstract="true",parent=""
也可直接继承
(5)工厂方式创建实例:
静态工厂
factory-method=""
工厂
factory-bean=""
factory-method=""
5、Bean的生命周期
(1)生命周期图
1)调用缺省构造的实例
2)装配
3)回调:A------->ApplicationContextAware bean获得的引用
B------>init-method初始化方法
4)就绪
5)回调 销毁对象----->destroy-method
(2)初始化与销毁(PPT25)
init-method,destroy-method
在非WEB应用中,对于Singleton的Bean所设置的destroy方法,可执行
AbstractApplicationContext.registerShutdownHook()。
(3)后处理Bean(PPT31)这两个接口是用来扩展容器的功能的。比较重要
所谓的后处理bean,是在bean 在被实例化后被调用的bean,会在bean的初始化饭方法调用之前,之后分别调用,实现了该接口的bean可以拿过来被对其他的bean进行加工
接口:org.springframework.beans.factory.config.BeanPostProcessor
Spring已经实现该接口的BeanPostProcessor(不用再注册)
它的两个方法:
postProcessAfterInitialization(Object 被拦截的bean, String bean的id);
postProcessBeforeInitialization(Object bean, String beanName)
ApplicationContextAwareProcessor:
把应用上下文传递给所用实现了 ApplicationContextAware接口的Bean ApplicationContextAware接口使用举例,可参照事件监听机制 DefaultAdvisorAutoProxyCreator自动对Bean应用切面
(4)Bean工厂后处理(只能在应用上下文中使用)
接口:org.springframework.beans.factory.config.BeanFactoryPostProcessor
它在读取配置文件之后,bean实例化之前被执行。一般用于修改配置文件的内容,“所谓的偷天换日”
Spring内部接口实现:
org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
它首先实现了BeanFactoryPostProcessor接口,然后进行分散配置()属性编辑 见ppt中的例子
另外一个类org.springframework.beans.factory.config.CustomEditorConfigurer的作用。我们可以以自变量的方式为不同类型的属性赋值
应用示例:
package ioc9;
public class Address {
private String city;
private String street;
private int roomNum;
public void setCity(String city) {
this.city = city;
}
public void setRoomNum(int roomNum) {
this.roomNum = roomNum;
}
public void setStreet(String street) {
this.street = street;
}