欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring中Bean的生命周期

程序员文章站 2022-05-24 17:52:02
...

生命周期简单版(忽略一些后处理器的方法调用)

  1. 实例化一个 Bean ——也就是我们常说的 new 一个对象;

  2. 按照Spring上下文对实例化的Bean进行配置——也就是IOC注入;设置属性值。

  3. 如果这个Bean已经实现了 BeanNameAware 接口,会调用它实现的 setBeanName(String name) 方法,此处传递的就是Spring配置文件中Bean的id值

  4. 如果这个Bean已经实现了 BeanFactoryAware 接口,会调用它实现的setBeanFactory(BeanFactory beanFactory) 传递的是Spring工厂自身(可以用这个方式来获取其它Bean,只需在Spring配置文件中配置一个普通的Bean就可以);

  5. 如果这个Bean已经实现了 ApplicationContextAware 接口,会调用setApplicationContext(ApplicationContext applicationContext) 方法,传入Spring上下文(同样这个方式也可以实现步骤4的内容,但比步骤4更好,因为 ApplicationContext 是 BeanFactory 的子接口,有更多的实现方法;

  6. 如果这个Bean关联了 BeanPostProcessor 接口,将会调用postProcessBeforeInitialization(Object bean, String beanName) 方法,BeanPostProcessor经常被用作是Bean内容的更改,并且由于这个是在Bean初始化结束时调用那个的方法,也可以被应用于内存或缓存技术;

  7. 如果Bean还实现了 InitializingBean 接口,调用 Bean 实现的 afterPropertiesSet() 方法。

  8. 如果Bean在Spring配置文件中配置了 init-method 属性会自动调用其配置的初始化方法。

  9. 如果这个Bean关联了 BeanPostProcessor 接口,将会调用 postProcessAfterInitialization(Object bean, String beanName) 方法;

    注:以上工作完成以后就可以应用这个Bean了,那这个Bean是一个Singleton的,所以一般情况下我们调用同一个id的Bean会是在内容地址相同的实例,当然在Spring配置文件中也可以配置非Singleton,这里我们不做赘述。

  10. 当Bean不再需要时,会经过清理阶段,如果Bean实现了 DisposableBean 这个接口,会调用那个其实现的 destroy() 方法;

  11. 最后,如果这个Bean的Spring配置中配置了 destroy-method 属性,会自动调用其配置的销毁方法。

结合代码理解一下

1、Bean的定义

Spring通常通过配置文件定义Bean。如:

<?xml version=”1.0″ encoding=”UTF-8″?>
 
<beans xmlns=”http://www.springframework.org/schema/beans”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd”>
 
<bean id=”HelloWorld” class=”com.pqf.beans.HelloWorld”>
    <property name=”msg”>
       <value>HelloWorld</value>
    </property>
</bean>
 
</beans>

这个配置文件就定义了一个标识为 HelloWorld 的Bean。在一个配置文档中可以定义多个Bean。

2、Bean的初始化

有两种方式初始化Bean。

1. 在配置文档中通过指定init-method 属性来完成

在Bean的类中实现一个初始化Bean属性的方法,如init(),如:

public class HelloWorld{
   public String msg=null;
   public Date date=null;
 
    public void init() {
      msg=”HelloWorld”;
      date=new Date();
    }
    ...
}

然后,在配置文件中设置init-mothod属性。

2. 实现 org.springframwork.beans.factory.InitializingBean接口

Bean实现InitializingBean接口,并且增加 afterPropertiesSet() 方法:

public class HelloWorld implement InitializingBean {
   public String msg=null;
   public Date date=null;
   
   @Override
   public void afterPropertiesSet() {
       msg="向全世界问好!";
       date=new Date();
   }
    ...
}

那么,当这个Bean的所有属性被Spring的BeanFactory设置完后,会自动调用afterPropertiesSet()方法对Bean进行初始化,于是,配置文件就不用指定 init-method属性了。

3、Bean的调用

有三种方式可以得到Bean并进行调用:

1. 使用BeanWrapper

HelloWorld hw = new HelloWorld();
BeanWrapper bw = new BeanWrapperImpl(hw);
bw.setPropertyvalue(”msg”,”HelloWorld”);
system.out.println(bw.getPropertyCalue(”msg”));

2. 使用BeanFactory

InputStream is = new FileInputStream(”config.xml”);
XmlBeanFactory factory = new XmlBeanFactory(is);
HelloWorld hw = (HelloWorld) factory.getBean(”HelloWorld”);
system.out.println(hw.getMsg());

3. 使用ApplicationConttext

ApplicationContext actx = new FleSystemXmlApplicationContext(”config.xml”);
HelloWorld hw = (HelloWorld) actx.getBean(”HelloWorld”);
System.out.println(hw.getMsg());

4、Bean的销毁

1. 使用配置文件中的 destory-method 属性

与初始化属性 init-methods类似,在Bean的类中实现一个撤销Bean的方法,然后在配置文件中通过 destory-method指定,那么当bean销毁时,Spring将自动调用指定的销毁方法。

2.实现 org.springframwork.bean.factory.DisposebleBean接口

如果实现了DisposebleBean接口,那么Spring将自动调用bean中的Destory方法进行销毁,所以,Bean中必须提供Destory方法。

更详细的流程

1. 实例化 BeanFactoryPostProcessor 的实现类
2. 执行 BeanFactoryPostProcessor 实现类的 postProcessBeanFactory 方法
3. 实例化 BeanPostProcessor 实现类
4. 实例化 InstantiationAwareBeanPostProcessorAdapter 实现类
5. 调用 InstantiationAwareBeanPostProcessorAdapter 实现类 的 postProcessBeforeInstantiation 方法
6. 执行 Bean 的 构造器
7. 调用 InstantiationAwareBeanPostProcessorAdapter 实现类 的 postProcessPropertyValues 方法
8. 为 Bean 注入属性
9. 若 Bean 实现了 BeanNameAware 接口调用实现接口的 setBeanName 方法
10. 若 Bean 实现了 BeanFactoryAware 接口调用实现接口的 setBeanFactory 方法
11. 若Bean实现了 ApplicationContextAware 接口 调用 setApplicationContext 方法
12. 执行 BeanPostProcessor 实现类的 postProcessBeforeInitialization 方法
13. 若 Bean 实现了 InitializingBean 接口 调用 afterPropertiesSet 方法
14. 调用配置文件配置的 init-method 方法
15. 执行 BeanPostProcessor 实现类的 postProcessAfterInitialization 方法
16. 执行 InstantiationAwareBeanPostProcessorAdapter实现类的postProcessAfterInstantiation方法
17. 容器初始化成功,执行正常调用后,下面销毁容器
18. 调用Bean实现 DisposableBean 接口的 destroy 方法
19. 调用配置文件配置的destroy-method配置的方法

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

  1. Bean自身的方法:
    这个包括了Bean本身调用的方法和通过配置文件中的 init-methoddestroy-method 指定的方法。

  2. Bean级生命周期接口方法:
    这个包括了 BeanNameAwareBeanFactoryAwareApplicationContextAwareInitializingBeanDiposableBean 这些接口的方法。

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

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