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(" * 创建");
}
}
}
参数注入
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
标签: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