Spring生命周期相关

              Spring 生命周期文档

作为菜鸟的我,刚刚走上编程的道路,不能说没经验,O(∩_∩)O哈哈~自己没事就会总结一些文章,希望大家积极来吐槽我这个小菜鸟!!! 



一、   Spring bean的生命周期

 

Spring Bean的完整生命周期从创建Spring容器开始,直到最终Spring容器销毁Bean,这其中包含了一系列关键点。下面就是基本流程图:

 


 

 

二、各种接口方法分类

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

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

2、Bean级生命周期接口方法:这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法

3、容器级生命周期接口方法:这个包括了InstantiationAwareBeanPostProcessor和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。

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

 

 

小总结;

spring容器的生命周期: 
(a)
在单例情况下: 
1、由spring容器创建对象 
2、spring容器调用初始化方法 
3、客户点调用该对象的某些方法 
4、关闭spring容器的时候,执行摧毁方法

(b)在多例的情况下: 
1
、由spring容器创建对象 
2、spring容器调用初始化方法 
3、客户点调用该对象的某些方法

 

 

 

 

三、其他资料总结;

实例化Bean的过程中有以下几个节点:

1)设置属性值;

2)调用Bean中的BeanNameAware.setBeanName()方法,如果该Bean实现了BeanNameAware接口;

3)调用Bean中的BeanFactoryAware.setBeanFactory()方法,如果该Bean实现了BeanFactoryAware接口;

4)调用BeanPostProcessors.postProcessBeforeInitialization()方法;

5)调用Bean中的afterPropertiesSet方法,如果该Bean实现了InitializingBean接口;

6)调用Bean中的init-method,通常是在配置bean的时候指定了init-method,例如:<beanclass="beanClass"init-method="init"></bean>

7)调用BeanPostProcessors.postProcessAfterInitialization()方法;

8)如果该Bean是单例的,则当容器销毁并且该Bean实现了DisposableBean接口的时候,调用destory方法;如果该Bean是prototype,则将准备好的Bean提交给调用者,后续不再管理该Bean的生命周期。

 

好了,简单了描述了下那幅图。一切都还太抽象了,作为程序员,代码还是最直接的表达方式。那我们就一起看段演示代码吧。

 

首先,为达到演示效果,我们准备两个待测试的Bean,代码如下:

@Component 

publicclass DemoBean implementsBeanFactoryAware, BeanNameAware, 

        InitializingBean, DisposableBean { 

    @PostConstruct 

    publicvoid init() { 

       System.out.println("DemoBean:init-method"); 

    } 

    publicvoid destroy() throwsException { 

       System.out.println("DemoBean:destroy-method!"); 

    } 

    publicvoid afterPropertiesSet() throws Exception { 

       System.out.println("DemoBean: afterproperties set!"); 

    } 

    publicvoid setBeanName(String name) { 

       System.out.println("DemoBean:beanName aware, [name=" + name + "]"); 

    } 

    publicvoid setBeanFactory(BeanFactory beanFactory) throws BeansException { 

       System.out.println("DemoBean:beanFactory aware, [beanFactory=" + beanFactory.toString() +"]"); 

    } 

 

publicclass AnotherDemoBean implementsInitializingBean { 

  

    @PostConstruct 

    publicvoid postConstruct() { 

      System.out.println("AnotherDemoBean:postConstruct-method"); 

    }   

    publicvoid init() { 

      System.out.println("AnotherDemoBean: init-method"); 

    } 

    @Override 

    publicvoid afterPropertiesSet() throws Exception { 

      System.out.println("AnotherDemoBean: after propertiesset!"); 

    } 

}

 

上面两个Bean大致相同,区别在于第一个Bean使用注解方式注入,第二个Bean我们使用配置文件方式,并指定其init-method,用于观察init-method与postConstruct的执行先后。

 

我们这个演示Bean实现了BeanFactoryAware, BeanNameAware,InitializingBean,  DisposableBean这几个接口,其实这些接口也可理解为Spring容器的一个个扩展点。

 

然后,我们再编写一个BeanPostProcessor,用于演示生命周期中的步骤4和步骤7。 代码如下:

@Component 

publicclass DemoBeanPostProcessor implements BeanPostProcessor { 

    public ObjectpostProcessBeforeInitialization(Object bean, String beanName)throws BeansException { 

      System.out.println("DemoBeanPostProcessor: post process beforeinitialization, [beanName=" + beanName + ", bean=" + bean +"]"); 

       returnbean; 

    } 

    public Object postProcessAfterInitialization(Objectbean, String beanName)throws BeansException { 

      System.out.println("DemoBeanPostProcessor: post process beforeinitialization, [beanName=" + beanName + ", bean=" + bean +"]"); 

       returnbean; 

    } 

 

最后,我们编写测试类,以及Spring的配置文件,这里我们使用ClassPathXMLApplicationContext加载配置文件和初始化Spring容器。一起看下配置文件和测试类代码:

applicationContext.xml:

<?xmlversion="1.0" encoding="GBK"?> 

  

<beans xmlns="http://www.springframework.org/schema/beans" 

   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop" 

   xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx" 

    xsi:schemaLocation=" 

        http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsd 

        http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.5.xsd 

        http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-2.5.xsd 

        http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> 

    <context:component-scan base-package="com.shansun.multidemo"></context:component-scan> 

    <bean class="com.shansun.multidemo.spring.lifecycle.AnotherDemoBean"init-method="init"></bean> 

</beans> 

Main.java  

publicclass Main { 

    @SuppressWarnings("unused") 

    publicstatic void main(String[] args) { 

        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); 

    } 

   

好了,一切就绪,我们就静观程序输出吧:

DemoBean: beanNameaware, [name=demoBean] 

DemoBean:beanFactory aware,[beanFactory=org.springframework.beans.factory.support.DefaultListableBeanFactory@888e6c:definingbeans[demoBean,demoBeanFactoryPostProcessor,demoBeanPostProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,com.shansun.multidemo.spring.lifecycle.AnotherDemoBean#0];root of factory hierarchy] 

DemoBean:init-method 

DemoBeanPostProcessor:post process before initialization, [beanName=demoBean,bean=com.shansun.multidemo.spring.lifecycle.DemoBean@1deeb40] 

DemoBean: afterproperties set! 

DemoBeanPostProcessor:post process before initialization, [beanName=demoBean,bean=com.shansun.multidemo.spring.lifecycle.DemoBean@1deeb40] 

AnotherDemoBean:postConstruct-method 

DemoBeanPostProcessor:post process before initialization, [beanName=com.shansun.multidemo.spring.lifecycle.AnotherDemoBean#0,bean=com.shansun.multidemo.spring.lifecycle.AnotherDemoBean@1a7ddcf] 

AnotherDemoBean:after properties set! 

AnotherDemoBean:init-method 

DemoBeanPostProcessor:post process before initialization,[beanName=com.shansun.multidemo.spring.lifecycle.AnotherDemoBean#0,bean=com.shansun.multidemo.spring.lifecycle.AnotherDemoBean@1a7ddcf]

 

 

4.相关概念:

 

相关链接; http://blog.csdn.net/liuhang03/article/details/50147117

 

 

 

 

 

 

                  
 
                                                                                      监听器Listener




1、Listener的定义与作用

  监听器Listener就是在application,session,request三个对象创建、销毁或者往其中添加修改删除属性时自动执行代码的功能组件。

  Listener是Servlet的监听器,可以监听客户端的请求,服务端的操作等。

2、Listener的分类与使用

  主要有以下三类:

  1、ServletContext监听

  ServletContextListener:用于对Servlet整个上下文进行监听(创建、销毁)。

public void contextInitialized(ServletContextEvent sce);//上下文初始化
public void contextDestroyed(ServletContextEvent sce);//上下文销毁
publicServletContext getServletContext();//ServletContextEvent事件:取得一个ServletContextapplication)对象
 
ServletContextAttributeListener:对Servlet上下文属性的监听(增删改属性)。
 
public void attributeAdded(ServletContextAttributeEventscab);//增加属性
public void attributeRemoved(ServletContextAttributeEventscab);//属性删除
public void attributeRepalced(ServletContextAttributeEventscab);//属性替换(第二次设置同一属性)
 
//ServletContextAttributeEvent事件:能取得设置属性的名称与内容
public String getName();//得到属性名称
public Object getValue();//取得属性的值
 
2、Session监听
Session属于http协议下的内容,接口位于javax.servlet.http.*包下。
HttpSessionListener接口:对Session的整体状态的监听。
示例代码1:
public voidsessionCreated(HttpSessionEvent se);//session创建
public voidsessionDestroyed(HttpSessionEvent se);//session销毁
//HttpSessionEvent事件:
publicHttpSession getSession();//取得当前操作的session
示例代码2:
HttpSessionAttributeListener接口:对session的属性监听。

public voidattributeAdded(HttpSessionBindingEvent se);//增加属性

public voidattributeRemoved(HttpSessionBindingEvent se);//删除属性

public void attributeReplaced(HttpSessionBindingEventse);//替换属性

 

//HttpSessionBindingEvent事件:

public String getName();//取得属性的名称

public Object getValue();//取得属性的值

public HttpSessiongetSession();//取得当前的session

  

 

session的销毁有两种情况:

 

1>  session超时,web.xml配置:

示例代码3:

<session-config>

<session-timeout>

120

</session-timeout>

<!--session120分钟后超时销毁-->

</session-config>

 

 

 

2>  手工使session失效

示例代码4:

public void invalidate();//使session失效方法。session.invalidate();

  

3、Request监听

 

-   ServletRequestListener:用于对Request请求进行监听(创建、销毁)。

示例代码1:

public void requestInitialized(ServletRequestEventsre);//request初始化

public voidrequestDestroyed(ServletRequestEvent sre);//request销毁

 

//ServletRequestEvent事件:

public ServletRequestgetServletRequest();//取得一个ServletRequest对象

public ServletContextgetServletContext();//取得一个ServletContext(application)对象

 

-   ServletRequestAttributeListener:对Request属性的监听(增删改属性)。

示例代码2:

public voidattributeAdded(ServletRequestAttributeEvent srae);//增加属性

public voidattributeRemoved(ServletRequestAttributeEvent srae);//属性删除

public void attributeReplaced(ServletRequestAttributeEventsrae);//属性替换(第二次设置同一属性)

 

//ServletRequestAttributeEvent事件:能取得设置属性的名称与内容

public String getName();//得到属性名称

public Object getValue();//取得属性的值

  

 

4、在web.xml中配置

 

  Listener配置信息必须在Filter和Servlet配置之前,Listener的初始化(ServletContentListener初始化)比Servlet和Filter都优先,而销毁比Servlet和Filter都慢。

 

示例代码1:

<listener>

   <listener-class>com.listener.class</listener-class>

</listener>

 

今天先讲到这里,有什么不足的地方请大家帮忙指点!!!




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值