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

目录
  • 背景介绍
  • 实现方法
    • DependsOn注解
    • ApplicationContextInitializer
  • 简单Demo

背景介绍

在一些需求中,可能存在某些场景,比如先加载自己的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优先加载内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot bean查询加载顺序流程详解

    目录 背景 探索-源码 进一步思考 背景 SpringBoot bean 加载顺序如何查看,想看加载了哪些bean, 这些bean的加载顺序是什么? 实际加载顺序不受控制,但会有一些大的原则: 1.按照字母顺序加载(同一文件夹下按照字母数序:不同文件夹下,先按照文件夹命名的字母顺序加载)2.不同的bean声明方式不同的加载时机,顺序总结:@ComponentScan > @Import > @Bean   这里的ComponentScan指@ComponentScan及其子注解,Bean指的是

  • SpringBoot Bean花式注解方法示例下篇

    目录 1.容器初始化完成后注入bean 2.导入源的编程式处理 3.bean裁定 拓展 4.最终裁定 1.容器初始化完成后注入bean import lombok.Data; import org.springframework.stereotype.Component; @Component("miao") @Data public class Cat { } 被注入的JavaBean import org.springframework.context.annotation.Con

  • SpringBoot Bean被加载时进行控制

    目录 序章 加载控制@Conditional派生注解 这是我未加控制前的代码 控制后 bean依赖的属性配置 序章 简介:bean的加载控制指根据特定情况对bean进行选择性加载以达到适用项目的目标. 根据之前对bean加载的八种方式,其中后面四种是可以对bean被加载时进行控制. 我拿第六种来举个例子. 之前也举过例子,但是实际开发呢,一般不会那么使用. import org.springframework.context.annotation.ImportSelector; import o

  • SpringBoot自定义bean绑定实现

    目录 自定义bean绑定 导入第三方bean 第三方bea通过配置文件注参数 出现Prefix must be in canonical form @EnableConfigurationProperties()和@ConfigurationProperties的区别 解除@ConfigurationProperties注解警告 @ConfigurationProperties的松散绑定 自定义bean绑定 在配置文件中写入 servers: ipAddress: 192.158.0.1 por

  • SpringBoot Bean花式注解方法示例上篇

    目录 1.XML方式声明 2.注解法@Component 3.完全注解式 4.简化注解@Import 1.XML方式声明 这里我举两个例子,一个是自定义的bean,另一个是第三方bean,这样会全面一些. 你还可以定义这个bean的模式,有单例模式和多例模式,prototype代表多例,singleton代表单例. <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://ww

  • 详解Spring中Bean的加载的方法

    之前写过bean的解析,这篇来讲讲bean的加载,加载要比bean的解析复杂些,从之前的例子开始. Spring中加载一个bean的方式: TestBean bean = factory.getBean("testBean"); 来看看getBean(String name)方法源码, @Override public Object getBean(String name) throws BeansException { return doGetBean(name, null, nul

  • 如何正确控制springboot中bean的加载顺序小结篇

    1.为什么需要控制加载顺序 springboot遵从约定大于配置的原则,极大程度的解决了配置繁琐的问题.在此基础上,又提供了spi机制,用spring.factories可以完成一个小组件的自动装配功能. 在一般业务场景,可能你不大关心一个bean是如何被注册进spring容器的.只需要把需要注册进容器的bean声明为@Component即可,spring会自动扫描到这个Bean完成初始化并加载到spring上下文容器. 而当你在项目启动时需要提前做一个业务的初始化工作时,或者你正在开发某个中间

  • 在springboot中实现个别bean懒加载的操作

    懒加载---就是我们在spring容器启动的是先不把所有的bean都加载到spring的容器中去,而是在当需要用的时候,才把这个对象实例化到容器中. @Lazy 在需要懒加载的bean上加上@Lazy就可以了 补充知识:springboot组件懒加载的坑及加载规则 什么是懒加载? 懒加载的意思是不在项目启动的时候实例出来这个组件 @RestController public class ApiController { @Autowired Skill kobSkillImpl; @Request

  • Spring中Bean的加载与SpringBoot的初始化流程详解

    目录 前言 第一章 Spring中Bean的一些简单概念 1.1 SpingIOC简介 1.2 BeanFactory 1.2.1 BeanDefinition 1.2.2 BeanDefinitionRegistry 1.2.3 BeanFactory结构图 1.3 ApplicationContext 第二章 SpringBoot的初始化流程 2.1 准备阶段 2.2 运行阶段 2.2.1 监听器分析 2.2.2 refreshContext 2.3 总结 前言 一直对它们之间的关系感到好奇

  • springboot中的静态资源加载顺序优先级

    目录 springboot静态资源加载顺序优先级 看springboot源码里面 springboot静态资源加载规则 一.静态资源映射规则 1.webjars 2.springboot内置默认访问路径 3.首页处理 4.网站图标 springboot静态资源加载顺序优先级 看springboot源码里面 springboot静态资源加载规则 我们经常会使用springboot创建web应用,在springboot中金静态资源是如何存放的呢? 一.静态资源映射规则 我们先创建一个springbo

  • 详解Spring简单容器中的Bean基本加载过程

    本篇将对定义在 XMl 文件中的 bean,从静态的的定义到变成可以使用的对象的过程,即 bean 的加载和获取的过程进行一个整体的了解,不去深究,点到为止,只求对 Spring IOC 的实现过程有一个整体的感知,具体实现细节留到后面用针对性的篇章进行讲解. 首先我们来引入一个 Spring 入门使用示例,假设我们现在定义了一个类 org.zhenchao.framework.MyBean ,我们希望利用 Spring 来管理类对象,这里我们利用 Spring 经典的 XMl 配置文件形式进行

  • Springboot常用注解及配置文件加载顺序详解

    Springboot常用注解及底层实现 1.@SpringBootApplication:这个注解标识了一个SpringBoot工程,她实际上是另外三个注解的组合,分别是: @SpringBootConfiguration:源码可以看到,这个注解除了元注解外,实际就只有一个@Configuration,把该类变成一个配置类,表示启动类也是一个配置类: @EnableAutoConfiguration:是开启自动配置的功能,向Spring容器中导入了一个Selector,用来加载ClassPath

  • SpringBoot使用Shiro实现动态加载权限详解流程

    目录 一.序章 二.SpringBoot集成Shiro 1.引入相关maven依赖 2.自定义Realm 3.Shiro配置类 三.shiro动态加载权限处理方法 四.shiro中自定义角色与权限过滤器 1.自定义uri权限过滤器 zqPerms 2.自定义角色权限过滤器 zqRoles 3.自定义token过滤器 五.项目中会用到的一些工具类常量等 1.Shiro工具类 2.Redis常量类 3.Spring上下文工具类 六.案例demo源码 一.序章 基本环境 spring-boot 2.1

随机推荐