首页 > 其他分享 >【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】

【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】

时间:2023-04-04 15:34:13浏览次数:41  
标签:InitializingBean Spring BeanFactoryPostProcessor Aware 接口 注解 失效 处理器

一、Aware接口&InitializingBean
1、基础准备

2、总结

3、补充:EmbeddedValueResolverAware
二、@Autowired和@PostConstruct注解失效
1、基础准备

2、失效情形

3、失效原因

4、使用Aware接口避免失效

5、总结 补充总结

一、Aware接口&InitializingBean

1、基础准备

  • ① 编写 MyBean 实现 BeanNameAware, ApplicationContextAware, InitializingBean 接口,并使用 @Autowired、@PostConstruct 注解,如下:

【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】_执行顺序

  • ② 编写测试类

注释掉AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor两个后处理器,如下:

【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】_初始化_02

【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】_执行顺序_03


2、总结

【A】、各类Aware及其作用:

Ⅰ BeanNameAware 注入 bean 的名字;
Ⅱ BeanFactoryAware 注入 BeanFactory 容器;
Ⅲ ApplicationContextAware 注入 ApplicationContext 容器;
Ⅳ EmbeddedValueResolverAware 解析 ${}。

【B】、为什么后处理器能实现的功能要通过Aware接口实现:

对比之下可以发现,原生干净的 GenericApplicationContext 容器并没有各类后处理器,需要我们手动添加才能实现拓展。
而实现这类接口,原生容器就能直接实现拓展。

3、补充:EmbeddedValueResolverAware

BeanFactoryAware与ApplicationContext类似,此处不演示。演示实现EmbeddedValueResolverAware接口,如下:

  • ① 让MyBean实现EmbeddedValueResolverAware接口

实现接口实现方法,并添加如下内容:

【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】_执行顺序_04

  • ② 修改测试类

【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】_执行顺序_05

【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】_初始化_06


二、@Autowired和@PostConstruct注解失效

1、基础准备

  • ① 编写MyConfig1类

【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】_执行顺序_07

  • ② 修改测试类

添加ConfigurationClassPostProcessor后处理器,注册MyConfig1,如下:

【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】_初始化_08

【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】_初始化_09


此时,我们可以看到@Autowired和@PostConstruct都生效了。

2、失效情形

  • ① 修改MyConfig1类

添加@Bean的相关内容,如下:

【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】_执行顺序_10

  • ② 测试

【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】_执行顺序_11


此时,后处理器拓展出来的注解都失效了。

3、失效原因

  • ① Java 配置类不包含 BeanFactoryPostProcessor 的情况

【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】_初始化_12


  • ② Java 配置类包含 BeanFactoryPostProcessor 的情况

案例中需要被执行的 BeanFactoryPostProcessor 在 MyConfig1 配置类中。为了保证 BeanFactoryPostProcessor 能顺利执行,此时会先创建和初始化 MyConfig1 对象。但是,注册 BeanPostProcessor 的步骤并没有执行到,所以 @Autowired 这类注解并没有生效。

【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】_测试类_13


为了证明如上顺序,我们继续测试。

  • ③ 测试不失效的情形来佐证

添加 MyConfig2 类,如下:

【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】_初始化_14

修改测试类,添加注册myConfig2,如下:


context.registerBean("myConfig2", MyConfig2.class);

【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】_初始化_15


可以看到由于 MyConfig2 类中没有 BeanFactoryPostProcessor 的调用需被执行,所以其中的 BeanPostProcessor 可以正常执行到。

  • ④ 结论

BeanFactoryPostProcessor 的执行顺序问题导致 BeanPostProcessor 相关配置失效。

4、使用Aware接口避免失效

  • ① 编写MyConfig3

实现InitializingBean、ApplicationContextAware接口,如下:

【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】_测试类_16

  • ② 修改测试类

添加注册myConfig3的内容,如下:


context.registerBean("myConfig3", MyConfig3.class);

【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】_执行顺序_17


5、总结

  • ① 尽量避免在调用BeanFactoryPostProcessor的Bean中使用BeanPostProcessor相关配置;
  • ② 如果无法避免两者在同一个Bean中均要用到的情形,则考虑实现Aware接口来实现BeanPostProcessor类似的功能。

补充总结:

  • ① AutowiredAnnotationBeanPostProcessor后处理器:解析 @Autowired、@Value 注解;
  • ② CommonAnnotationBeanPostProcessor后处理器:解析 @Resource、@PostConstruct、@PreDestroy 注解;
  • ③ ConfigurationClassPostProcessor后处理器:解析 @Component、ConfigurationProperties、@Import、@ImportSource 注解。


三、结尾

以上即为Aware接口&InitializingBean的全部内容


》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

接下来讲解:

Spring原理分析-初始化与销毁执行顺序

一、初始化执行顺序

1、基础准备

  • ① 编写Bean1

【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】_测试类_18

  • ② 编写启动类

【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】_测试类_19

  • ③ 测试

【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】_测试类_20


2、总结

@PostConstruct → InitializingBean#afterPropertiesSet → @Bean(initMethod = "")


二、销毁执行顺序

1、基础准备

  • ① 编写Bean2

【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】_初始化_21

  • ② 修改启动类

添加如下内容:

【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】_测试类_22

  • ③ 测试

【Spring原理分析-Aware接口&InitializingBean&初始化与销毁执行顺序】_执行顺序_23


2、总结

@PreDestroy → DisposableBean#destroy → @Bean(destroyMethod = "")


三、结尾

以上即为初始化与销毁执行顺序的全部内容,感谢阅读。




标签:InitializingBean,Spring,BeanFactoryPostProcessor,Aware,接口,注解,失效,处理器
From: https://blog.51cto.com/u_15874356/6168730

相关文章

  • SpringBoot中如何实现业务校验,这种方式才叫优雅!
    大家好,我是飘渺。在日常的接口开发中,为了保证接口的稳定安全,我们一般需要在接口逻辑中处理两种校验:参数校验业务规则校验首先我们先看看参数校验。参数校验参数校验很好理解,比如登录的时候需要校验用户名密码是否为空,创建用户的时候需要校验邮件、手机号码格式是否准确。......
  • 在IDEA创建SpringBoot项目没有src等文件夹
    问题在IDEA创建SpringBoot项目的时候,有时候创建完成了,但是没有src等文件夹,可能前几分钟还行,突然就不行了。原因可能是网络等问题,我也还没弄懂,或者哪位大神知道的,可以留言告知一下。解决办法办法一:自己手动创建办法二:通过网页创建,下载压缩包,再通过IDEA打开即可阿里云:https:/......
  • 创建SpringSecurity项目
    一.搭建SpringBoot开发环境我们的SpringSecurity系列教程会基于SpringBoot环境,并且以案例迭代的方式进行开发,所以为了方便后续案例的编写,我们先提前搭建一个SpringBoot环境的Web项目。1.创建SpringBoot项目如各位对SpringBoot基础不熟悉,请参考本人的SpringBoot系列教程:blo......
  • 2-SpringBoot开发单体应用
    SpringBoot开发单体应用1.SpringBootWeb开发使用SpringBoot的步骤:创建一个SpringBoot应用,选择我们需要的模块,SpringBoot就会默认将我们的需要的模块自动配置好;手动在配置文件中配置部分配置项目就可以运行起来了。专注编写业务代码,不需要考虑以前那样一大堆的配置......
  • SpringBoot 跨域 解决方案
    SpringBoot跨域看大部分文章都是通过WebMvcConfigurer来处理的,这样的话会导致其他配置紊乱发一下我常用的配置importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.web.cors.C......
  • SpringBoot之使用IDEA新建Web项目
    1.打开IDEA,点击左上角的File选项,打开菜单选择New,再打开菜单选择Project2.选择SpringInitializr,输入或选择项目相关的信息3.选择SpringBoot版本以及相应的依赖,并点击右下角的Create按钮进行项目创建4.项目创建完成后,点击左上角的File选项,打开菜单选择Settings选......
  • 记一次springboot通过jackson渲染到前端,出现大写字母变成小写问题
    前言最近业务部门接手了外包供应商的项目过来自己运维,该部门的小伙伴发现了一个问题,比如后端的DTO有个属性名为nPrice的字段,通过json渲染到前端后,变成nprice,而预期的字段是要为nPrice。于是他们就找到我们部门,希望我们能帮忙解决一下这个问题,本文就聊聊如何解决问题,至于为什么会......
  • Java SpringBoot Test 单元测试中包括多线程时,没跑完就结束了
    如何阻止JavaSpringBootTest单元测试中包括多线程时,没跑完就结束了使用CountDownLatchCountDownLatch、CyclicBarrier使用区别多线程ThreadPoolTaskExecutor应用JavaBasePooledObjectFactory对象池化技术@SpringBootTestpublicclassPoolTest{@Test......
  • SpringBoot外部化配置定时任务cron表达式
    SpringBoot外部化配置定时任务cron表达式背景在日常开发中我们经常会使用到定时任务的情况,SpringBoot为我们很方便的集成了定时任务。我们只需要简单的几部就可以配置好一个定时任务。@ComponentpublicclassLocationTask{@Scheduled(cron="0/10****?")pu......
  • Spring从熟悉到陌生
    BeanFactory与ApplicationContext的区别与联系在SpringBoot项目中我们通过SpringApplication.run(SpringLearnApplication.class,args);来启动项目,实际上这个方法有一个返回值,类型为ConfigurableApplicationContext,类图关系如下。可以看到它实现了ApplicationContext接口,而Ap......