软件编程
位置:首页>> 软件编程>> java编程>> springboot中bean的加载顺序问题

springboot中bean的加载顺序问题

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

标签:springboot,bean,加载顺序

一、为什么要控制

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

你会声明自己的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

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com