普通的Java对象而言,生命周期相对简单,new的时候创建对象,当没有任何引用的时候被垃圾回收机制回收。
而由Spring Ioc容器托管的对象,它们的生命周期完全由容器完全控制。如图:
实例化Bean
实例化Bean时要看是BeanFactory容器还是ApplicationContext容器。
1.BeanFactory容器:当向容器请求一个未初始的bean时,或初始化bean的时候需要注入到另一个尚未初始化的依赖时的容器就会调用creatBean来进行初始化
2.ApplicationContext容器,当容器启动结束后,便实例化所有的bean。
3.容器通过获取BeanDefinition对象中的信息进行实例化。并且这一步仅仅是简单的实例化,并未进行依赖注入
4.实例化对象被包装在BeanWrapper对象中,BeanWrapper提供了设置对象属性的接口,从而避免了使用反射机制设置属性
设置对象属性(依赖注入)
实例化的对象被封装在BeanWrapper对象中,并且此时对象仍然是一个原生的状态,并没有进行依赖注入
随后Spring根据BeanDefinition中的信息进行依赖注入,并且通过BeanWrapper提供的设置属性的接口完成依赖注入
注入Aware接口
随后Spring会检测该对象是否实现了xxxAware接口,并且将相关的实例注入给bean。
此时bean对象已经被正确构造。
BeanNameAware
如果bean实现此接口,spring将bean的id传给setBeanName()方法
BeanFactoryAware
如果bean实现此接口,Spring将调用setBeanFactory方法,将BeanFactory实例传过来
ApplicationContextAware
如果实现此接口,它的setApplicationContext()方法将被调用,将应用上下文的引用传入到bean中;
BeanPostProcessor
该接口提供了两个函数用来对对象在被使用前做一些自定义的处理,此时Bean会被传递进来,可以对bean做任何处理。
前置处理:在Bean实例创建
1.postProcessBeforeInitialzation( Object bean, String beanName )
2.会先于InitialzationBean执行,所有的Aware接口的注入就是在此完成的
后置处理:
1.postProcessAfterInitialzation( Object bean, String beanName)
InitializingBean与init-method
当前置处理完成后就会进入本阶段。
afterPropertiesSet()
这一阶段也可以在bean正式构造完成前增加我们自定义的逻辑,在这一步没办法处理对象本身,只能增加一些额外的逻辑。
若要使用它,我们需要让bean实现该接口,并把要增加的逻辑写在该函数中。然后Spring会在前置处理完成后检测当前bean是否实现了该接口,并执行afterPropertiesSet函数。
当然,Spring为了降低对客户代码的侵入性,给bean的配置提供了init-method属性,该属性指定了在这一阶段需要执行的函数名。Spring便会在初始化阶段执行我们设置的函数。init-method本质上仍然使用了InitializingBean接口。
DisposableBean和destroy-method
和init-method一样,通过给destroy-method指定函数,就可以在bean销毁前执行指定的逻辑。
实战案例
package lifecycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class PersonBean implements BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean, ApplicationContextAware {
private String name;
public PersonBean() {
System.out.println("========================调用PersonBean的构造器实例化==========================");
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("【属性赋值】 name="+name);
this.name = name;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("【接口ApplicationContextAware中的setApplicationContext()方法】");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("【接口BeanFactoryAware中的setBeanFactory()方法】");
}
@Override
public void setBeanName(String name) {
System.out.println("【接口BeanNameAware中的setBeanName()方法】");
}
@Override
public void destroy() throws Exception {
System.out.println("【接口DisposableBean中的destroy()方法】");
}
public void customDestroy() throws Exception {
System.out.println("【自定义destroy-method】");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("【接口InitializingBean中的afterPropertiesSet()方法】初始化阶段");
}
public void init() {
System.out.println("【自定义init-method】");
}
}
package lifecycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if(bean instanceof PersonBean){
System.out.println("MyBeanPostProcessor.postProcessBeforeInitialization");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(bean instanceof PersonBean){
System.out.println("MyBeanPostProcessor.postProcessAfterInitialization");
}
return bean;
}
}
package lifecycle;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class LifeCycleTest {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-lifecycle.xml");
PersonBean personBean = (PersonBean) applicationContext.getBean("personBean");
((ClassPathXmlApplicationContext) applicationContext).destroy();
}
}
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"
default-autowire="byName">
<bean id="personBean" class="lifecycle.PersonBean" init-method="init" destroy-method="customDestroy">
<property name="name" value="hao are you" />
</bean>
<bean id="myBeanPostProcessor" class="lifecycle.MyBeanPostProcessor" />
</beans>
实例化->属性赋值->各种Aware接口的依赖(ApplicationContextAware/BeanNameAware/BeanFactoryAware)->执行BeanPostProcessor前置处理器(postProcessBeforeInitialization)->实现InitializingBean(执行AfterPropertiesSet初始化)/自定义init-method->BeanPostProcessor后置处理器(postProcessAfterInitialization)->实现DisposableBean/自定义destroy-method