springboot中bean的加载顺序问题

作者:华妃 时间:2022-01-04 19:55:57 

一、为什么要控制

当你在项目启动时需要提前做一个业务的初始化工作时,或者你正在开发某个中间件需要完成自动装配时。

你会声明自己的Configuration类,但是可能你面对的是好几个有互相依赖的Bean。

如果不加以控制,这时候可能会报找不到依赖的错误,这个时候需要通过一些手段来控制springboot中的bean加载顺序。

二、怎么控制

@DependsOn

@DependsOn注解可以用来控制bean的创建顺序,该注解用于声明当前bean依赖于另外一个bean。

所依赖的bean会被容器确保在当前bean实例化之前被实例化。

与@Component或@Bean配合使用 

demo

@Slf4j
@Configuration
@ConfigurationProperties(prefix = "dict")
public class SpringConfig {
   @Component(value = "EventSource")
   public class EventSource {
       public EventSource(){
           System.out.println("事件源创建");
       }
   }
   /**
    * 监听类
    */
   @Component
   @DependsOn(value = {"EventSource"})
   public class EventTListener {
       public EventTListener(){
           System.out.println(" * 创建");
       }
   }
}

springboot中bean的加载顺序问题

参数注入

package com.sinosoft.springbootplus.test.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
/**
* @author lsh
* @date 2022/2/25
*/
@Slf4j
@Configuration
@ConfigurationProperties(prefix = "dict")
public class SpringConfig {
   @Component
   public class Event{
       public Event(){
           System.out.println("事件事件");
       }
   }
   @Component
   public class EventSource{
       public EventSource(Event e){
           System.out.println("事件源创建");
       }
   }
   @Component
   public class EventTListener {
       public EventTListener(){
           System.out.println(" * 创建");
       }
   }
}

springboot中bean的加载顺序问题

利用bean的生命周期中的扩展点

@AutoConfigureOrder

@AutoConfigureOrder只能改变外部依赖的@Configuration的顺序。

这是不对的用法

@Slf4j
@Configuration
@ConfigurationProperties(prefix = "dict")
public class SpringConfig {
   @Component
   @AutoConfigureOrder(1)
   public class Event{
       public Event(){
           System.out.println("事件事件");
       }
   }
   @Component
   @AutoConfigureOrder(2)
   public class EventSource{
       public EventSource(Event e){
           System.out.println("事件源创建");
       }
   }
   @Component
   @AutoConfigureOrder(3)
   public class EventTListener {
       public EventTListener(){
           System.out.println(" * 创建");
       }
   }
}

springboot中bean的加载顺序问题

以上内容发现,在config里配置是不起作用的。

这是正确的用法

创建两个配置类

@Slf4j
@Configuration
@AutoConfigureOrder(1)
public class SpringConfig {
   @Component
   public class Event{
       public Event(){
           System.out.println("首先在SpringConfig");
       }
   }
}
@Slf4j
@Configuration
@AutoConfigureOrder(2)
public class NewConfig {
   @Component
   public class Event{
       public Event(){
           System.out.println("然后在NewConfig");
       }
   }
}

测试

springboot中bean的加载顺序问题

发现结果是不正确的,注解还是没有生效。

当前工程里增加配置 META-INF/spring.factories,内容为项目中的配置类

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.sinosoft.springbootplus.common.config.NewConfig,com.sinosoft.springbootplus.common.config.SpringConfig

测试结果如图(正确)

springboot中bean的加载顺序问题

三、遇到的问题

需要根据配置决定生成哪个实现类

springboot中bean的加载顺序问题

当在配置文件中配置的dict.cacheType的值是local时,初始化LocalISysDictRepository交给spring容器管理;

当项目依赖了redis并且配置文件中配置的dict.cacheType的值是redis时,初始化RedisISysDictRepository交给spring容器管理。

但是我又在这两个实现类上加了@Repository注解

也要交给Spring管理,这个时候项目启动就报错了。(通俗的来说一个类只能一次交给Spring管理)

springboot中bean的加载顺序问题

来源:https://blog.csdn.net/weixin_44792849/article/details/123116593

标签:springboot,bean,加载顺序
0
投稿

猜你喜欢

  • Android实现ImageView阴影和图层效果

    2021-12-20 06:02:00
  • Jackson库中objectMapper的用法

    2023-10-25 13:20:40
  • Java 面试题和答案 -(上)

    2023-10-08 08:15:56
  • java数据结构与算法之noDups去除重复项算法示例

    2023-06-19 08:50:34
  • 详解Java异常处理中finally子句的运用

    2023-11-29 10:10:30
  • Android SharedPreferences实现记住密码和自动登录界面

    2023-06-15 20:07:00
  • JDK常用命令jps jinfo jstat的具体说明与示例

    2021-08-09 16:03:30
  • Jetpack navigation组件超详细讲解

    2021-07-17 08:49:58
  • java实现简单的俄罗斯方块

    2021-08-02 18:13:11
  • Java ShutdownHook原理详解

    2023-11-10 21:30:36
  • 使用注解@Recover优化丑陋的循环详解

    2021-08-05 15:11:13
  • 详解C# WinForm如何实现自动更新程序

    2022-03-04 02:19:29
  • idea快速搭建spring cloud注册中心与注册的方法

    2023-03-09 17:40:35
  • Android Studio使用Kotlin时,修改代码后运行不生效的解决方法

    2022-08-05 11:29:04
  • Android中在GridView网格视图上实现item拖拽交换的方法

    2022-07-13 01:26:04
  • C#中+=是什么意思及+=的用法

    2023-07-11 23:25:31
  • SpringData如何通过@Query注解支持JPA语句和原生SQL语句

    2022-08-26 22:07:29
  • 简介Winform中创建用户控件

    2021-10-14 04:39:37
  • mybatis sum(参数) 列名作为参数的问题

    2022-06-16 01:45:44
  • C#使用Redis的基本操作

    2023-12-03 11:03:51
  • asp之家 软件编程 m.aspxhome.com