提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
Bean生命周期流程
一、Bean生命周期流程图
- spring启动,加载类路径下配置文件,解析为BeanDefinition并装配到对应容器中;
- 查找并加载spring管理的bean,进行bean的实例化;
- Bean实例化后对Bean的引用和值进行属性注入;
- 若Bean实现接口BeanNameAware,则执行setBeanName()方法,获取bean的名字;
- 若Bean实现接口BeanFactoryAware,则执行setBeanFactory()方法,获取BeanFactory;
- 若Bean实现接口ApplicationContextAware,则执行setApplicationContext()方法,获取应用上下文;
- 若Bean实现BeanPostProcessor接口,则先执行postProcessBeforeInitialization()方法;
- 若Bean实现InitializingBean接口,则执行afterPropertiesSet()方法;
- 若Bean配置了init-method方法,则执行自定义方法;
- 若Bean实现BeanPostProcessor接口,则先执行postProcessAfterInitialization()方法;
- 如Bean实现了DisposableBean接口,则容器销毁时则执行destory()方法;
- 如果Bean配置了destory-method,则容器销毁时则执行自定义方法。
二、验证流程
1.验证UserDao生命周期
代码如下(示例):
/**
* @program: spring
* @description:
* @author: kerry
* @date: 2021-10-09 14:06
**/
public class UserDao implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {
public User getUserById() {
return new User(123456L, "kerry");
}
@Override
public void setBeanName(String name) {
System.out.println("setBeanName:" + name);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("setBeanFactory");
}
@Override
public void destroy() throws Exception {
System.out.println("destroy");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("setApplicationContext");
}
@PostConstruct
public void testPostConstruct() {
System.out.println("testPostConstruct");
}
@PreDestroy
public void testPreDestroy() {
System.out.println("testPreDestroy");
}
@Override
protected void finalize() throws Throwable {
System.out.println("finalize");
}
public void initMethod() {
System.out.println("initMethod");
}
public void destroyMethod() {
System.out.println("destroyMethod");
}
}
2.自定义MyBeanFactoryPostProcessor
代码如下(示例):
/**
* @program: spring
* @description:
* @author: kerry
* @date: 2021-10-09 17:02
**/
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
Object obj = beanFactory.getBean("userService");
if (Objects.nonNull(obj) && obj instanceof UserService) {
System.out.println("postProcessBeanFactory " + ((UserService) obj).getUserById(123));
}
System.out.println("postProcessBeanFactory");
}
}
3.自定义MyBeanPostProcessor
代码如下(示例):
/**
* @program: spring
* @description:
* @author: kerry
* @date: 2021-10-09 16:59
**/
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof UserDao) {
System.out.println("postProcessBeforeInitialization");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof UserDao) {
System.out.println("postProcessAfterInitialization");
}
return bean;
}
}
4.配置文件
代码如下(示例):
<?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">
<bean class="com.kerry.test.processor.MyBeanFactoryPostProcessor"></bean>
<bean class="com.kerry.test.processor.MyBeanPostProcessor"></bean>
<bean id="userDao" class="com.kerry.test.dao.UserDao" init-method="initMethod" destroy-method="destroyMethod"></bean>
<bean id="userService" class="com.kerry.test.service.impl.UserServiceImpl"></bean>
</beans>
5.测试类
代码如下(示例):
/**
* @program: spring
* @description:
* @author: kerry
* @date: 2021-09-30 14:29
**/
public class Test {
public static void main(String[] args) {
System.out.println("************容器启动开始*************");
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"spring-context.xml"});
UserService userService = (UserService) context.getBean("userService");
User user = userService.getUserById(12345);
if (context instanceof AbstractApplicationContext) {
((AbstractApplicationContext) context).registerShutdownHook();
}
System.out.println("************容器启动成功*************");
/*AnnotationConfigApplicationContext annotationConfigApplicationContext = new
AnnotationConfigApplicationContext(AppConfig.class);
UserDao userDao = annotationConfigApplicationContext.getBean(UserDao.class);
User user = userDao.getUserById();
System.out.println(user.toString());
*/
}
}
测试结果如下:
************容器启动开始*************
postProcessBeanFactory User{userId=12345, name='kerry'}
postProcessBeanFactory
setBeanName:userDao
setBeanFactory
setApplicationContext
postProcessBeforeInitialization
afterPropertiesSet
initMethod
postProcessAfterInitialization
************容器启动成功*************
destroy
destroyMethod