SpringBoot注解---4.扩展原理

一、Bean的生命周期管理

  1. bean的实例化:调用bean的构造方法,我们可以在bean的无参构造方法中执行相应的逻辑。
  2. bean的初始化:在初始化时,可以通过BeanPostProcessor的postProcessBeforeInitialization()方法和postProcessAfterInitialization()方法进行拦截,执行自定义的逻辑;通过@PostConstruct注解、InitializingBean和init-method来指定bean初始化前后执行的方法,在该方法中咱们可以执行自定义的逻辑。
  3. bean的销毁:可以通过@PreDestroy注解、DisposableBean和destroy-method来指定bean在销毁前执行的方法,在该方法中咱们可以执行自定义的逻辑。

1.通过@Bean指定init-method和destroy-method

使用时机:

  1. 初始化方法:对象创建完成,如果对象中存在一些属性,并且这些属性也都赋好值之后,那么就会调用bean的初始化方法。
  2. 销毁的方法:可以对数据源的连接等信息进行关闭和清理。
  单实例 多实例
初始化 对于单实例bean来说,在Spring容器创建完成后,Spring容器会自动调用bean的初始化方法 在每次获取bean对象的时候,调用bean的初始化方法
销毁 在容器关闭的时候,会调用bean的销毁方法 Spring容器不会管理这个bean,也就不会自动调用这个bean的销毁方法了

2.通过让bean实现InitializingBean和DisposableBean两个接口

(1)初始化bean

Spring为bean提供了两种初始化的方式,实现InitializingBean接口(也就是要实现该接口中的afterPropertiesSet方法),或者在配置文件或@Bean注解中通过init-method来指定,两种方式可以同时使用。

  1. 实现InitializingBean接口是直接调用afterPropertiesSet()方法,与通过反射调用init-method指定的方法相比,效率相对来说要高点。但是init-method方式消除了对Spring的依赖。
  2. 如果调用afterPropertiesSet方法时出错,那么就不会调用init-method指定的方法了。

(2)销毁bean

  1. 实现org.springframework.beans.factory.DisposableBean接口的bean在销毁前,Spring将会调用DisposableBean接口的destroy()方法。
  2. 使用destroy-method

 前者与Spring耦合高,使用类型强转.方法名(),效率高;后者耦合低,使用反射,效率相对来说较低。

【 注意】多实例bean的生命周期不归Spring容器来管理,这里的DisposableBean接口中的方法是由Spring容器来调用的,所以如果一个多实例bean实现了DisposableBean接口是没有啥意义的,因为相应的方法根本不会被调用,当然了,在XML配置文件中指定了destroy方法,也是没有任何意义的。所以,在多实例bean情况下,Spring是不会自动调用bean的销毁方法的。

3.使用JSR-250规范里面定义的@PostConstruct和@PreDestroy两个注解

@PostConstruct注解是Java中的注解,并不是Spring提供的注解。@PostConstruct和@PreDestroy是Java规范JSR-250引入的注解,定义了对象的创建和销毁工作,同一期规范中还有@Resource注解,Spring也支持了这些注解。

 注解 源码 执行顺序
@PostConstruct

在bean创建完成并且属性赋值完成之后,来执行初始化方法。

Constructor(构造方法)→@Autowired(依赖注入)→@PostConstruct(注释的方法)

@PreDestroy

在容器销毁bean之前通知我们进行清理工作。

调用destroy()方法→@PreDestroy→destroy()方法→bean销毁 

4.通过让bean实现BeanPostProcessor接口

(1)BeanPostProcessor是什么?

BeanPostProcessor是一个接口,其中有两个方法,Spring容器中的每一个bean对象初始化前后,都会执行BeanPostProcessor接口的实现类中的这两个方法。

 接口 调用时机
postProcessBeforeInitialization 在bean实例化和属性设置之后,自定义初始化方法之前被调用
postProcessAfterInitialization 在自定义初始化方法之后被调用

当容器中存在多个BeanPostProcessor的实现类时,会按照它们在容器中注册的顺序执行。对于自定义的BeanPostProcessor实现类,还可以让其实现Ordered接口自定义排序。

(2)作用

  后置处理器可用于bean对象初始化前后进行逻辑增强。Spring提供了BeanPostProcessor接口的很多实现类,例如AutowiredAnnotationBeanPostProcessor用于@Autowired注解的实现,AnnotationAwareAspectJAutoProxyCreator用于Spring AOP的动态代理等等。

(3)原理

在Spring中调用initializeBean()方法之前,还调用了populateBean()方法来为bean的属性赋值

在applyBeanPostProcessorsBeforeInitialization()方法中,会遍历所有BeanPostProcessor对象,然后依次执行所有BeanPostProcessor对象的postProcessBeforeInitialization()方法,一旦BeanPostProcessor对象的postProcessBeforeInitialization()方法返回null以后,则后面的BeanPostProcessor对象便不再执行了,而是直接退出for循环。

(4)Spring底层对BeanPostProcessor的使用

bean赋值,注入其他组件,@Autowired,生命周期注解功能,@Async,xxxBeanProcessor等。

 

posted @   nxf_rabbit75  阅读(172)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
历史上的今天:
2019-04-05 pandas处理时间序列(1):pd.Timestamp()、pd.Timedelta()、pd.datetime( )、 pd.Period()、pd.to_timestamp()、datetime.strftime()、pd.to_datetime( )、pd.to_period()
2019-04-05 修改jupyter notebook的默认打开地址
一、Bean的生命周期管理1.通过@Bean指定init-method和destroy-method2.通过让bean实现InitializingBean和DisposableBean两个接口(1)初始化bean(2)销毁bean3.使用JSR-250规范里面定义的@PostConstruct和@PreDestroy两个注解4.通过让bean实现BeanPostProcessor接口(1)BeanPostProcessor是什么?(2)作用(3)原理(4)Spring底层对BeanPostProcessor的使用
点击右上角即可分享
微信分享提示