SpringBoot选择自有bean优先加载实现方法

 更新时间:2023年03月14日 08:29:46   作者:amcomputer  
在一些需求中,可能存在某些场景,比如先加载自己的bean,然后自己的bean做一些DB操作,初始化配置问题,然后后面的bean基于这个配置文件,继续做其他的业务逻辑。因此有了本文的这个题目

背景介绍

在一些需求中,可能存在某些场景,比如先加载自己的bean,然后自己的bean做一些DB操作,初始化配置问题,然后后面的bean基于这个配置文件,继续做其他的业务逻辑。因此有了本文的这个题目。

实现方法

DependsOn注解

这个@DependsOn网上实现方法很多,依赖的bean数目较少的话,比较好弄,但数目变多后,就比较麻烦了,每个类都需要重新写一遍,因此推荐第二种方法。

ApplicationContextInitializer

通过注册 ApplicationContextInitializer 后,就可以注册 BeanDefinitionRegistryPostProcessor 到 Spring里面。最后实现 BeanDefinitionRegistryPostProcessor ,注册目标 bean。

 class DemoApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
  @Override
  public void initialize(ConfigurableApplicationContext applicationContext) {
      applicationContext.addBeanFactoryPostProcessor(new DemoBeanDefinitionRegistryPostProcessor());
  }
}

实现 BeanDefinitionRegistryPostProcessor:

public class DemoBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
  // from BeanDefinitionRegistryPostProcessor interface
  @Override
  public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
// 重点在这里,这里可以把自己的 想要提起 实现的 或者初始化的 bean  加到这里
beanDefinitionRegistry.registerBeanDefinition("DemoService",new RootBeanDefinition(DemoService.class));
  }
  // from BeanDefinitionRegistryPostProcessor interface
  @Override
  public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
  }
// from PriorityOrdered  interface
  @Override
  public int getOrder() {
  // 排在 ConfigurationClassPostProcessor 之前即可
      return Ordered.LOWEST_PRECEDENCE - 1;
  }
}

这里需要注意的是,不能使用 @Componet 或者其他的注解进行注册 BeanDefinitionRegistryPostProcessor。

因为@Componet 注解方式能注册的前提是 被 ConfigurationClassPostProcessor 扫描到,而现在,我们需要考虑我们的bean注册,要在这些bean之前,所以一定不能被“它-ConfigurationClassPostProcessor”管理 。 换一个角度思考,如果被 “它” 管理类 注册出来的bean 一定不可能排在 ConfigurationClassPostProcessor 的前面。

注意:@Order 这个只能控制 spring 自身 bean的顺序,对于 @Service @Component 、@Repository这些注解是不能控制的。

简单Demo

需求:笔者想让TestService 提前被注册,并且执行后,其他bean 才能被注册。

public class TestService {
    // 存放系统配置
    private static Map<String, String> GLOBAL_CONF = new HashMap<>();
    @PostConstruct
    public void init() {
        // 先做初始化 GLOBAL_CONF 或者其他 IO操作
        // GLOBAL_CONF.put(key, value);
    }
    //其他 bean 通过这个方法获得系统配置
    public static String getGlobalConfig(String key) {
        return GLOBAL_CONF.get(key);
    }
}

实现:(为了简单,直接实现上述的3个接口)

public class DemoBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor, 
PriorityOrdered, 
ApplicationContextInitializer<ConfigurableApplicationContext> {
    /**
     *  第二步: 注册 自己的 bean
     *
     * @param beanDefinitionRegistry
     */
    // from BeanDefinitionRegistryPostProcessor interface
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        beanDefinitionRegistry.registerBeanDefinition("TestService",new RootBeanDefinition(TestService.class));
    }
    // from BeanDefinitionRegistryPostProcessor interface
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
    }
// from PriorityOrdered  interface
    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE - 1;
    }
    /**
     *  第一步 先注册 到 configurableApplicationContext 中
     *
     * @param configurableApplicationContext
     */
    // from ApplicationContextInitializer  interface
    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
        configurableApplicationContext.addBeanFactoryPostProcessor(new DemoBeanDefinitionRegistryPostProcessor());
    }
}

思考: 那如何得到 或者 看到 spring bean 加载的顺序呢?

下一篇

到此这篇关于SpringBoot选择自有bean优先加载实现方法的文章就介绍到这了,更多相关SpringBoot bean优先加载内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 解析Java中的队列和用LinkedList集合模拟队列的方法

    解析Java中的队列和用LinkedList集合模拟队列的方法

    这篇文章主要介绍了解析Java中的队列和用LinkedList集合模拟队列的方法,相关算法的实现也是ACM中的常见题目,需要的朋友可以参考下
    2015-08-08
  • SpringBoot+Vue项目新手快速入门指南

    SpringBoot+Vue项目新手快速入门指南

    最近刚刚做了一个基于vue+springboot的系统,于是基于这点,对遇到的一些问题进行一些配置的汇总,下面这篇文章主要给大家介绍了关于SpringBoot+Vue项目新手快速入门的相关资料,需要的朋友可以参考下
    2022-06-06
  • Java SE判断两个文件内容是否相同的多种方法代码

    Java SE判断两个文件内容是否相同的多种方法代码

    昨天因为要帮师兄的忙所以看了一下如何判断两个文件内容是否相同,这里给大家总结下,这篇文章主要给大家介绍了关于Java SE判断两个文件内容是否相同的多种方法,需要的朋友可以参考下
    2023-11-11
  • Spring注解方式无法扫描Service注解的解决

    Spring注解方式无法扫描Service注解的解决

    这篇文章主要介绍了Spring注解方式无法扫描Service注解的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • Java Calendar类的详解及使用实例

    Java Calendar类的详解及使用实例

    这篇文章主要介绍了Java Calendar类的详解及使用实例的相关资料,需要的朋友可以参考下
    2017-04-04
  • java中Collections.sort排序详解

    java中Collections.sort排序详解

    这篇文章主要介绍了java中Collections.sort排序详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • 关于通过java调用datax,返回任务执行的方法

    关于通过java调用datax,返回任务执行的方法

    今天小编就为大家分享一篇关于通过java调用datax,返回任务执行的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-08-08
  • 在Eclipse中更改maven项目名的方法

    在Eclipse中更改maven项目名的方法

    今天小编就为大家分享一篇关于在Eclipse中更改maven项目名的方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • SpringBoot中属性赋值操作的实现

    SpringBoot中属性赋值操作的实现

    这篇文章主要介绍了SpringBoot中属性赋值操作的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • springboot实现邮箱验证码功能

    springboot实现邮箱验证码功能

    这篇文章主要为大家详细介绍了springboot实现邮箱验证码功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-02-02

最新评论