美文网首页
Spring bean的生命周期

Spring bean的生命周期

作者: 打不过就加入 | 来源:发表于2018-02-27 19:25 被阅读0次

记一下Spring容器管理的bean的生命周期,各类方法的调用顺序。

shunxu.xml
<?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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd" >
       
        <context:annotation-config></context:annotation-config>
        <bean class="com.cyh.MyBeanPostProcessor"></bean>
        <bean id="shunxu" class="com.cyh.Shunxu" init-method="init" destroy-method="destroy">
            <property name="name" value="kyle"></property>
        </bean>
        
 </beans>




Shunxu.java
package com.cyh;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class Shunxu implements InitializingBean,BeanNameAware,BeanFactoryAware,ApplicationContextAware{

    public String name;
    public void setName(String name) {
        this.name = name;
    }

    public Shunxu() {
        super();
        // TODO Auto-generated constructor stub
        System.out.println("调用构造函数"+"--------------"+this.name);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        // TODO Auto-generated method stub
        System.out.println("调用InitializingBean接口的afterPropertiesSet方法"+"--------------"+this.name);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        // TODO Auto-generated method stub
        System.out.println("调用BeanFactoryAware接口的setBeanFactory方法"+"--------------"+this.name);
    }
    
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        // TODO Auto-generated method stub
        System.out.println("调用ApplicationContextAware接口的setApplicationContext方法"+"--------------"+this.name);
    }

    @Override
    public void setBeanName(String name) {
        // TODO Auto-generated method stub
        System.out.println("调用BeanNameAware接口的setBeanName方法"+"--------------"+this.name);
    }

    
    public void init(){
        System.out.println("调用xml中配置的init-method"+"--------------"+this.name);
    }
    
    public void destroy(){
        System.out.println("调用xml中配置的destroy-method");
    }
    
    public void sayName(){
        System.out.println("业务代码"+"--------------"+this.name);
    }
    
    @PostConstruct
    public void init2(){
        System.out.println("调用@PostConstruct注解的方法"+"--------------"+this.name);
    }
    
    @PreDestroy
    public void des(){
        System.out.println("调用@PreDestroy注解的方法");
    }
    
    
    
}

MyBeanPostProcessor.java
package com.cyh;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import com.cyh.Shunxu;

public class MyBeanPostProcessor implements BeanPostProcessor {
//注意:BeanPostProcessor会对所有的Bean进行拦截
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // TODO Auto-generated method stub
        Shunxu s = (Shunxu) bean; 
        s.setName("andy1");
        System.out.println("自定义BeanPostProcessor的postProcessBeforeInitialization执行"+"--------------"+s.name);
        
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // TODO Auto-generated method stub
        Shunxu s = (Shunxu) bean; 
        s.setName("andy2");
        System.out.println("自定义BeanPostProcessor的postProcessAfterInitialization执行"+"--------------"+s.name);
        return bean;
    }

}


单元测试调用结果

调用构造函数--------------null
调用BeanNameAware接口的setBeanName方法--------------kyle
调用BeanFactoryAware接口的setBeanFactory方法--------------kyle
调用ApplicationContextAware接口的setApplicationContext方法--------------kyle
自定义BeanPostProcessor的postProcessBeforeInitialization执行--------------andy1
调用@PostConstruct注解的方法--------------andy1
调用InitializingBean接口的afterPropertiesSet方法--------------andy1
调用xml中配置的init-method--------------andy1
自定义BeanPostProcessor的postProcessAfterInitialization执行--------------andy2
业务代码--------------andy2
调用@PreDestroy注解的方法
调用xml中配置的destroy-method

结果表明顺序如下1、先调用构造函数。2、然后注入值。可以看到name成员变量被注入了值kyle。3、如果该bean实现了Aware接口,则调用接口中的方法。4、如果该bean容器注册了一个BeanPostProcessor,则调用该BeanPostProcessor的postProcessBeforeInitialization方法。5、如果该bean有@PostConstruct注解的方法,则调用该方法。6、如果该bean实现了InitializingBean接口,则调用afterPropertiesSet方法。7、调用xml中配置的init-method。8、如果该bean容器注册了一个BeanPostProcessor,则调用该BeanPostProcessor的postProcessAfterInitialization方法。此时bean已经完全准备好,可以使用9、bean容器销毁,如果bean有@PreDestroy注解的方法,则调用该方法。10、调用xml中配置的destroy-method
注意9和10只有在bean的scope为Singleton的情况下才会调用

相关文章

网友评论

      本文标题:Spring bean的生命周期

      本文链接:https://www.haomeiwen.com/subject/uggmxftx.html