博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring学习总结1——bean的生命周期
阅读量:6866 次
发布时间:2019-06-26

本文共 9115 字,大约阅读时间需要 30 分钟。

  hot3.png

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

ioc是什么?

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

DI是什么?

: di(dependency injection) 依赖注入实际上diioc是同一个概念,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”属性设定方法名称,如下:

  ....... 

      这时会执行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”定义的方法

  .......

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

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

095019_s64b_1470450.png

如果使用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 id    public void setBeanName(String arg0) {        // TODO Auto-generated method stub        System.out.println("BeanNameAware接口:setBeanName 被调用 值"+arg0);    }    //该方法可以传递beanFactroy    public void setBeanFactory(BeanFactory arg0) throws BeansException {        // TODO Auto-generated method stub        System.out.println("BeanFactoryAware接口:setBeanFactory 被调用"+arg0);    }    //该方法传递ApplicationContext    public void setApplicationContext(ApplicationContext arg0)            throws BeansException {        // TODO Auto-generated method stub        System.out.println("ApplicationContextAware接口:setApplicationContext "+arg0);    }    //这是InitializingBean接口方法    public void afterPropertiesSet() throws Exception {        // TODO Auto-generated method stub        System.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 stub        System.out.println("BeanPostProcessor接口:postProcessAfterInitialization 函数被调用   "+arg0+"被创建的时间是"+new java.util.Date());        return arg0;    }    public Object postProcessBeforeInitialization(Object arg0, String arg1)            throws BeansException {        // TODO Auto-generated method stub        System.out.println("BeanPostProcessor接口:postProcessBeforeInitialization 函数被调用");        return arg0;    }}

接着ApplicatationContext.xml的配置

   
      
      
         
小明
            
         
2015
            
   

最后用一个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 stub        System.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 被调用 值personServiceBeanFactoryAware接口:setBeanFactory 被调用org.springframework.beans.factory.support.DefaultListableBeanFactory@229a8e52: defining beans [personService,myBeanPostProcessor]; root of factory hierarchyApplicationContextAware接口:setApplicationContext org.springframework.context.support.ClassPathXmlApplicationContext@7b7381ef: startup date [Fri Feb 27 22:22:15 CST 2015]; root of context hierarchyBeanPostProcessor接口: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 hierarchyDiposibleBean接口:调用DiposibleBean.destory()自定义mydestory 释放各种资源Process finished with exit code 0

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

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

你可能感兴趣的文章
javac java 命令行编译运行程序
查看>>
几个重要的Linux系统内核文件介绍
查看>>
jquery ajax “Uncaught TypeError: Illegal invocation”
查看>>
Android 农历和节气相关工具类(记录)
查看>>
php字符串处理函数大全
查看>>
redis应用场景
查看>>
页面加载自动定位到显示位置
查看>>
JTree实现文件树
查看>>
FMDB详解
查看>>
F12浏览器调试模式页面刷新network日志刷新消失的解决办法
查看>>
DiskGroup resource are not running on nodes. Database instance may not come up on these nodes
查看>>
nginx+keepalived实现集群配置
查看>>
maven常用命令整理
查看>>
2.6 yum如何下载rpm包到本地
查看>>
PHP超全局变量(5):$_REQUEST[]
查看>>
Idea代码模板初探
查看>>
Win7系统管理员密码重置
查看>>
神奇的MySQL分区-测试案例
查看>>
Download android problem
查看>>
垃圾回收
查看>>