为什么80%的码农都做不了架构师?>>>   

Spring实际上是一个容器框架,可以配置各种bean(action/service/domain/dao...),并且可以维护bean与bean的关系。

ioc是什么?

答 :ioc(inverse of controll ) 控制反转: 所谓控制反转就是把创建对象(bean),和维护对象(bean)的关系的权利从程序中转移到spring的容器(applicationContext.xml),而程序本身不再维护。

DI是什么?

答: di(dependency injection) 依赖注入: 实际上di和ioc是同一个概念,spring设计者认为di更准确表示spring核心技术。

下面以BeanFactory为例,说明一个Bean的生命周期活动:

1.Bean的建立

由BeanFactory读取Bean定义文件,并生成各个实例。

2.Setter注入

执行Bean的属性依赖注入。

3.BeanNameAware的setBeanName()

如果Bean类实现了org.springframework.beans.factory.BeanNameAware接口,则执行其setBeanName()方法。

4.BeanFactoryAware的setBeanFactory()

如果Bean类实现了org.springframework.beans.factory.BeanFactoryAware接口,则执行其setBeanFactory()方法。

5.BeanPostProcessors的processBeforeInitialization()

容器中如果有实现org.springframework.beans.factory.BeanPostProcessors接口的实例,则任何Bean在初始化之前都会执行这个实例的processBeforeInitialization()方法。

6.InitializingBean的afterPropertiesSet()

如果Bean类实现了org.springframework.beans.factory.InitializingBean接口,则执行其afterPropertiesSet()方法。

7.Bean定义文件中定义init-method

在Bean定义文件中使用“init-method”属性设定方法名称,如下:

<bean id="demoBean" class="com.nyp.bean.DemoBean" init-method="initMethod">.......</bean>

这时会执行initMethod()方法,注意,这个方法是不带参数的。

8.BeanPostProcessors的processAfterInitialization()

容器中如果有实现org.springframework.beans.factory.BeanPostProcessors接口的实例,则任何Bean在初始化之前都会执行这个实例的processAfterInitialization()方法。

9.DisposableBean的destroy()

在容器关闭时,如果Bean类实现了org.springframework.beans.factory.DisposableBean接口,则执行它的destroy()方法。

10.Bean定义文件中定义destroy-method

在容器关闭时,可以在Bean定义文件中使用“destory-method”定义的方法

<bean id="demoBean" class="com.nyp.bean.DemoBean" destory-method="destroyMethod">.......
</bean>

这时会执行destroyMethod()方法,注意,这个方法是不带参数的。

以上就是BeanFactory维护的一个Bean的生命周期。下面这个图可能更直观一些:

如果使用ApplicationContext来维护一个Bean的生命周期,则基本上与上边的流程相同,只不过在执行BeanNameAware的setBeanName()后,若有Bean类实现了org.springframework.context.ApplicationContextAware接口,则执行其setApplicationContext()方法,然后再进行BeanPostProcessors的processBeforeInitialization()

实际上,ApplicationContext除了向BeanFactory那样维护容器外,还提供了更加丰富的框架功能,如Bean的消息,事件处理机制等。

小结: 我们实际开发中往往,没有用的这么的过程,常见的是:

  1. 实例化

  2. 调用set方法设置属性

  3. 如果bean 和 一个前置处理器关联

  4. 使用我们的bean

  5. 如果bean 和 一个后置处理器关联

  6. 容器关闭

在这里在补充讲一下BeanFactory(Spring心脏) 与ApplicationContext(身躯)比较:

BeanFactory在初始化容器的时候,并未实例化Bean,直到第一次访问Bean时才实例化目标Bean;

ApplicationContext在初始化应用上下文时就实例化所有单实例的Bean(所以初始化比较耗时,不过稍后使用不存在“第一次惩罚”)

另外,Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:

1、Bean自身的方法 :

这个包括了Bean本身调用的方法和通过配置文件中<bean>的init-method和destroy-method指定的方法

2、Bean级生命周期接口方法 :

这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法

3、容器级生命周期接口方法 :

这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。

4、工厂后处理器接口方法 :

这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器 接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。

最后来个演示:

首先是一个bean User

package com.sunsharing.beanlife;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;/*** Created by nyp on 2015/2/27.*/
public class User implements BeanNameAware,BeanFactoryAware,ApplicationContextAware,InitializingBean,DisposableBean{private String name;private Integer age;public Integer getAge() {return age;}public void setAge(Integer age) {System.out.println("属性age set方法:setName(Integer age) 被调用");this.age = age;}public String getName() {return name;}public void setName(String name) {System.out.println("属性name set方法:setName(String name) 被调用");this.name = name;}public User(){System.out.println("构造函数:User ");}public void sayHi(){System.out.println("hi "+ name);}//该方法可以给arg0表示正在被实例化得bean idpublic void setBeanName(String arg0) {// TODO Auto-generated method stubSystem.out.println("BeanNameAware接口:setBeanName 被调用 值"+arg0);}//该方法可以传递beanFactroypublic void setBeanFactory(BeanFactory arg0) throws BeansException {// TODO Auto-generated method stubSystem.out.println("BeanFactoryAware接口:setBeanFactory 被调用"+arg0);}//该方法传递ApplicationContextpublic void setApplicationContext(ApplicationContext arg0)throws BeansException {// TODO Auto-generated method stubSystem.out.println("ApplicationContextAware接口:setApplicationContext "+arg0);}//这是InitializingBean接口方法public void afterPropertiesSet() throws Exception {// TODO Auto-generated method stubSystem.out.println("InitializingBean接口:InitializingBean.afterPropertiesSet()");}// 这是DiposibleBean接口方法public void destroy() throws Exception {System.out.println("DiposibleBean接口:调用DiposibleBean.destory()");}//定制我们的初始化方法public void myinit(){System.out.println("自定义myinit方法 被调用");}//定制我们的销毁方法public void mydestory(){System.out.println("自定义mydestory 释放各种资源");}}

然后是MyBeanPostProcessor

package com.sunsharing.beanlife;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;/*** Created by nyp on 2015/2/27.*/
public class MyBeanPostProcessor implements BeanPostProcessor {public Object postProcessAfterInitialization(Object arg0, String arg1)throws BeansException {// TODO Auto-generated method stubSystem.out.println("BeanPostProcessor接口:postProcessAfterInitialization 函数被调用   "+arg0+"被创建的时间是"+new java.util.Date());return arg0;}public Object postProcessBeforeInitialization(Object arg0, String arg1)throws BeansException {// TODO Auto-generated method stubSystem.out.println("BeanPostProcessor接口:postProcessBeforeInitialization 函数被调用");return arg0;}
}

接着ApplicatationContext.xml的配置

<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"><bean id="personService" init-method="myinit" destroy-method="mydestory"  class="com.sunsharing.beanlife.User"  ><!-- 这里注入我们属性,前提就是有setName才能ok --><property name="name"><value>小明</value></property><property name="age"><value>2015</value></property></bean><!-- 配置我们的自己后置处理器(有点类似我们的filter) --><bean id="myBeanPostProcessor" class="com.sunsharing.beanlife.MyBeanPostProcessor" />
</beans>

最后用一个App类 测试下,

package com.sunsharing.beanlife;/*** Created by nyp on 2015/2/27.*/
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stubSystem.out.println("==========开始初始化容器!==========");BeanFactory factory=new ClassPathXmlApplicationContext("applicationContext.xml");System.out.println("==========初始化成功!==========");User u=(User) factory.getBean("personService");u.sayHi();System.out.println("==========开始关闭容器!==========");((ClassPathXmlApplicationContext)factory).registerShutdownHook();}}

然后华丽丽的结果出来了,如下:

==========开始初始化容器!==========
[INFO ] [22:22:15] org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@7b7381ef: startup date [Fri Feb 27 22:22:15 CST 2015]; root of context hierarchy
[INFO ] [22:22:15] org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [applicationContext.xml]
[INFO ] [22:22:17] org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@229a8e52: defining beans [personService,myBeanPostProcessor]; root of factory hierarchy
构造函数:User
属性name set方法:setName(String name) 被调用
属性age set方法:setName(Integer age) 被调用
BeanNameAware接口:setBeanName 被调用 值personService
BeanFactoryAware接口:setBeanFactory 被调用org.springframework.beans.factory.support.DefaultListableBeanFactory@229a8e52: defining beans [personService,myBeanPostProcessor]; root of factory hierarchy
ApplicationContextAware接口:setApplicationContext org.springframework.context.support.ClassPathXmlApplicationContext@7b7381ef: startup date [Fri Feb 27 22:22:15 CST 2015]; root of context hierarchy
BeanPostProcessor接口:postProcessBeforeInitialization 函数被调用
InitializingBean接口:InitializingBean.afterPropertiesSet()
自定义myinit方法 被调用
BeanPostProcessor接口:postProcessAfterInitialization 函数被调用   com.sunsharing.beanlife.User@fc85b94被创建的时间是Fri Feb 27 22:22:17 CST 2015
==========初始化成功!==========
hi 小明
==========开始关闭容器!==========
[INFO ] [22:22:17] org.springframework.context.support.ClassPathXmlApplicationContext - Closing org.springframework.context.support.ClassPathXmlApplicationContext@7b7381ef: startup date [Fri Feb 27 22:22:15 CST 2015]; root of context hierarchy
[INFO ] [22:22:17] org.springframework.beans.factory.support.DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@229a8e52: defining beans [personService,myBeanPostProcessor]; root of factory hierarchy
DiposibleBean接口:调用DiposibleBean.destory()
自定义mydestory 释放各种资源
Process finished with exit code 0

这样打印的结果清晰明了,相信对理解spring bean生命周期的理解会更加深刻。

转载于:https://my.oschina.net/nyp/blog/380007

Spring学习总结1——bean的生命周期相关推荐

  1. Spring全家桶(四)Bean的生命周期

    十.Bean生命周期 10.1 Bean的生命周期 Spring IOC容器可以管理Bean的生命周期,也允许在Bean生命周期的特定点执行定制的任务. Spring IOC容器对Bean的生命周期进 ...

  2. Spring容器启动流程+Bean的生命周期【附源码】

    如果对SpringIoc与Aop的源码感兴趣,可以访问参考:https://javadoop.com/,十分详细. 文章目录 Spring容器的启动全流程 Spring容器关闭流程 Bean 的生命周 ...

  3. Spring源码分析——Bean的生命周期

    文章目录 说明 测试代码 说明 本文从源码的角度分析Spring中Bean的加载过程,本文使用的Spring版本为4.3.25.RELEASE 测试代码 测试代码如下,根据这段简单的测试代码,一步步跟 ...

  4. Spring高级应用之bean的生命周期

    简介: 在spring世界中,一切皆为bean,spring是面向bean编程的,bean也可以称为组件,是一个个java对象,多个组件间协调工作完成复杂的业务功能. 所以理解bean的生命周期,方便 ...

  5. spring入门第二讲 bean的生命周期 装配方式 Spring整合Junit

    bean的生命周期 实体类 //初始化 public void init(){System.out.println("--初始化--"); }//销毁 public void de ...

  6. Spring源码深度解析,Spring源码以及Bean的生命周期(五)(附代码示例:)

    五)Bean 的生命周期,创建---初始化---销毁的过程 目录 五)Bean 的生命周期,创建---初始化---销毁的过程 一 ,  指定初始化方法 init-method 方法​ 二 ,指定销毁 ...

  7. Spring:IOC容器Bean的生命周期的int和destro方法详解(4)

    Bean的生命周期 1)实例化Bean 对于BeanFactory容器,当客户向容器请求一个未初始化的bean时,或初始化bean的时候需要注入另一个未初始化的依赖时,容器就会调用createBean ...

  8. Spring学习笔记09 - 对象的生命周期

    对象的生命周期 什么是对象的生命周期 一个对象的创建.存活.消亡的一个完整过程. 为什么要学习对象的生命周期? (由程序员控制的 创建对象 就使用new,User user = new User() ...

  9. Spring《二》 Bean的生命周期

    Bean初始化 1.bean中实现public void init():方法,config.xml中增加init-method="init" 属性. 2.bean实现接口Initi ...

最新文章

  1. OpenVINO2021.4+YOLOX目标检测模型部署测试
  2. java求二次函数的a,b,c值
  3. 10件5G能实现但4G不能做的事情
  4. 物联网时代更要注意信息安全
  5. Linux 安装composer
  6. 据说这是程序员为什么改行送外卖的原因
  7. java 8流自定义收集器_Java 8编写自定义收集器简介
  8. python-OpenCV之numpy数组操作
  9. http://circles.arenaofthemes.com/
  10. 技术文档(3)--查看和修改Linux服务器的时区和时间
  11. 请求验证过程检测到有潜在危险的客户端输入值,对请求的处理已经中止。
  12. linux怎么更改兼容模式,SketchUp兼容性更改
  13. linux mysql 视频教程_Linux视频教程基础入门到精通Shell高级编程实战/Nginx/MySQL运维视频教程下载...
  14. android robotium教程,Robotium + Android studio
  15. ORacle异常:ORA-00980:同义词转换不再有效
  16. 深度信念网络_静园5号院前沿讲座 | Geoffery Hinton谈深度信念网络
  17. 【某deed和某app面试】
  18. 父窗口操控iframe
  19. 万豪国际集团贵州首家万枫酒店在贵阳会展中心开业
  20. 【web素材】16—激发你开发灵感的十大创意网站菜单示例效果

热门文章

  1. vue开发使用vue-particles如何兼容IE11?
  2. thinkphp上传图片自动压缩问题
  3. Tomcat unable to start within 45 seconds.
  4. Java8 stream操作
  5. Java并发编程:Thread类的使用
  6. 数据结构与算法分析——C语言描述
  7. Linux程序包管理之RPM
  8. 黑马程序员_Java解析网络数据流的三种特殊方法
  9. CKEditor+CKFinder配置学习
  10. Attribute在拦截机制上的应用