【巨人的肩膀】Spring bean生命周期验证

BeanFactory接口

尊重源码,以下摘自 BeanFactory 源码注释翻译:

BeanFactory 是获取 spring bean 容器的顶级接口。该接口被持有一系列 bean definitions 的对象所实现。依赖 bean definitions,工厂返回一个原型实例或者一个单例实例
通常,BeanFactory 将加载存储在配置中的 bean definitions 资源(例如XML文档)。这些定义没有限制何种方式存储:LDAP, RDBMS, XML,properties file等。并且鼓励使用 bean 的依赖注入引用

实现类需要支持 Bean 的完整生命周期,完整的初始化方法及其标准顺序(格式:接口 方法)为:

  1. BeanNameAware setBeanName 设置bean名称
  2. BeanClassLoaderAware setBeanClassLoader 设置bean类加载器
  3. BeanFactoryAware setBeanFactory 设置bean工厂
  4. EnvironmentAware setEnvironment 设置环境:profiles+properties
  5. EmbeddedValueResolverAware setEmbeddedValueResolver 设置嵌入式值解析器
  6. ResourceLoaderAware setResourceLoader 设置资源载入器,只适用于在应用程序上下文中运行
  7. ApplicationEventPublisherAware setApplicationEventPublisher 注入应用事件发布器 ApplicationEventPublisher
  8. MessageSourceAware setMessageSource 设置国际化支持
  9. ApplicationContextAware setApplicationContext 设置应用上下文
  10. ServletContextAware setServletContext 设置 servlet 上下文
  11. BeanPostProcessors postProcessBeforeInitialization 执行 bean 处理器前置方法
  12. InitializingBean afterPropertiesSet 执行初始化 Bean 设置完属性后置方法
  13. a custom init-method definition 执行自定义初始化方法
  14. BeanPostProcessors postProcessAfterInitialization 执行 bean 处理器后置方法

销毁顺序:

  1. DestructionAwareBeanPostProcessors postProcessBeforeDestruction 销毁处理器的前置方法
  2. DisposableBean destroy Bean销毁回调方法
  3. a custom destroy-method definition 用户自定义销毁方法
 public interface BeanFactory {
 
     //转定义符
     String FACTORY_BEAN_PREFIX = "&";
 
     //定义5种获取Bean方法
     Object getBean(String name) throws BeansException;
     <T> T getBean(String name, Class<T> requiredType) throws BeansException;
     <T> T getBean(Class<T> requiredType) throws BeansException; 
     Object getBean(String name, Object... args) throws BeansException;
     <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
 
     //判断容器是否含有指定名字的Bean
     boolean containsBean(String name);
 
     //查询指定名字的Bean是否是Singleton类型的Bean.
     boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
 
     //查询指定名字的Bean是否是Prototype类型的
     boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
 
     //查询指定了名字的Bean的Class类型是否是特定的Class类型.
     boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
     boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
 
     //查询指定名字的Bean的Class类型.
     Class<?> getType(String name) throws NoSuchBeanDefinitionException;
 
     //查询指定了名字的Bean的所有别名,这些都是在BeanDefinition中定义的
     String[] getAliases(String name);
 
 }
模拟获取bean
 public static void main(String[] args) {
         //1.容器IOC获取bean初始化
         ClassPathResource resource = new ClassPathResource("spring.xml");//载入资源
         DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
         XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);//构造reader
         reader.loadBeanDefinitions(resource);//核心方法,解析bean定义
         Dao dao = factory.getBean("daoImpl", Dao.class);//IOC容器DefaultListableBeanFactory通过名称和类class获取bean单例对象
         dao.select();//执行Bean实例方法
 }
<bean id="daoImpl" class="spring.aop.xml.dao.impl.DaoImpl" />

测试验证

【巨人的肩膀】Spring bean生命周期验证_第1张图片

需求:前面说的17个步骤都可以测试,我们选取其中的8个步骤进行测试如下:

初始化流程:
1 BeanNameAware.setBeanName:设置 Bean 名称
3. BeanFactoryAware.setBeanFactory:设置 Bean 工厂
11. BeanPostProcessors.postProcessBeforeInitialization:执行 Bean 处理器前置方法
12. InitializingBean.afterPropertiesSet:执行初始化 Bean 设置完属性后置方法
13. a custom init-method.definition:执行自定义初始化方法
14. BeanPostProcessors.postProcessAfterInitialization:执行 Bean 处理器后置方法
销毁流程:
2. DisposableBean.destroy:Bean销毁回调方法
3. a custom destroy-method.definition:用户自定义销毁方法

代码清单
  1. 构建一个 Person 类,实现 BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean 接口
 package spring.ioc;
 
 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.DisposableBean;
 import org.springframework.beans.factory.InitializingBean;
 
 public class Person implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean {
     
     private String name;   
     
     private String mobile;
      
     public Person() {
         super();
         System.out.println("[构造器] 调用Person的构造器实例化");
     }
 
     public String getName() {
         return name;
     }
 
     public void setName(String name) {
         System.out.println("[属性注入] name="+name);
         this.name = name;
     }
 
     public String getMobile() {
         return mobile;
     }
 
     public void setMobile(String mobile) {
         System.out.println("[属性注入] mobile="+mobile);
         this.mobile = mobile;
     }
 
     @Override
     public void destroy() throws Exception {
         System.out.println("[接口DisposableBean.destroy() ]");
     }
 
     @Override
     public void afterPropertiesSet() throws Exception {
         System.out.println("[接口InitializingBean.afterPropertiesSet() ]");
     }
 
     @Override
     public void setBeanName(String name) {
         System.out.println("[接口BeanNameAware.setBeanName() ]");
     }
 
     @Override
     public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
         System.out.println("[接口BeanFactoryAware.setBeanFactory() ]");
     }
 
     public void myInit(){
         System.out.println("[init-method]调用的init-method属性指定的初始化方法");
     }
     
     public void myDestory() {
         System.out.println("[destroy-method]调用的destroy-method属性指定的销毁方法");
     }
 
 }
  1. 自定义工厂后处理器,复写 postProcessBeanFactory 方法,获取 bean 定义后添加属性 mobile=110
 package spring.ioc;
 
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.config.BeanDefinition;
 import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
 import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
 
 public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
 
     public MyBeanFactoryPostProcessor() {
         super();
         System.out.println("[MyBeanFactoryPostProcessor工厂后处理器]BeanFactoryPostProcessor实现类构造器!!");
     }
 
     @Override
     public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0) throws BeansException {
         System.out.println("[MyBeanFactoryPostProcessor工厂后处理器]BeanFactoryPostProcessor.postProcessBeanFactory()获取bean定义后添加属性mobile=110");
         BeanDefinition bd = arg0.getBeanDefinition("person");
         bd.getPropertyValues().addPropertyValue("mobile", "110");
     }
 
 }
  1. 自定义 Bean 后处理器,复写 postProcessBeforeInitialization 和 postProcessAfterInitialization 2个方法,分别对应初始化前后时的操作
 package spring.ioc;
 
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.config.BeanPostProcessor;
 
 public class MyBeanPostProcessor implements BeanPostProcessor {
 
     public MyBeanPostProcessor() {
         super();
         System.out.println("这是BeanPostProcessor实现类构造器!!");
     }
 

     @Override
     public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
         System.out.println("BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!beanName="+beanName);
         return bean;
     }

     @Override
     public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
         System.out.println("BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!beanName="+beanName);
         return bean;//注意,如果返回null,后续BeanPostProcessor不会再执行
     }
  
 }
  1. 自定义实例化 bean 后处理器适配器,复写 postProcessBeforeInstantiation、postProcessBeforeInstantiation、postProcessPropertyValues 分别对应实例化 Bean 前调用、实例化 Bean 后调用、设置某个属性时调用

注意:InstantiationAwareBeanPostProcessorAdapter ,这里是实例化 Instantiation,不是初始化 Initialization!!!

 package spring.ioc;
 
 import java.beans.PropertyDescriptor;
 
 import org.springframework.beans.BeansException;
 import org.springframework.beans.PropertyValues;
 import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
 
 public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
 
     public MyInstantiationAwareBeanPostProcessor() {
         super();
         System.out.println("这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!");
     }
 
     // 接口方法、实例化Bean之前调用
     @Override
     public Object postProcessBeforeInstantiation(Class<?> beanClass,String beanName) throws BeansException {
         System.out.println("InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法[实例化Bean之前调用 ]beanname="+beanName);
         return null;
     }
 
     // 接口方法、实例化Bean之后调用
     @Override
     public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
         System.out .println("InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法[实例化Bean之后调用]beanname="+beanName);
         return bean;
     }
 
     // 接口方法、设置某个属性时调用
     @Override
     public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
         System.out.println("InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法 pvs="+pvs+",beanName="+beanName);
         return pvs;
     }    
 }  
  1. 测试类,使用 ClassPathXmlApplicationContext 从 xml 中读取 bean 配置文件生成 applicationContext 容器应用上下文,这一步对应容器初始化。第二部从应用上下文中获取 bean。最后一步注册一个关闭钩子,在容器关闭时触发
 package spring.ioc;
 
 import org.junit.Test; 6 import org.springframework.context.ApplicationContext;
 import org.springframework.context.support.ClassPathXmlApplicationContext;10 
 import spring.aop.xml.dao.Dao;
 
 public class IOCTest {
     
     @Test
     public void iocPersonTest(){
         System.out.println("=============容器初始化======start=========");
         @SuppressWarnings("resource")
         ApplicationContext applicationContext = new ClassPathXmlApplicationContext("simple_spring_bean.xml");//源码入口
         System.out.println("=============容器初始化=======end========");
         System.out.println("=============获取person bean====start=======");
         Person person = applicationContext.getBean("person",Person.class);//获取Bean
         System.out.println("=============获取person bean====end=======,person类名="+person.getClass().getName());
         System.out.println("=============注册关闭钩子,关闭容器(JVM shutdown)时触发钩子!================");
         ((ClassPathXmlApplicationContext)applicationContext).registerShutdownHook();
     }
 }
// 结果
=============容器初始化======start=========
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
[MyBeanFactoryPostProcessor工厂后处理器]BeanFactoryPostProcessor实现类构造器!!
[MyBeanFactoryPostProcessor工厂后处理器]BeanFactoryPostProcessor.postProcessBeanFactory()获取bean定义后添加属性mobile=110
这是BeanPostProcessor实现类构造器!!
这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!
InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法[实例化Bean之前调用 ]beanname=person
[构造器] 调用Person的构造器实例化
InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法 pvs=PropertyValues: length=2; bean property 'mobile'; bean property 'name',beanName=person
[属性注入] mobile=110
[属性注入] name=张三
[接口BeanNameAware.setBeanName() ]
[接口BeanFactoryAware.setBeanFactory() ]
BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!beanName=person
[接口InitializingBean.afterPropertiesSet() ]
[init-method]调用<bean>的init-method属性指定的初始化方法
BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!beanName=person
InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法[实例化Bean之后调用]beanname=person
=============容器初始化=======end========
=============获取person bean====start=======
=============获取person bean====end=======,person类名=spring.ioc.Person
=============注册关闭钩子,关闭容器(JVM shutdown)时触发钩子!================
[接口DisposableBean.destroy() ]
[destroy-method]调用<bean>的destroy-method属性指定的销毁方法

流程图
【巨人的肩膀】Spring bean生命周期验证_第2张图片
【巨人的肩膀】Spring bean生命周期验证_第3张图片
【巨人的肩膀】Spring bean生命周期验证_第4张图片

你可能感兴趣的:(巨人的肩膀,spring,java,后端)