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事件:取得一个ServletContext(application)对象
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>
今天先讲到这里,有什么不足的地方请大家帮忙指点!!!