Spring的bean的生命周期
来源:互联网 发布:php chmod 777 编辑:程序博客网 时间:2024/05/17 13:08
接触Spring时间越久,越觉得其设计思想对我们开发的影响之深,最近在开发项目时,组里一个师兄的项目设计就和Spring的bean生命周期设计有很多不谋而合之处,接着对项目理解,回顾了一下Spring的bean的生命周期。
本文基于ApplicationContext中的bean的生命周期为例。
生命周期流程图
Spring bean的生命周期从创建Spring容器开始到Spring的容器销毁bean。最核心关键的流程图如下:
从上图可以看出,最核心的分为三步:
- bean的实例化
- 给bean populate填充属性
- bean的初始化
各类接口作用域维度的分类
1. 粒度在bean自身的方法:
配置文件中<bean>
的init-method和destroy-method指定的方法
2. 粒度在bean级生命周期的方法
BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法
3. 容器级生命周期接口方法
InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。
测试demo
下面定义了三个bean:
MyBeanFactoryPostProcessor实现了BeanFactoryPostProcessor,这个类在bean开始实例化之前被调用,所以可以修改bean的属性,修改每个bean里面的properties。可以理解成前置处理器
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor{ public MyBeanFactoryPostProcessor() { System.out.println("MyBeanFactoryPostProcessor 构造器实例化"); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println("MyBeanFactoryPostProcessor#postProcessBeanFactory()"); System.out.println("count bean = "+beanFactory.getBeanDefinitionCount()); System.out.println("beanDefinitionName number is "+ beanFactory.getBeanDefinitionNames().length); for(String beanDefinitionName : beanFactory.getBeanDefinitionNames()){ System.out.println(" "+ beanDefinitionName); } System.out.println("singletonNames number is "+ beanFactory.getSingletonNames().length); for(String singletonName : beanFactory.getSingletonNames()){ System.out.println(" "+ singletonName); } BeanDefinition bd = beanFactory.getBeanDefinition("louyuting-user"); bd.getPropertyValues().addPropertyValue("id", "110"); }}
MyBeanPostProcessor实现了BeanPostProcessor接口,用于bean初始化前后调用、
public class MyBeanPostProcessor implements BeanPostProcessor { public MyBeanPostProcessor() { System.out.println("MyBeanPostProcessor 构造器实例化"); } // 初始化之前 @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("bean初始化之前调用:BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!"); return bean; } // 初始化之后调用 @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("bean初始化之后调用:BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!"); return bean; }}
MyInstantiationAwareBeanPostProcessor实现了InstantiationAwareBeanPostProcessorAdapter接口,用于bean实例化前后调用处理。
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter { public MyInstantiationAwareBeanPostProcessor() { System.out.println("MyInstantiationAwareBeanPostProcessor构造器"); } // 实例化Bean之前调用 @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { System.out.println("bean实例化之前调用,InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation"); return null; } // 实例化Bean之后调用 @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { System.out.println("bean实例化之后前调用,InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation"); return false; } // 接口方法、设置某个属性时调用 @Override public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { System.out.println("接口方法、设置某个属性时调用,InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法 "); return pvs; }}
User 实现了BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean四个接口。作用于bean填充属性之后执行。
public class User implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean { private String id; private String name; private BeanFactory beanFactory; private String beanName; public User() { System.out.println("User 构造器实例化"); } public String getId() { return id; } public void setId(String id) { System.out.println("注入属性 id"); this.id = id; } public String getName() { return name; } public void setName(String name) { System.out.println("注入属性 name"); this.name = name; } // BeanFactoryAware @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("【BeanFactoryAware接口】 接口调用 BeanFactoryAware.setBeanFactory(BeanFactory beanFactory)"); this.beanFactory = beanFactory; } // BeanNameAware @Override public void setBeanName(String name) { System.out.println("【BeanNameAware接口】 接口调用 BeanNameAware.setBeanName(String name)"); this.beanName = name; } public void myInit() { System.out.println("【init-method】调用<bean>的init-method属性指定的初始化方法"); } public void myDestory() { System.out.println("【destroy-method】调用<bean>的destroy-method 属性指定的初始化方法"); } @Override public void destroy() throws Exception { System.out.println("【DiposibleBean接口】调用DiposibleBean.destory()"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("【InitializingBean接口】调用InitializingBean.afterPropertiesSet()"); }}
Spring的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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-autowire="byName"> <bean id="louyuting-user" class="com.example.demo.test.ioc.User" init-method="myInit" destroy-method="myDestory"> <property name="id" value="1234"/> <property name="name" value="louyuting"/> </bean> <bean id="beanPostProcessor" class="com.example.demo.test.ioc.MyBeanPostProcessor"> </bean> <bean id="instantiationAwareBeanPostProcessor" class="com.example.demo.test.ioc.MyInstantiationAwareBeanPostProcessor"> </bean> <bean id="beanFactoryPostProcessor" class="com.example.demo.test.ioc.MyBeanFactoryPostProcessor"> </bean></beans>
测试运行主函数:
public class BeanLifeCycleTest { public static void main(String[] args) { ConfigurableApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:bean.xml"); User user = applicationContext.getBean("louyuting-user", User.class); System.out.println(user); applicationContext.registerShutdownHook(); }}
测试运行结果
MyBeanFactoryPostProcessor 构造器实例化MyBeanFactoryPostProcessor#postProcessBeanFactory()count bean = 4beanDefinitionName number is 4 louyuting-user beanPostProcessor instantiationAwareBeanPostProcessor beanFactoryPostProcessorsingletonNames number is 4 environment systemProperties systemEnvironment beanFactoryPostProcessorMyBeanPostProcessor 构造器实例化MyInstantiationAwareBeanPostProcessor构造器bean实例化之前调用,InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiationUser 构造器实例化bean实例化之后前调用,InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation【BeanNameAware接口】 接口调用 BeanNameAware.setBeanName(String name)【BeanFactoryAware接口】 接口调用 BeanFactoryAware.setBeanFactory(BeanFactory beanFactory)bean初始化之前调用:BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!【InitializingBean接口】调用InitializingBean.afterPropertiesSet()【init-method】调用<bean>的init-method属性指定的初始化方法bean初始化之后调用:BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!com.example.demo.test.ioc.User@57e1b0c【DiposibleBean接口】调用DiposibleBean.destory()【destroy-method】调用<bean>的destroy-method 属性指定的初始化方法
完美验证了结果。
- Spring Bean的生命周期
- Spring Bean的生命周期
- spring - bean的生命周期
- Spring Bean的生命周期
- spring bean 的生命周期
- Spring bean的生命周期
- spring bean的生命周期
- Spring Bean的生命周期
- Spring Bean的生命周期
- Spring bean的生命周期
- Spring Bean的生命周期
- Spring Bean的生命周期
- Spring bean的生命周期
- Spring Bean的生命周期
- Spring Bean的生命周期
- Spring Bean 的生命周期
- spring Bean的生命周期
- spring Bean的生命周期
- 类和对象
- <!DOCTYPE> 知识点回顾
- LeetCode-43-Multiply Strings 模拟
- Ambari安装之部署单节点集群
- 使用Unity3D制作技能图标冷却效果
- Spring的bean的生命周期
- Appserv连接Mysql失败解决方式
- LeetCode 338. Counting Bits (Medium)
- ionic+做一个侧滑跳转+标题头旁边有一个后退功能的按钮
- Ambari安装之部署3个节点的HA分布式集群
- LintCode 488快乐数
- centos6.5编译安装php7
- Bootstrap carousel轮播图插件 简洁版
- Service层getParameter方法接受字符转换成int类型