五、bean的生命周期
一、如果是ApplicationContext加载xml,则加载的时候就bean的生命周期就开始了,如果是BeanFactory加载xml,则getbean的时候bean的生命周期才开始。
Bean的生命周期大致如下(前提是bean的scope=”singleton”,如果scope不为这个,则没这么复杂):
- 实例化
- 设置属性
- 调用setBeanName方法(如果bean实现了BeanNameAware接口)
- 调用setBeanFactory方法(如果bean实现了BeanFactoryAware接口)
- 调用setApplicationContext方法(如果bean实现了ApplicationContextAware接口)
- 调用postProcessBeforeInitialization方法(如果项目配置了后置处理器)
- 调用afterPropertiesSet方法(如果bean实现了InitializingBean接口)
- 调用定制的初始化方法(如果定制了初始化方法)
- 调用postProcessAfterInitialization方法(如果项目配置了后置处理器)
- Bean可以使用了
- 容器关闭
- 调用destory方法(如果bean实现了DisposableBean接口)
- 调用定制的销毁方法(如果定制了销毁方法)
二、
- 实例化
容器寻找bean的定义信息并实例化,调用构造函数(默认调用无参构造函数,如果没有无参构造函数且没给bean配置factory-method会报错)
- 设置属性
调用属性的set方法注入属性
3.设置属性
如果你的bean实现了BeanNameAware接口,则bean在执行完前面的内容的时候就会执行setBeanName()函数,你可以在这个函数里操作bean的id,如输出id。
@Override public void setBeanName(String arg0) { // TODO Auto-generated method stub System.out.println("person类正在被配备id-->"+arg0); }
4.调用setBeanFactory方法(如果bean实现了BeanFactoryAware接口)
@Override public void setBeanFactory(BeanFactory arg0) throws BeansException { // TODO Auto-generated method stub System.out.println("正在给Person类配备BeanFactory "+arg0); }
5.setApplicationContext方法(如果bean实现了ApplicationContextAware接口)
@Override public void setApplicationContext(ApplicationContext arg0) throws BeansException { // TODO Auto-generated method stub System.out.println(arg0); }
6.调用postProcessBeforeInitialization方法(如果项目配置了后置处理器)
项目中有一个类实现了BeanPostProcessor接口,并在xml中配置了的bean称为后置处理器,类似于过滤器filter。
package com.myz.bean; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessAfterInitialization(Object arg0, String arg1) throws BeansException { // TODO Auto-generated method stub System.out.println("postProcessAfterInitialization正在执行"); return arg0; } @Override public Object postProcessBeforeInitialization(Object arg0, String arg1) throws BeansException { // TODO Auto-generated method stub System.out.println("postProcessBeforeInitialization正在执行"); return arg0; } }
<bean id="myBeanPostProcessor" class="com.myz.bean.MyBeanPostProcessor">
7.调用afterPropertiesSet方法(如果bean实现了InitializingBean接口)
如果bean实现了InitializingBean接口,则可以在函数afterPropertiesSet中进行设置完属性的操作
@Override public void afterPropertiesSet() throws Exception { // TODO Auto-generated method stub System.out.println("已经设置完所有属性"); }
8.调用定制的初始化方法(如果定制了初始化方法)
public void init(){ System.out.println("执行我自己的init方法"); }
<bean id="person" init-method="init" class="com.myz.bean.Person"> <property name="name" value="小明"/> </bean>
9.执行后置处理器的后过程函数(如果有后置处理器)
@Override public Object postProcessAfterInitialization(Object arg0, String arg1) throws BeansException { // TODO Auto-generated method stub System.out.println("postProcessAfterInitialization正在执行"); return arg0; }
10.Bean可以使用了
11.使用完成后关闭容器
12.调用destory方法(如果bean实现了DisposableBean接口)
在容器关闭后,调用destroy方法(如果bean实现了DisposableBean接口),但是由于容器关闭的时候(一般指项目关闭了),我们一般看不到函数里面的内容执行了。
@Override public void destroy() throws Exception { // TODO Auto-generated method stub }
13.调用定制的销毁方法(如果定制了销毁方法)
@Override public void destroy() throws Exception { // TODO Auto-generated method stub }
<bean id="person" destroy-method="myDestroy" class="com.myz.bean.Person">
三、在一般的项目中,bean没有那么复杂的生命周期,一般为1->2->6->9->10->11
而且定制初始化方法和定制销毁方法可以采用注解的方式,具体操作为:
①添加注解
@PostConstruct public void init(){ System.out.println("执行我自己的init方法"); }
@PreDestroy public void myDestroy(){ }
②启用注解,告诉spring 容器采用注解配置:扫描注解配置
<?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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation= "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd ">
<!--或者使用 <context:annotation-config /> 扫描--> <context:component-scan base-package="com.myapp.core.jsr330"/> <bean id="person" class="com.myz.bean.Person"> <property name="name" value="小明"/> </bean> </beans>