当前位置: 首页> 科技> 能源 > SpringBoot之@AutoConfigureBefore、@AutoConfigureAfter、@AutoConfigureOrder注解

SpringBoot之@AutoConfigureBefore、@AutoConfigureAfter、@AutoConfigureOrder注解

时间:2025/7/21 11:31:07来源:https://blog.csdn.net/qq_38257958/article/details/139225668 浏览次数:0次

前言

SpringBoot通过@AutoConfigureOrder、@AutoConfigureBefore、@AutoConfigureAfter注解,控制自动配置类的实例化顺序。

Spring中控制Bean的实例化顺序

Spring中默认实例化顺序

创建实体类A、B、C
@Component
public class A {public A() {System.out.println("A construct");}
}@Component
public class B {public B() {System.out.println("B construct");}
}@Component
public class C {public C() {System.out.println("C construct");}
}
启动SpringBoot

实例化顺序: A > B > C

Spring中指定实例化顺序(C > B > A)

修改实体类A、B、C
@Component
@DependsOn("b")
public class A {public A() {System.out.println("A construct");}
}@Component
@DependsOn("c")
public class B {public B() {System.out.println("B construct");}
}@Component
public class C {public C() {System.out.println("C construct");}
}
启动SpringBoot

实例化顺序: C > B > A

SpringBoot中控制自动配置类的实例化顺序

SpringBoot中默认实例化顺序

在 resources 文件夹下创建 META-INF 文件夹,在 META-INF 文件夹下创建 spring.factories 文件,整体结构如下:

spring.factories 明细如下:

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.ys.boot.auto.D,\
com.ys.boot.auto.E,\
com.ys.boot.auto.F
创建实体类D、E、F
public class D {public D() {System.out.println("D construct");}
}public class E {public E() {System.out.println("E construct");}
}public class F {public F() {System.out.println("F construct");}
}
启动SpringBoot

实例化顺序: D > E > F

使用@DependsOn解决实例化顺序?

修改实体类D、E、F
@DependsOn("e")
public class D {public D() {System.out.println("D construct");}
}@DependsOn("f")
public class E {public E() {System.out.println("E construct");}
}public class F {public F() {System.out.println("F construct");}
}
启动SpringBoot

抛出 org.springframework.beans.factory.NoSuchBeanDefinitionException 

异常原因 : 一般情况下,自动配置的类都不是当前项目的文件,即Spring不会将相关文件扫描成BeanDefinition对象。当我们使用@DependsOn注解的时候,Spring就尝从当前环境中查找或实例化指定名称的Bean,因为找不到相关BeanDefinition对象,所以抛出异常。

SpringBoot中指定实例化顺序(方式一)

修改实体类D、E、F
@AutoConfigureOrder(3)
public class D {public D() {System.out.println("D construct");}
}@AutoConfigureOrder(2)
public class E {public E() {System.out.println("E construct");}
}@AutoConfigureOrder(1)
public class F {public F() {System.out.println("F construct");}
}
启动SpringBoot

实例化顺序: F > E > D

SpringBoot中指定实例化顺序(方式二)

修改实体类D、E、F
@AutoConfigureAfter(E.class)
public class D {public D() {System.out.println("D construct");}
}@AutoConfigureAfter(F.class)
public class E {public E() {System.out.println("E construct");}
}public class F {public F() {System.out.println("F construct");}
}
启动SpringBoot

实例化顺序: F > E > D

源码简析

AutoConfigurationSorter#getInPriorityOrder

List<String> getInPriorityOrder(Collection<String> classNames) {AutoConfigurationSorter.AutoConfigurationClasses classes = new AutoConfigurationSorter.AutoConfigurationClasses(this.metadataReaderFactory,this.autoConfigurationMetadata, classNames);List<String> orderedClassNames = new ArrayList<>(classNames);// 最初按字母顺序排序Collections.sort(orderedClassNames);// 根据@AutoConfigureOrder的order值排序,值越小,优先级越高orderedClassNames.sort((o1, o2) -> {int i1 = classes.get(o1).getOrder();int i2 = classes.get(o2).getOrder();return Integer.compare(i1, i2);});// 根据@AutoConfigureBefore、@AutoConfigureAfter注解指定的顺序排序orderedClassNames = sortByAnnotation(classes, orderedClassNames);return orderedClassNames;
}

排序优先级 : 

  1. 根据@AutoConfigureBefore、@AutoConfigureAfter注解指定的顺序排序
  2. 根据@AutoConfigureOrder的order值排序
  3. 按字母顺序排序

@AutoConfigureBefore、@AutoConfigureAfter配置不当可能会抛出异常,案例演示如下:

@AutoConfigureAfter(E.class)
public class D {public D() {System.out.println("D construct");}
}@AutoConfigureAfter(F.class)
public class E {public E() {System.out.println("E construct");}
}@AutoConfigureAfter(D.class)
public class F {public F() {System.out.println("F construct");}
}

关键字:SpringBoot之@AutoConfigureBefore、@AutoConfigureAfter、@AutoConfigureOrder注解

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: