Spring IOC也就是控制反转(Inverse of Control)是Spring容器的的内核,AOP、声明式事务都是在此基础上建立的。
所谓的IOC就是把传统的用程序控制业务对象之间的关系的控制权交给容器来操控,比如传统的要实例化一个对象,需要代码来new,何时new,new几个,都需要写代码来实现,在Spring IOC里把这种操作交给容器来做,把控制权由应用代码转到了外部容器,这就是“控制反转”思想的所在,IOC带来的好处就是降低了业务对象之间的依赖程度,让开发人员不必关注对象的创建,而只关注于对象的使用。
Spring IOC是通过一个配置文件来描述每个Bean之间的依赖关系,利用java语言的反射功能来实例化Bean并建立Bean之间的依赖关系。在创建实例化Bean的工具上,Spring提供了两种方式:Beanfactory 和 ApplicationContext两个接口。
BeanFactory是Spring最核心的接口,提供了高级IOC的配置机制。是Spring框架的基础设施,面向Spring本身
ApplicationContext是以BeanFactory作为基础的,提供了面向应用的功能,国际化支持和框架事件体系,对于创建应用来说,ApplicationContext比BeanFactory更接地气。
下面来看下两种实现方式的区别
JavaBean类:Car.java
JavaBean类:Car.java
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
packagelearning.ioc.pojo;
publicclassCar{
privateStringbrand;
privateStringcolor;
privateStringmaxSpeed;
publicStringgetBrand(){
returnbrand;
}
publicvoidsetBrand(Stringbrand){
this.brand=brand;
}
publicStringgetColor(){
returncolor;
}
publicvoidsetColor(Stringcolor){
this.color=color;
}
publicStringgetMaxSpeed(){
returnmaxSpeed;
}
publicvoidsetMaxSpeed(StringmaxSpeed){
this.maxSpeed=maxSpeed;
}
publicStringtoString(){
returnthis.getBrand()+" "+this.getColor()+" "+this.getMaxSpeed();
}
}
配置文件:Beans.xml
beans.xml
XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
p:brand="长安CX75"p:color="珍珠白"p:maxSpeed="300公里/h"/>
BeanFactory的初始化方法:
BeanFactory的初始化方法
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
packagelearning.ioc.start1;
importlearning.ioc.pojo.Car;
importorg.springframework.beans.factory.BeanFactory;
importorg.springframework.beans.factory.support.DefaultListableBeanFactory;
importorg.springframework.beans.factory.xml.XmlBeanDefinitionReader;
importorg.springframework.core.io.Resource;
importorg.springframework.core.io.support.PathMatchingResourcePatternResolver;
importorg.springframework.core.io.support.ResourcePatternResolver;
publicclassBeanFactorySample{
publicstaticvoidmain(String[]args){
ResourcePatternResolverresolver=newPathMatchingResourcePatternResolver();
Resourceres=resolver.getResource("classpath:learning/ioc/start1/beans.xml");
/*
* 这种初始化BeanFactory的方式,在Spring 3.x之后就不在使用,
* 该程序是基于Spring 4.1.6基础上 写的
BeanFactory bf = new XmlBeanFactory(res);
System.out.println("Init BeanFactory...");
Car car = bf.getBean(Car.class);
System.out.println(car.toString());
*/
DefaultListableBeanFactorydbf=newDefaultListableBeanFactory();
XmlBeanDefinitionReaderxmlbdr=newXmlBeanDefinitionReader(dbf);
xmlbdr.loadBeanDefinitions(res);
BeanFactorybf=dbf;
System.out.println("Init BeanFactory...");
Carcar=bf.getBean(Car.class);
System.out.println(car.toString());
/*
* 下面这段代码是 单例缓存器的 一个应用
* DefaultSingletonBeanRegistry 提供了一个用于缓存单实例bean的缓存器,
* 其实就是用了一个HashMap实现的,把每个单实例bean的对象实例保存在这个map里
DefaultSingletonBeanRegistry dsbr = new DefaultSingletonBeanRegistry();
dsbr.registerSingleton("car", car);
Car car1 = (Car)dsbr.getSingleton("car");
System.out.println(car1.toString());
*/
}
}
ApplicationContext的实例化Bean的方法:
ApplicationContext实例化bean
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
packagelearning.ioc.start1;
importlearning.ioc.pojo.Car;
importorg.springframework.context.ApplicationContext;
importorg.springframework.context.support.ClassPathXmlApplicationContext;
publicclassAppContextSample{
publicstaticvoidmain(String[]args){
System.out.println("Init BeanFactory...");
ApplicationContextappContext=newClassPathXmlApplicationContext("learning/ioc/start1/beans.xml");
/**
*
* 配置文件在文件系统里
*ApplicationContext appContext = new FileSystemXmlApplicationContext("learning/ioc/start1/beans.xml");
*
*指定一组配置文件
*ApplicationContext appContext = new ClassPathXmlApplicationContext(new String[]{"learning/ioc/start1/beans.xml"});
*/
Carcar=appContext.getBean(Car.class);
System.out.println(car.toString());
}
}
ApplicationContext 和 BeanFactory的区别:
ApplicationContext 是由 BeanFactory派生而来的,提供了更多面向实际应用的功能。
BeanFactory 的很多功能是基于编程的方式实现的,而ApplicationContext则是通过配置的方式实现的。
两者在初始化Bean时的区别:
BeanFactory在初始化容器的时候并未实例化bean,而是在第一次访问某个bean时才会实例化目标bean
ApplicationContext在初始化应用上下文的时候就实例化所有的单实例bean
因此,ApplicationContext的初始化要比BeanFactory时间长一些,但也就没有稍后调用的“第一次惩罚”的问题