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(" * 创建");
}
}
}
参数注入
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(" * 创建");
}
}
}
利用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(" * 创建");
}
}
}
以上内容发现,在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");
}
}
}
测试
发现结果是不正确的,注解还是没有生效。
当前工程里增加配置 META-INF/spring.factories,内容为项目中的配置类
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.sinosoft.springbootplus.common.config.NewConfig,com.sinosoft.springbootplus.common.config.SpringConfig
测试结果如图(正确)
三、遇到的问题
需要根据配置决定生成哪个实现类
当在配置文件中配置的dict.cacheType的值是local时,初始化LocalISysDictRepository交给spring容器管理;
当项目依赖了redis并且配置文件中配置的dict.cacheType的值是redis时,初始化RedisISysDictRepository交给spring容器管理。
但是我又在这两个实现类上加了@Repository注解
也要交给Spring管理,这个时候项目启动就报错了。(通俗的来说一个类只能一次交给Spring管理)
来源:https://blog.csdn.net/weixin_44792849/article/details/123116593


猜你喜欢
- MyBatis框架提供了二级缓存接口,我们只需要实现它再开启配置就可以使用了。特别注意,我们要解决缓存穿透、缓存穿透和缓存雪崩的问题,同时也
- webview是一个很简单的功能,代码没有什么逻辑上的难度,只是需要注意权限上的问题。其实在安卓编程的过程当中,权限问题可以算是出现的比较多
- 先来看一个名为Message的类在这个类中有一段包含在companion object中的代码,需要说一下的是,Kotlin的cl
- Socket异常客户端异常java.net.ConnectException: Connection refused: connect。该异
- Zxing是Google提供的关于条码(一维码、二维码)的解析工具,提供了二维码的生成与解析的方法,现在我简单介绍一下使用Java利用Zxi
- java jpa自定义sql语句本篇只是为了再次记录自己又学习了jpa的使用,框架原生的通过解析方法名多适用于单表操作,自定义的sql查询则
- Swing 程序用JFrame 对象实现了它们的窗口。JFrame 类是AWT Frame 类的一个子类。它还加入了一些Swing 所独有的
- 一、XML DOM概述XML 文档大小写敏感、属性用引号括起来,每一个标记都要闭合。DOM是XML文档的内存中树状的表示形式。继承关系图:X
- 先来看看效果:测试一:原图:效果图:测试二:原图:效果图:代码部分:/** * */ package com.b510; import ja
- 需求:List<UserPojo> users = new ArrayList<>();//第一个user和第4个u
- 利用栈实现一个简易计算器(Java实现),供大家参考,具体内容如下一、思路分析当我们输入一个类似于“7*2+100-5+
- Dubbo的扩展点加载从JDK标准的SPI(Service Provider Interface)扩展点发现机制加强而来。Dubbo改进了J
- VideoView介绍之前介绍过使用MediaPlayer+SurfaceView实现播放视频功能。无意间发现官方封装了VideoView组
- java中引用数据类型有哪些Java中有俩种数据类型,其中主要有8中基本数据类型和引用数据类型,除了8中基本数据类型以外都是引用数据类型,8
- 今年新开Java课程第一步就是…配置环境就从Java的环境配置开始好了以下是正式的步骤首先,从Oracle的官网下载jdk的安装包点我下载J
- Parallel类是对线程的抽象,提供数据与任务的并行性。类定义了静态方法For和ForEach,使用多个任务来完成多个作业。Paralle
- 一、this关键字this是一个引用,它指向自身的这个对象。看内存分析图:假设我们在堆内存new了一个对象,在这个对象里面你想象着他有一个引
- 适配器(Adapter)模式:适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一
- 1.例题题目描述迷宫由 n 行 m 列的单元格组成,每个单元格要么是空地,要么是障碍物。其中1表示空地,可以走通,2表示障碍物。给定起点坐标
- 线程池中ThreadGroup的坑在Java中每一个线程都归属于某个线程组管理的一员,例如在主函数main()主工作流程中产生一个线程,则产