博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringBean的生命周期
阅读量:3956 次
发布时间:2019-05-24

本文共 8639 字,大约阅读时间需要 28 分钟。

你未必出类拔萃,但一定与众不同

SpringBean的生命周期

文章目录

Spring IoC的本质就是为了管理Bean

在这里插入图片描述

生命周期

  • Bean 容器找到配置⽂件中 Spring Bean 的定义。

  • Bean 容器利⽤反射创建⼀个Bean的实例。

  • 如果涉及到⼀些属性值 利⽤ set() ⽅法设置⼀些属性值。

  • 如果Bean 实现了接口BeanNameAware的setBeanName方法,那么就会调用这个方法。

  • 如果Bean实现了接口BeanFactoryAware的setBeanFactory方法,那么就会调用这个方法。

  • 如果Bean实现了接口AppicationContextAware的setAppicationContext方法,且这个Spring IoC容器必须是一个AppicationContext接口的实现类,那么就会调用这个方法,否则不调用

  • 如果Bean 实现了接口BeanPostProcessor的postProcessBeforeInitialization方法那么就会调用这个方法。

  • 如果Bean实现了接口BeanFactoryPostProcessor的afterPropertiesSet方法,那么就会调用这个方法

  • 如果Bean自定义了初始化方法,它就会调用已定义的初始化方法

  • 如果Bean实现了接口BeanPostProcessor的postProcessAfterInitialization方法,完成了这些调用,这个时候Bean就完成了初始化,那么Bean就生存在了Spring IoC的容器中。

    当服务器正常关闭或者其他关闭Spring IoC容器的事件,就会完成对Bean的销毁

  • 如果Bean实现了接口DisPosableBean的destory方法,那么就会调用它。

  • 如果定义了自定义的销毁方法,那么就会调用它。

现在我们来看看一个简易的bean的实现 了解一个大概实例化初始化流程

先写一个实体类

去实现BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean这些接口

public class Student implements BeanFactoryAware, BeanNameAware,        InitializingBean, DisposableBean {    private String studentName;    private String studentAddress;    private String studentPhone;    private BeanFactory beanFactory;    private String beanName;    public String getStudentName() {        return studentName;    }    public void setStudentName(String studentName) {        System.out.println("---注入属性 studentName-----");        this.studentName = studentName;    }    public String getStudentAddress() {        return studentAddress;    }    public void setStudentAddress(String studentAddress) {        System.out.println("---注入属性 StudentAddress-----");        this.studentAddress = studentAddress;    }    public String getStudentPhone() {        return studentPhone;    }    public void setStudentPhone(String studentPhone) {        System.out.println("---注入属性 studentPhone-----");        this.studentPhone = studentPhone;    }    // 这是BeanFactoryAware接口方法    @Override    public void setBeanFactory(BeanFactory arg0) throws BeansException {        System.out.println("----BeanFactoryAware接口----调用BeanFactoryAware.setBeanFactory()");        this.beanFactory = arg0;    }    // 这是BeanNameAware接口方法    @Override    public void setBeanName(String arg0) {        System.out.println("----BeanNameAware接口----调用BeanNameAware.setBeanName()");        this.beanName = arg0;    }    // 这是InitializingBean接口方法    @Override    public void afterPropertiesSet() throws Exception {        System.out.println("----InitializingBean接口----调用InitializingBean.afterPropertiesSet()");    }    // 这是DiposibleBean接口方法    @Override    public void destroy() throws Exception {        System.out.println("----DiposibleBean接口----调用DiposibleBean.destory()");    }    // 通过
的init-method属性指定的初始化方法 public void myInit() { System.out.println("---init-method---调用
的init-method属性指定的初始化方法"); } // 通过
的destroy-method属性指定的初始化方法 public void myDestroy() { System.out.println("---destroy-method---调用
的destroy-method属性指定的初始化方法"); }}

编写spring配置文件

如果Bean 实现了接口BeanNameAware的setBeanName方法,那么就会调用这个方法。

如果Bean实现了接口BeanFactoryAware的setBeanFactory方法,那么就会调用这个方法。

这里我们的bean就实现了这个两个接口,因此会调用这个方法,还在实例化之前

BeanPostProcessor 前置处理器

BeanPostProcessor是Spring IOC容器给我们提供的一个扩展接口

public interface BeanPostProcessor {
//bean初始化方法调用前被调用 Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException; //bean初始化方法调用后被调用 Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;}

我们现在自定义一个MyBeanPostProcessor去实现这个接口 监测这个接口方法的初始化顺序

public class MyBeanPostProcessor implements BeanPostProcessor {
public MyBeanPostProcessor() {
super(); System.out.println("BeanPostProcessor构造器"); } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization"); return bean; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization"); return bean; }}

BeanFactoryPostProcessor

BeanFactoryPostProcessor是在spring容器加载了bean的定义文件之后,在bean实例化之前执行的

实现该接口,可以在spring的bean创建之前,修改bean的定义属性。也就是说,Spring允许BeanFactoryPostProcessor在容器实例化任何其它bean之前读取配置元数据,并可以进行修改,例如可以把bean的scope从singleton改为prototype,也可以把property的值给修改掉。可以同时配置多个BeanFactoryPostProcessor,并通过设置’order’属性来控制各个BeanFactoryPostProcessor的执行次序。

@FunctionalInterfacepublic interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;}

ConfigurableListableBeanFactory作为参数可以获取到bean的一些定义信息

我们自定义一个MyBeanFactoryPostProcessor

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public MyBeanFactoryPostProcessor() {
super(); System.out.println("BeanFactoryPostProcessor构造器"); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException {
System.out.println("postProcessBeanFactory"); BeanDefinition bd = var1.getBeanDefinition("student"); bd.getPropertyValues().addPropertyValue("studentPhone", "110"); }}

BeanDefinition

Spring容器启动的过程中,会将Bean解析成Spring内部的BeanDefinition结构

一个 BeanDefinition 描述了一个 Bean 实例,实例包含属性值、构造方法参数值以及更多实现信息。

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {	//单例和原型    String SCOPE_SINGLETON = "singleton";    String SCOPE_PROTOTYPE = "prototype";    //标识 Bean 的类别,分别对应 用户定义的 Bean、来源于配置文件的 Bean、Spring 内部的 Bean    int ROLE_APPLICATION = 0;    int ROLE_SUPPORT = 1;    int ROLE_INFRASTRUCTURE = 2;	//Bean 的父类名称    void setParentName(@Nullable String var1);    ......}

BeanDefinition 描述了一个 Bean 的定义,实际上就是对象在容器中的抽象。通过这个 BeanDefinition 定义的数据结构,容器能够方便地对 Bean 进行管理。对于单例的 Bean,在第一次 getBean 的时候读取 BeanDefinition 获取定义,然后再创建和初始化 Bean,并缓存起来。对于原型的 Bean,在每一次 getBean 的时候都需要使用 BeanDefinition 的数据进行创建和初始化,不会缓存 Bean。

BeanDefinition 在 Spring 内部使用,外部开发者一般感知不到 BeanDefinition 的存在。我们使用时只需要关注通过 xml、注解怎样定义了一个 Bean,然后使用即可。而这中间的解析、创建、初始化都通过 BeanDefinition 来承载。

InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor代表了Spring的另外一段生命周期:实例化。先区别一下Spring Bean的实例化和初始化两个阶段的主要作用:

1、实例化的过程是一个创建Bean的过程,即调用Bean的构造函数,单例的Bean放入单例池中

2、初始化的过程是一个赋值的过程,即调用Bean的setter,设置Bean的属性

Instantiation表示实例化:实例化的意思在对象还未生成

Initialization表示初始化:初始化的意思在对象已经生成

自定义一个MyInstantiationAwareBeanPostProcessor类继承InstantiationAwareBeanPostProcessor重写两个方法

public class MyInstantiationAwareBeanPostProcessor extends        InstantiationAwareBeanPostProcessorAdapter {
public MyInstantiationAwareBeanPostProcessor() {
super(); System.out.println("这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!"); } /** * 接口方法、实例化Bean之前调用 * @param beanClass * @param beanName * @return * @throws BeansException */ @Override public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {
System.out.println("InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法"); return null; } /** * 接口方法、实例化Bean之后调用 * @param bean * @param beanName * @return * @throws BeansException */ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法"); return bean; }}

写个主函数进行测试

public static void main(String[] args) {
System.out.println("初始化容器"); ApplicationContext factory = new ClassPathXmlApplicationContext("spring-config.xml"); System.out.println("容器初始化成功"); Student student = factory.getBean("student",Student.class); System.out.println(student);}

打印结果

初始化容器BeanFactoryPostProcessor构造器postProcessBeanFactoryBeanPostProcessor构造器这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法---注入属性 StudentAddress--------注入属性 studentName--------注入属性 studentPhone---------BeanNameAware接口----调用BeanNameAware.setBeanName()----BeanFactoryAware接口----调用BeanFactoryAware.setBeanFactory()postProcessBeforeInitialization----InitializingBean接口----调用InitializingBean.afterPropertiesSet()---init-method---调用
的init-method属性指定的初始化方法postProcessAfterInitializationInstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法容器初始化成功com.wyyy.run.test.Student@489115ef

转载地址:http://xftzi.baihongyu.com/

你可能感兴趣的文章
Android 下 JNI 开发
查看>>
Android 下 JNI 开发
查看>>
Android 下 JNI 开发
查看>>
Android 下 JNI 开发
查看>>
Mysql索引
查看>>
OGNL投影查询
查看>>
OGNL投影查询
查看>>
OGNL投影查询
查看>>
Redis之RDB和AOF持久化
查看>>
Redis之RDB和AOF持久化
查看>>
Servlet3.0
查看>>
Servlet3.0
查看>>
Servlet3.0
查看>>
SQL 语句的解析过程
查看>>
SQL 语句的解析过程
查看>>
SQL 语句的解析过程
查看>>
Java类文件结构
查看>>
Java类文件结构
查看>>
使用注解生成代码
查看>>
使用注解生成代码
查看>>