spring系列-注解驱动原理及源码-bean生命周期
目录
一、Bean的初始化和销毁
1、@Bean指定初始化和销毁方法
2、通过实现InitializingBean和Disposabean来初始化和销毁bean
3、使用JSR250定义的@PostConstruct&@PreDestroy注解来创建和销毁bean
4、BeanPostProcessor-后置处理器(全局)
5、生命周期总结
二、BeanPostProcessor原理
1、BeanPostProcessor原理
2、spring底层对BeanPostProcessor的使用
一、Bean的初始化和销毁
1、@Bean指定初始化和销毁方法
(1)定义bean类
package com.xiang.spring.bean;public class Car {public Car() {System.out.println("car constructor ...");}public void init() {System.out.println("car init ...");}public void destory() {System.out.println("car destory ...");}
}
(2)编写配置类
package com.xiang.spring.config;import com.xiang.spring.bean.Car;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;/**
* bean的生命周期(由容器管理):
* bean创建——初始化——销毁
* 可以自定义初始化和销毁方法,容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法。
*
* 构造(创建对象):
* 单实例:在容器启动的时候创建对象
* 多实例:在每次获取的时候创建对象
* 初始化:
* 对象创建完成,并赋值好,调用初始化方法。
* 销毁:
* 单实例bean:在容器关闭时进行销毁。
* 多实例bean:容器不会管理bean,容器不会调用销毁方法。
*
* 1、指定初始化和销毁方法:
* 通过@Bean指定init-method和destroy-method
*
*/
@Configuration
public class MainConfigOfLifeCycle {//@Scope("prototype")@Bean(initMethod = "init", destroyMethod = "destory")public Car car() {return new Car();}
}
(3)测试程序
@Test
public void test01() {// 创建ioc容器,容器创建时,默认会将单例的bean都创建出来AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);System.out.println("容器创建完成");applicationContext.getBean("car");// 容器关闭 就会销毁beanapplicationContext.close();
}//执行结果
car constructor ...
car init ...
容器创建完成
car destory ...
2、通过实现InitializingBean和Disposabean来初始化和销毁bean
(1)定义bean类
package com.xiang.spring.bean;import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;public class Cat implements InitializingBean, DisposableBean {public Cat() {System.out.println("cat construator");}// 销毁public void destroy() throws Exception {System.out.println("cat destroy");}// 初始化public void afterPropertiesSet() throws Exception {System.out.println("cat init");}
}
(2)配置类
@Bean
public Cat cat() {return new Cat();
}
(3)测试类
@Test
public void test01() {// 创建ioc容器,容器创建时,默认会将单例的bean都创建出来AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);System.out.println("容器创建完成");// 容器关闭 就会销毁beanapplicationContext.close();
}// 运行结果
cat construator
cat init
容器创建完成
cat destroy
3、使用JSR250定义的@PostConstruct&@PreDestroy注解来创建和销毁bean
(1)定义bean
package com.xiang.spring.bean;import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;@Component
public class Dog {public Dog() {System.out.println("dog constructor ...");}// 对象创建并赋值之后调用@PostConstructpublic void init() {System.out.println("dog PostConstruct ...");}// 容器移除对象之前调用@PreDestroypublic void destory() {System.out.println("dog PreDestroy ...");}
}
(2)测试查看结果
@Test
public void test01() {// 创建ioc容器,容器创建时,默认会将单例的bean都创建出来AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);System.out.println("容器创建完成");// 容器关闭 就会销毁beanapplicationContext.close();
}dog constructor ...
dog PostConstruct ...
容器创建完成
dog PreDestroy ...
4、BeanPostProcessor-后置处理器(全局)
(1)编写自定义BeanPostProcessor
package com.xiang.spring.bean;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;/**
* 后置处理器:初始化前后进行工作
* 方法返回值:包装好的bean
*/
//@Component
public class MyBeanPostProcessor implements BeanPostProcessor {public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println(beanName + " - MyBeanPostProcessor - postProcessBeforeInitialization");return bean;}public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println(beanName + "MyBeanPostProcessor - postProcessAfterInitialization");return bean;}
}
(2)测试查看结果
可以看出来,所有的bean都在初始化前后执行了postProcessBeforeInitialization和postProcessAfterInitialization。
@Test
public void test01() {// 创建ioc容器,容器创建时,默认会将单例的bean都创建出来AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);System.out.println("容器创建完成");// 容器关闭 就会销毁beanapplicationContext.close();
}// 运行结果
org.springframework.context.event.internalEventListenerProcessor - MyBeanPostProcessor - postProcessBeforeInitialization
org.springframework.context.event.internalEventListenerProcessorMyBeanPostProcessor - postProcessAfterInitialization
org.springframework.context.event.internalEventListenerFactory - MyBeanPostProcessor - postProcessBeforeInitialization
org.springframework.context.event.internalEventListenerFactoryMyBeanPostProcessor - postProcessAfterInitialization
mainConfigOfLifeCycle - MyBeanPostProcessor - postProcessBeforeInitialization
mainConfigOfLifeCycleMyBeanPostProcessor - postProcessAfterInitialization
dog constructor ...
dog - MyBeanPostProcessor - postProcessBeforeInitialization
dog PostConstruct ...
dogMyBeanPostProcessor - postProcessAfterInitialization
car constructor ...
car - MyBeanPostProcessor - postProcessBeforeInitialization
car init ...
carMyBeanPostProcessor - postProcessAfterInitialization
cat construator
cat - MyBeanPostProcessor - postProcessBeforeInitialization
cat init
catMyBeanPostProcessor - postProcessAfterInitialization
容器创建完成
cat destroy
car destory ...
dog PreDestroy ...
5、生命周期总结
bean的生命周期(由容器管理):
bean创建——初始化——销毁
可以自定义初始化和销毁方法,容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法。
构造(创建对象):
单实例:在容器启动的时候创建对象
多实例:在每次获取的时候创建对象
初始化:
对象创建完成,并赋值好,调用初始化方法。
销毁:
单实例bean:在容器关闭时进行销毁。
多实例bean:容器不会管理bean,容器不会调用销毁方法。
① 、指定初始化和销毁方法:
通过@Bean指定init-method和destroy-method
② 、通过让bean实现InitializingBean(定义初始化逻辑)
实现DisposableBean(定义销毁逻辑)
③ 、可以使用JSR250:
@PostConstruct:在bean创建完成并且属性赋值完成后,来执行初始化
@PreDestroy:在容器销毁bean之前,通知我们进行清理工作
④ 、BeanPostProcessor接口:bean的后置处理器:
在bean初始化前后进行一些处理工作。
postProcessBeforeInitialization:在初始化之前工作
postProcessAfterInitialization:在初始化之后工作
二、BeanPostProcessor原理
1、BeanPostProcessor原理
遍历得到容器中所有的BeanPostProcessor,挨个执行beforeInitialization,一旦返回null,跳出for循环,不会执行后面的BeanPostProcessor。
源码中是先执行populateBean方法进行属性赋值、再执行postProcessBeforeInitialization方法,再执行初始化方法、再执行postProcessAfterInitialization方法。
/**
* 初始化bean的完整源码
*/
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {if (System.getSecurityManager() != null) {AccessController.doPrivileged(new PrivilegedAction<Object>() {@Overridepublic Object run() {invokeAwareMethods(beanName, bean);return null;}}, getAccessControlContext());}else {invokeAwareMethods(beanName, bean);}Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {invokeInitMethods(beanName, wrappedBean, mbd);}catch (Throwable ex) {throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),beanName, "Invocation of init method failed", ex);}if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;
}
2、spring底层对BeanPostProcessor的使用
bean赋值,注入其他组件、@Autowired、生命周期注解功能、@Async、等等很多功能都用到了BeanPostProcessor。
spring系列-注解驱动原理及源码-bean生命周期相关推荐
- spring系列-注解驱动原理及源码-bean组件注册
目录 一.环境初始化 1.环境准备 二.bean的手动注入 1.xml方式注入bean 2.使用@Configuration&@Bean方式注入bean 三.自动扫描注册组件及bean 1.使 ...
- spring系列-注解驱动原理及源码-声明式事务使用及原理解析
目录 一.环境准备 1.JdbcTemplate使用实例 2.事务添加 二.声明式事务源码分析 1.原理(与AOP非常相似) 一.环境准备 1.JdbcTemplate使用实例 (1)pom文件添加依 ...
- spring系列-注解驱动原理及源码-自动装配
目录 一.spring规范的bean自动注入 1.使用@Autowired自动注入 2.使用@Qualifier指定需要装配的组件 3.使用@Autowired装配null对象 4.使用@Primar ...
- spring系列-注解驱动原理及源码-AOP使用及源码解析
目录 一.用注解方式开启AOP 1.实例 2.AOP简单小结 二.AOP原理 1.@EnableAspectJAutoProxy溯源 2.AnnotationAwareAspectJAutoProxy ...
- spring系列-注解驱动原理及源码-spring容器创建流程
目录 一.spring容器的refresh()[创建刷新] 二.BeanFactory 的创建及预准备工作 1.prepareRefresh()刷新前预处理工作. 2.obtainFreshBeanF ...
- spring系列-注解驱动原理及源码-属性赋值
目录 一.bean属性赋值 1.bean属性使用@Value赋值 2.bean属性通过配置文件赋值 一.bean属性赋值 1.bean属性使用@Value赋值 (1)编写bean类 package c ...
- spring源码bean生命周期篇 一 如何实例化对象
当前源码springboot版本为2.1.6.RELEASE ,spring版本为5.1.8.RELEASE 代码粘贴的也只有相关重要部分,如果是需要全部的代码请看源码 章节内容 (1) spring ...
- 手撸Spring系列12:MyBatis(源码篇)
说在前头: 笔者本人为大三在读学生,书写文章的目的是为了对自己掌握的知识和技术进行一定的记录,同时乐于与大家一起分享,因本人资历尚浅,发布的文章难免存在一些错漏之处,还请阅读此文章的大牛们见谅与斧正. ...
- Dubbo源码分析-Spring与Dubbo整合原理与源码分析(二)
Spring与Dubbo整合的整体流程(基于apache-dubbo-2.7.15) 因为dubbo有较多的兼容以前的代码比如@DubboReference 以前就有两个版本@Reference 和@ ...
最新文章
- 10个角度分析软件工程师应该知道的100件事
- C语言---写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串
- 远程办公指南 | 齐心守护健康,共倡远程协同
- 论怎么写好一篇实验报告
- word2vec如何得到词向量
- php arcode svg,在react中使用svg的各种方法总结(附代码)
- 通过Katas进行Java教程:网球比赛(轻松)
- PyTorch框架学习三——张量操作
- MySQL数据库专家分享资深DBA经验
- 三菱modbusRTU通讯实例_三菱FX5U以太网通讯功能有哪些?
- perl语言十分钟入门【零基础可入】
- java属于什么语言_java是什么语言 ?是什么系统?
- 如何压缩word文档大小?
- android手机连接电脑,安卓手机连接电脑的方法【图文教程】
- 如何解决网络运营商对4G网络的限速?
- 计算机固态和机械什么意思,固态硬盘和机械硬盘有什么不同?详解固态硬盘和机械硬盘...
- 雷军:天使投资人不是上帝只是配角
- win7上编译ipmitool
- 【20210122期AI简报】保姆级深度学习环境配置指南、寒武纪首颗AI训练芯片亮相...
- 联想的“智慧城市群落”
热门文章
- springboot配置文件加载顺序
- java中将对象转为基本数据类型
- 为什么visual的联机浏览功能不能用_饥荒为什么不出联机手游?看到这3条缺陷,才明白原因...
- 如何避免_旅游住宿如何避免雷区?
- CentOS 7安装GNOME图形界面并设置默认启动
- oracle中那个日期怎么相减_二手车鉴定中最容易混淆的日期读法,你会是那个读错的人吗?...
- python websocket server_用Python实现一个简单的WebSocket服务器
- python utf8_肿么在Python里使用UTF-8编码
- small2java_java类
- cudnn7.6.5下载 solitairetheme8_.NET Framework 3.5 开启方法及微软官方原版下载