Spring Framework 官方文档学习(二)之IoC容器与bean lifecycle

到目前为止,已经看了一百页。再次感慨下,如果想使用Spring,那可以看视频或者找例子,但如果想深入理解Spring,最好还是看官方文档。

 

原计划是把一些基本接口的功能、层次以及彼此的关系罗列一下。同时兼顾版本的演化,简述下相应功能的历史,最好是画一张图。

BeanPostProcessor接口为例,当configuration metadata中有其实现的bean definition时,容器会在所有bean创建完成后执行其中的方法,但是会在@PostContruct之前。

BeanPostProcessor对应的beans会在容器创建早期进行初始化,并会将其依赖也提前初始化。

 

等等。

希望周二之前完成。

【--无语的是,没想到直接找到了一张图(见末尾),倒是省事了】

 

发现要写的东西太多了,应该有所区分,比如一部分将原理,一部分将应用。先写完再说吧。

基本概念 

一、什么是IoC/DI?

  一种设计模式,IoC(控制反转),目的是将对象的创建与使用分离开来,以让用户更专注于业务逻辑。

  后来有位大虾觉得IoC不好理解,难以顾名思义,就写了一篇 文章 建议改口叫DI(依赖注入)。

  然后导致了今天的状态,IoC和DI经常混杂出现。

  ps:至今未见DI容器一说。DI更被当作一个动词,而非名字。

二、什么是IoC容器?

  负责创建对象的地方,老外将其命名为IoC Container

  而在Spring框架下,IoC Container 是由ApplicationContext接口代表的。

  换句话说,你可以认为 ApplicationContext对象 就是一个IoC容器。(注意,仅限于Spring框架)

三、Spring IoC容器 能做什么?

  从配置元数据(configuration metadata)中读取 bean definitions,然后创建beans

  ApplicationContext本质上是一个高级工厂接口,能够维护不同bean的注册和依赖。

四、什么是 配置元数据(configuration metadata)?

  包含bean definition的配置。可以是XML格式(默认),也可以基于注解(自Spring 2.5起)或Java编码(自Spring 3.0起)。

五、什么是 bean

  由Spring IoC容器 管理和操作的对象。负责它们的初始化、装配以及管理。

六、什么是 bean definition

  就是 bean定义,描述了一个bean 实例,包括类、构造方法(或工厂方法)、参数(值或引用)、scope等等。

  在容器内部,它们对应 org.springframework.beans.factory.config.BeanDefinition接口的对象,包含以下元数据:

1 限定package的类名:通常是bean的实际实现类。
2 bean行为配置元素,描述了bean在容器中的行为(scope、lifecycle callbacks,以及其他)。
3 对所需bean的引用,通常称为  collaborators or dependencies 。
4 其他配置设置,例如,连接池的连接数等。

  元数据会被翻译成一组properties,以构成各个bean definition

 

 

关键概念

 

如何创建Spring IoC Container?/如何创建ApplicationContext对象?

这两个问题可以说是同一个问题,至于原因,在前面有提到(二、什么是IoC容器?)。

其实这个问题没多少意义,因为创建对象我们都会,构造方法或者factory创建,具体的见Javadoc就是。

这里,ApplicationContext是个接口,但Spring已经提供了一些实现以供我们在不同环境下使用,所以直接调用其实现类的构造方法创建即可。

如下:

ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"});

但是,这只是原理部分,实际工作环境中往往不需要手动创建Spring IoC容器ApplicationContext)。

例如web应用环境下,只需要将ContextLoaderListener注册到Servlet容器中,就会在容器启动的时候自动创建Spring IoC容器

事实上,ContextLoaderListener是一个监听器,监听Servlet容器的启动过程,并创建Spring IoC容器。

详见我的 ContextLoader,ContextLoaderListener解读

 

 

,有时间再改。

需要说明的是,除了自身创建的bean,IoC容器还允许注册在其外部创建的对象。这是通过ApplicationContext 的 getBeanFactory()方法获取 BeanFactory 来完成的,实际上返回的是 BeanFactory的实现 DefaultListableBeanFactory。 它支持上面说的这种注册: registerSingleton(..) and registerBeanDefinition(..) 。

Spring容器在被创建时就会校验每个bean的配置。但直到创建bean时,才会设置bean properties单例且被设置成pre-instantiated(默认)的bean是在容器被创建时创建否则,都是被请求的时候才创建

 

关键概念

Spring bean lifecycle

当一个bean被实例化时,需要进行一系列的初始化工作,才能被使用。同样的,当不再需要它,需要从容器中移除时,也有一些清理工作需要进行。

Spring设计了一系列接口,提供了在lifecycle不同阶段的回调方法 -- 由IoC容器识别,并在不同阶段调用。--本质上,属于AOP。

例如,org.springframework.beans.factory.InitializingBean接口 和 org.springframework.beans.factory.DisposableBean接口,

凡是实现了它们的bean,容器会在它们构造完成后、销毁之前调用相应的方法。

例如,还有BeanPostProcessor接口,会在每个bean初始化完成后执行相应方法。--容器调用。而且这个执行是在InitializingBean接口的方法之前。

需要注意的是,由于BeanPostProcessor对象实例化太早,会导致一些问题。例如导致其依赖的提前初始化,导致无法使用自动注入的注解,导致aop代理无法启用等等。需要小心使用。

 

找到一张好图,如下:

突然就没有说的欲望了。。因为这张图完整的描述了bean lifecycle中各阶段的行为。

卧槽,我辛苦总结半天,还不如一张图来的清楚,受伤了。

 

补充:

1 <bean class="...">
2     <property name=".." value=".."/>
3 </bean>

像上面这种给property设值的情况,是在@PostConstruct method之前进行的!!!原因可以参考@Bean method,如下:

1 @Bean
2 public A a(){
3     A a= new A();
4     a.setProperty(...);
5     return a;
6 }

 

 

ps:

图片来自 Spring in Action 4th edition,p45

--Figure 1.5  A Bean goes through several steps between creation and destruction in the Spring container. Each step is an opportunity to customize how the bean is managed in Spring.

--图1.5 一个bean在Spring容器中的从被创建到被销毁之间的几个步骤。每个步骤都可以用来定制在Spring中如何管理该bean

 

做了一个小demo放在码云上,有需要的可以下下来看看。

地址

欢迎讨论。

posted on 2016-09-24 21:09  LarryZeal  阅读(2028)  评论(0编辑  收藏  举报

导航