Spring中@order注解用法实战教程_第1页
Spring中@order注解用法实战教程_第2页
Spring中@order注解用法实战教程_第3页
Spring中@order注解用法实战教程_第4页
Spring中@order注解用法实战教程_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第Spring中@order注解用法实战教程目录前言一、观察@order源码二、@order实战三、@order失效原因四、解决排序问题五、排序源码分析六、@AutoConfigureOrder总结

前言

@order注解是spring-core包下的一个注解,@Order的作用是定义SpringIOC容器中Bean的执行顺序的优先级(这里的顺序也可以理解为存放到容器中的先后顺序)。开发过程当中有时候经常会出现配置依赖关系,例如注入A对象使用了

@ConditionalOnBean(B.class),意思是要求容器当中必须存在B.class的实例的时候,才会进行注入A。这时候我们就必须保证B对象在注入A对象前进行注入。

一、观察@order源码

(1)源码当中有三个元注解:

@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD}):使用范围接口、类、枚举、注解、方法、字段@Retention(RetentionPolicy.RUNTIME):@Retention是用来修饰注解的生命周期的,RetentionPolicy.RUNTIME代表的是不仅被保存到class文件中,jvm加载class文件之后,仍然存在;一直有效!@Documented:@Documented和@Deprecated注解长得有点像,@Deprecated是用来标注某个类或者方法不建议再继续使用,@Documented只能用在注解上,如果一个注解@B,被@Documented标注,那么被@B修饰的类,生成Javadoc文档时,会显示@B。

(2)属性:

@order当中只要一个value属性,而且还是int类型,值越低优先级越高,默认值是Ordered.LOWEST_PRECEDENCE,表示最低优先级(输给任何其他指定的顺序值)。

@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})

@Documented

public@interfaceOrder{

intvalue()default2147483647;

官网注释:/spring-projects/spring-framework/blob/main/spring-core/src/main/java/org/springframework/core/annotation/Order.java

二、@order实战

(1)自定义两个配置类

我们要求Config2先进行加载,然后通过@order来排序测试一下

@Configuration

publicclassConfig1{

publicConfig1(){

System.out.println("Config1构建了");

@Configuration

publicclassConfig2{

publicConfig2(){

System.out.println("Config2构建了");

(2)启动项目测试:默认是先创建的Config1后创建的Config2

(3)既然order可以控制加载顺序,那我们来试验一下,然后让Config2先加载

@Configuration

@Order(2)

publicclassConfig1{

publicConfig1(){

System.out.println("Config1构建了");

@Configuration

@Order(1)

publicclassConfig2{

publicConfig2(){

System.out.println("Config2构建了");

但是好像没什么卵用

(4)分析原因

目前这两个是在同包情况下不起作用。

于是进行分开了

分开之后竟然生效了

(5)但是分开也是将Config2放到了上面的包当中,于是我又改成了Config1放到最上面,这样进行测试,结果又失效了

(6)于是我又放在了同包下,将Config2命名为A开头的,这样他就放到了最上面,于是这样同样也生效了。

期间我还尝试着将@Configuration都改为使用@Component,结果仍然不变。

得出结论:@order指定加载顺序还跟类的命名和存放位置有关!假如有Config1和Config2两个类在一个包下,要求是Config2先加载:

这时候设置Config2的@order值就算是小于Config1的@order值同样也是Config1先加载。如果同包情况下可以重新命名Config2,只要在Config1上面就行。或者拆开不同包也可以,但是Config2所在的包也必须比Config1所呆的包上面。

这样才能保证@Order生效!

三、@order失效原因

https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-constructor-injection

最关键的一句话:您可以在目标类级别和@Bean方法上声明@Order注释,可能针对的是单个bean定义(如果多个定义使用同一个bean类)。@Order值可能会影响注入点的优先级,但请注意,它们不会影响单例启动顺序,这是由依赖关系和@DependsOn声明确定的正交关注。

我理解的注入点的优先级应该是指的存放容器的先后顺序,也就是他并不会影响启动顺序。

四、解决排序问题

我们不可能每次遇到这种问题又是改名又是换包的,所以,springboot提供了如下三个注解可以控制顺序:

@AutoConfigureAfter:当前配置类在指定配置类之后执行@AutoConfigureBefore:当前配置类在指定配置类之前执行@AutoConfigureOrder:指定优先级,数值越小,优先级越高。

(1)首先将代码改回原来的样子

(2)在Config2使用@AutoConfigureBefore(Config1.class),代表的是在config1加载前进行加载

@Configuration

publicclassConfig1{

publicConfig1(){

System.out.println("Config1构建了");

@Configuration

@AutoConfigureBefore(Config1.class)

publicclassConfig2{

publicConfig2(){

System.out.println("Config2构建了");

(3)输出结果,显然还是没生效

可能有时候走了运给你一种错觉还真的配置成功了。实际上这种方式是不可行的,以上三个注解只有针对自动配置类才会生效。

在autoconfigure包下就有spring.factories,这个文件配置了自动配置类,springboot会读取这个文件的,我们也可以在自己项目上定义spring.factories,这样我们的配置类对于@AutoConfigureAfter注解就可以生效了。

(4)自定义spring.factories

第一行是固定的,后面的就是全类名,虽然只有Config2使用了注解,但是需求是和Config1进行排序,所以这两个都得加。

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\

.springbootcache.config.Config2,\

.springbootcache.config.Config1

(5)测试,成功解决

五、排序源码分析

针对于@AutoConfigure那三个注解原理:其实关键的代码还是在AutoConfigurationImportSelector中,将自动配置类从spring.factories加载出来之后会根据条件排序(只有自动配置类!),在selectImports()方法中最后一行代码如下:

紧接着会走到这个地方,实际上是分了三步排序:

先按照文件名字母排序按照@AutoConfigureOrder进行排序按照@AutoConfigureBefore和@AutoConfigureAfter排序

从上面配置的顺序可以知道,最终决定权还是在@AutoConfigureAfter、@AutoConfigureBefore这两个注解。

当我们不设置spring.factories的时候,这里面压根都没有这两个类!

六、@AutoConfigureOrder

这种也是可以的!当然前提也是需要配置spring.factories

@Configuration

@AutoConfigureOrder(

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论