目录

一、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生命周期相关推荐

  1. spring系列-注解驱动原理及源码-bean组件注册

    目录 一.环境初始化 1.环境准备 二.bean的手动注入 1.xml方式注入bean 2.使用@Configuration&@Bean方式注入bean 三.自动扫描注册组件及bean 1.使 ...

  2. spring系列-注解驱动原理及源码-声明式事务使用及原理解析

    目录 一.环境准备 1.JdbcTemplate使用实例 2.事务添加 二.声明式事务源码分析 1.原理(与AOP非常相似) 一.环境准备 1.JdbcTemplate使用实例 (1)pom文件添加依 ...

  3. spring系列-注解驱动原理及源码-自动装配

    目录 一.spring规范的bean自动注入 1.使用@Autowired自动注入 2.使用@Qualifier指定需要装配的组件 3.使用@Autowired装配null对象 4.使用@Primar ...

  4. spring系列-注解驱动原理及源码-AOP使用及源码解析

    目录 一.用注解方式开启AOP 1.实例 2.AOP简单小结 二.AOP原理 1.@EnableAspectJAutoProxy溯源 2.AnnotationAwareAspectJAutoProxy ...

  5. spring系列-注解驱动原理及源码-spring容器创建流程

    目录 一.spring容器的refresh()[创建刷新] 二.BeanFactory 的创建及预准备工作 1.prepareRefresh()刷新前预处理工作. 2.obtainFreshBeanF ...

  6. spring系列-注解驱动原理及源码-属性赋值

    目录 一.bean属性赋值 1.bean属性使用@Value赋值 2.bean属性通过配置文件赋值 一.bean属性赋值 1.bean属性使用@Value赋值 (1)编写bean类 package c ...

  7. spring源码bean生命周期篇 一 如何实例化对象

    当前源码springboot版本为2.1.6.RELEASE ,spring版本为5.1.8.RELEASE 代码粘贴的也只有相关重要部分,如果是需要全部的代码请看源码 章节内容 (1) spring ...

  8. 手撸Spring系列12:MyBatis(源码篇)

    说在前头: 笔者本人为大三在读学生,书写文章的目的是为了对自己掌握的知识和技术进行一定的记录,同时乐于与大家一起分享,因本人资历尚浅,发布的文章难免存在一些错漏之处,还请阅读此文章的大牛们见谅与斧正. ...

  9. Dubbo源码分析-Spring与Dubbo整合原理与源码分析(二)

    Spring与Dubbo整合的整体流程(基于apache-dubbo-2.7.15) 因为dubbo有较多的兼容以前的代码比如@DubboReference 以前就有两个版本@Reference 和@ ...

最新文章

  1. 10个角度分析软件工程师应该知道的100件事
  2. C语言---写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串
  3. 远程办公指南 | 齐心守护健康,共倡远程协同
  4. 论怎么写好一篇实验报告
  5. word2vec如何得到词向量
  6. php arcode svg,在react中使用svg的各种方法总结(附代码)
  7. 通过Katas进行Java教程:网球比赛(轻松)
  8. PyTorch框架学习三——张量操作
  9. MySQL数据库专家分享资深DBA经验
  10. 三菱modbusRTU通讯实例_三菱FX5U以太网通讯功能有哪些?
  11. perl语言十分钟入门【零基础可入】
  12. java属于什么语言_java是什么语言 ?是什么系统?
  13. 如何压缩word文档大小?
  14. android手机连接电脑,安卓手机连接电脑的方法【图文教程】
  15. 如何解决网络运营商对4G网络的限速?
  16. 计算机固态和机械什么意思,固态硬盘和机械硬盘有什么不同?详解固态硬盘和机械硬盘...
  17. 雷军:天使投资人不是上帝只是配角
  18. win7上编译ipmitool
  19. 【20210122期AI简报】保姆级深度学习环境配置指南、寒武纪首颗AI训练芯片亮相...
  20. 联想的“智慧城市群落”

热门文章

  1. springboot配置文件加载顺序
  2. java中将对象转为基本数据类型
  3. 为什么visual的联机浏览功能不能用_饥荒为什么不出联机手游?看到这3条缺陷,才明白原因...
  4. 如何避免_旅游住宿如何避免雷区?
  5. CentOS 7安装GNOME图形界面并设置默认启动
  6. oracle中那个日期怎么相减_二手车鉴定中最容易混淆的日期读法,你会是那个读错的人吗?...
  7. python websocket server_用Python实现一个简单的WebSocket服务器
  8. python utf8_肿么在Python里使用UTF-8编码
  9. small2java_java类
  10. cudnn7.6.5下载 solitairetheme8_.NET Framework 3.5 开启方法及微软官方原版下载