一、Bean的加载顺序
spring容器载入bean顺序是不确定的,在一定的范围内bean的加载顺序可以控制。

spring容器载入bean虽然顺序不确定,但遵循一定的规则:

1、按照字母顺序加载(同一文件夹下按照字母数序;不同文件夹下,先按照文件夹命名的字母顺序加载)
2、不同的bean声明方式不同的加载时机,顺序总结:@ComponentScan > @Import > @Bean这里的ComponentScan指@ComponentScan及其子注解,Bean指的是@configuration + @bean同时需要注意的是:(1)Component及其子注解申明的bean是按照字母顺序加载的(2)@configuration + @bean是按照定义的顺序依次加载的(3)@import的顺序,就是bean的加载顺序(4)在xml中,通过<bean id="">方式声明的bean也是按照代码的编写顺序依次加载的(5)同一类中加载顺序:Constructor >> @Autowired >> @PostConstruct >> @Bean(6)同一类中加载顺序:静态变量 / 静态代码块 >> 构造代码块 >> 构造方法(需要特别注意的是静态代码块的执行并不是优先所有的bean加载,只是在同一个类中,静态代码块优先加载)

特别情况下,如果想手动控制部分bean的加载顺序,有如下方法:

方法1:构造方法依赖 (推荐)

@Component
public class CDemo1 {private String name = "cdemo 1";public CDemo1(CDemo2 cDemo2) {System.out.println(name);}
}
@Component
public class CDemo2 {private String name = "cdemo 2";public CDemo2() {System.out.println(name);}
}

CDemo2在CDemo1之前被初始化。

限制
要有注入关系,如:CDemo2通过构造方法注入到CDemo1中,若需要指定两个没有注入关系的bean之间优先级,则不太合适(比如我希望某个bean在所有其他的Bean初始化之前执行)

循环依赖问题,如过上面的CDemo2的构造方法有一个CDemo1参数,那么循环依赖产生,应用无法启动

另外一个需要注意的点是,在构造方法中,不应有复杂耗时的逻辑,会拖慢应用的启动时间

方法2:参数注入

在@Bean标注的方法上,如果你传入了参数,springboot会自动会为这个参数在spring上下文里寻找这个类型的引用。并先初始化这个类的实例。
利用此特性,我们也可以控制bean的加载顺序。


以上结果,beanB先于beanA被初始化加载。
需要注意的是,springboot会按类型去寻找。如果这个类型有多个实例被注册到spring上下文,那你就需要加上@Qualifier(“Bean的名称”)来指定

方法3:@DependsOn(“xxx”)
没有直接的依赖关系的,可以通过@DependsOn注解,我们可以在bean A上使用@DependsOn注解 ,告诉容器bean B应该优先被加载初始化。
不推荐的原因:这种方法是通过bean的名字(字符串)来控制顺序的,如果改了bean的类名,很可能就会忘记来改所有用到它的注解,那就问题大了。

当一个bean需要在另一个bean实例化之后再实例化时,可使用这个注解。

@Component("dependson02")
public class Dependson02 {Dependson02(){System.out.println(" dependson02 Success ");}
}
@Component
@DependsOn("dependson02")
public class Dependson01 {Dependson01(){System.out.println("Dependson01 success");}
}

执行结果:

结果:dependson02 Success
Dependson01 success

方法4:BeanDefinitionRegistryPostProcessor接口
通过实现BeanDefinitionRegistryPostProcessor接口,在postProcessBeanDefinitionRegistry方法中通过BeanDefinitionRegistry获取到所有bean的注册信息,将bean保存到LinkedHashMap中,并从BeanDefinitionRegistry中删除,然后将保存的bean定义排序后,重新再注册到BeanDefinitionRegistry中,即可实现bean加载顺序的控制。

/***配置类*/
@Configuration
@ComponentScan(basePackages = "demo")
public class AppConfig extends WebMvcConfigurationSupport {/*** 注册用于控制bean加载顺序的处理器* @return*/@Beanpublic static DemoProcessor demoProcessor() {return new DemoProcessor();}
}/****/
public class DemoProcessor implements BeanDefinitionRegistryPostProcessor{@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {}@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {String[] beanDefinitionNames = registry.getBeanDefinitionNames();int index = 0;//保留前n个关键bean的顺序for(;index<beanDefinitionNames.length;index++) {if(AppConfig.class.getName().equals(registry.getBeanDefinition(beanDefinitionNames[index]).getBeanClassName())) {break;}}Map<String, BeanDefinition> beans = new LinkedHashMap<>(beanDefinitionNames.length-index);for(;index<beanDefinitionNames.length;index++) {BeanDefinition beanDefinition = registry.getBeanDefinition(beanDefinitionNames[index]);beans.put(beanDefinitionNames[index], beanDefinition);registry.removeBeanDefinition(beanDefinitionNames[index]);}//TODO ...排序逻辑,注意beans中可能还包含有其他spring自身定义的beanList<String> orderdBeanNames = new ArrayList<>();//将排好序的bean再次注册到容器中orderdBeanNames.forEach(beanName->{registry.registerBeanDefinition(beanName, beans.get(beanName));});}
}

注意:

执行顺序:Constructor > @Autowired > @PostConstruct
所以正常情况下,所有的bean都已经执行了构造器Constructor,也就是bean都已经存在容器中了。
也就是正常情况下,都是可以正常执行了。
Autowired为null的情况如下:
(1)该类没有托管给spring 管理一般在类的上面添加@Component 就可以了
(2)不能new出来的实例,例如:A a = new A();//new的对象不会交给Spring容器管理, 所以是不行的特殊情况:@Configuration + @Bean 这种方式是可以的

二、Bean的执行顺序
注解@Order或者接口Ordered的作用是定义Spring IOC容器中Bean的执行顺序的优先级,而不是定义Bean的加载顺序,Bean的加载顺序不受@Order或Ordered接口的影响。


特别介绍
@PropertySource:用于注解类,告诉当前类使用什么配置文件,配置文件必须是.property或者.xml类型。

@PropertySource(value = {"classpath:config/user1.properties","classpath:config/user2.properties"})

@ImportResource:通过配置文件注入bean,用于注解主配置类,导入一个或多个定义bean的配置文件,配置文件必须是.xml类型。

@ImportResource(value = {"classpath:/beans.xml"})
@SpringBootApplication(scanBasePackages = {"team.seagull.client"})
public class DeployApplication {public static void main(String[] args) {SpringApplication.run(DeployApplication.class, args);}
}

Sprin中Bean的顺序相关推荐

  1. spring中bean初始化顺序

    spring bean 初始化的流程如下: 初始化顺序演示程序 pom文件 <project xmlns="http://maven.apache.org/POM/4.0.0" ...

  2. 如何正确控制springboot中bean的加载顺序总结

    1.为什么需要控制加载顺序 springboot遵从约定大于配置的原则,极大程度的解决了配置繁琐的问题.在此基础上,又提供了spi机制,用spring.factories可以完成一个小组件的自动装配功 ...

  3. java 中 bean 的生命周期

    java 中 bean 的生命周期 本篇中会对涉及到的知识点皆做出描述: 首先,我们先了解先虚拟机的类加载机制: 虚拟机把描述类的数据从Class 文件中加载到内存,并对数据进行校验.转换解析和初始化 ...

  4. Spring解析,加载及实例化Bean的顺序(零配置)

    点击上方蓝色"方志朋",选择"设为星标"回复"666"获取独家整理的学习资料! 作者:jb_hz blog.csdn.net/qq_2752 ...

  5. Spring Boot 学习系列(09)—自定义Bean的顺序加载

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. Bean 的顺序加载 有些场景中,我们希望编写的Bean能够按照指定的顺序进行加载.比如,有UserServ ...

  6. Spring 中 Bean 的生命周期

    本文作者: 伯乐在线 - yemengying 智商捉鸡?,实在没办法一下子理解Spring IoC和AOP的实现原理,看的闹心也不太懂,所以...决定拆成小的不能在小的一个个问题,一点点啃.今天先来 ...

  7. 厉害了,Spring中bean的12种定义方法!

    前言 在庞大的java体系中,spring有着举足轻重的地位,它给每位开发者带来了极大的便利和惊喜.我们都知道spring是创建和管理bean的工厂,它提供了多种定义bean的方式,能够满足我们日常工 ...

  8. 如果你每次面试前都要去背一篇Spring中Bean的生命周期,请看完这篇文章

    前言 当你准备去复习Spring中Bean的生命周期的时候,这个时候你开始上网找资料,很大概率会看到下面这张图: 先不论这张图上是否全面,但是就说这张图吧,你是不是背了又忘,忘了又背? 究其原因在于, ...

  9. spring bean生命周期_Spring中bean的生命周期和扩展点有哪些?

    前言 今天和大家分享一下Spring中Bean的生命周期的一些知识.先来说一下什么是生命周期吧,生命周期从其语义上理解就是一个对象从产生到销毁的整个过程,之所以把这个过程称为生命周期是因为其就像一个生 ...

最新文章

  1. 【 MATLAB 】序列的奇偶分解的 MATLAB 函数编写实践
  2. terminal怎么运行c语言文件,在mac电脑的terminal里该如何运行c语言
  3. Web自适应布局你需要知道的所有事儿
  4. 在微软工作一年,我学会了什么
  5. ZGrapher 画函数曲线图的工具
  6. thinking in java(第七章)
  7. 高性能MySQL(第2版)中文版pdf
  8. leetcode不同路径-结题( C++、Python、解析式)
  9. python脚本读书心得_《利用Python进行数据分析》读书笔记(一)Python Basic
  10. WebView load**方法 加载资源【总结】
  11. 推荐5款优质的黑科技软件,好不好用你来判断
  12. Java中将将JPG图片转GIF动画和将GIF转JPG图片
  13. html5饼图的制作方法,excel2010复合饼图制作方法
  14. 搭建本地以图搜图服务
  15. 我们仍处于本轮牛市之中
  16. 大型游戏行业网络技术解决方案
  17. 对角矩阵的性质(diagonal matrix)
  18. 4月3日工作总结及次日计划
  19. CAD-VB多段线、波浪线、射线、构造线
  20. 2023最新短视频解析接口

热门文章

  1. CMIIT ID是什么意思
  2. opencv usb镜头帧率低 图像卡顿
  3. 有小孩的30多岁的程序员,过完年是继续在深圳还是回老家省会城市?
  4. 人工智能 人工智能一种_人工超级智能的最疯狂后果
  5. 一个爬虫代码价值 7000 万!
  6. Ubuntu卡在开机[failed]Started GNOME Display Manager 出现failed to start see systemctl status gdm.service
  7. 元宇宙游戏:新瓶换新酒
  8. 百度地图怎么添加公司地址标注
  9. SAP MRP元素代码、描述、缩写及元素说明(中文)
  10. 计算机仿真还给稿费,国内期刊不需要审稿费和版面费汇总