关于Spring中@Order注解的使用

2022年11月23日11:29:40

@关于Spring中@Order注解的使用

先来一段代码:

publicinterfaceDefaultService{voidsend();}
@Component
@Order(2)publicclassServiceAimplementsDefaultService{publicServiceA(){
        System.out.println("constructor ServiceA");}

    @Overridepublicvoidsend(){
        System.out.println("ServiceA.send");}}
@Component
@Order(1)publicclassServiceBimplementsDefaultService{publicServiceB(){
        System.out.println("constructor ServiceB");}

    @Overridepublicvoidsend(){
        System.out.println("ServiceB.send");}}
@ComponentpublicclassSortedService{

    @Autowiredprivate List<DefaultService> list;
    @Autowiredprivate Map<String, DefaultService> map;publicvoiddemo(){
        Optional.of(list).ifPresent(l-> l.forEach(e-> System.out.println(e)));//输出//com.example.demo.service.ServiceB@19b843ba//com.example.demo.service.ServiceA@2462cb01//构造方法//constructor ServiceA//constructor ServiceB}}

我们可以看到,ServiceA和ServiceB的实例化顺序是不受@Order注解影响的,受影响的只是@Autowired自动注入时的一个注入的顺序(接口的实现类集合list是按照@Order顺序排列的)。

再来一段代码:

@Component
@Order(2)publicclassRunnerAimplementsApplicationRunner{
    @Overridepublicvoidrun(ApplicationArguments args) throws Exception{
        System.out.println("RunnerA.run");}}
@Component
@Order(1)publicclassRunnerBimplementsApplicationRunner{
    @Overridepublicvoidrun(ApplicationArguments args) throws Exception{
        System.out.println("RunnerB.run");}}
@SpringBootApplicationpublicclassDemoApplication{publicstaticvoidmain(String[] args){
        ConfigurableApplicationContext ctx= SpringApplication.run(DemoApplication.class, args);//RunnerB.run//RunnerA.run}}
privatevoidcallRunners(ApplicationContext context, ApplicationArguments args){
		List<Object> runners=newArrayList<>();
		runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
		runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());// 容器已经完成了初始化后,排序后调用接口实现类
		AnnotationAwareOrderComparator.sort(runners);for(Object runner:newLinkedHashSet<>(runners)){if(runnerinstanceofApplicationRunner){callRunner((ApplicationRunner) runner, args);}if(runnerinstanceofCommandLineRunner){callRunner((CommandLineRunner) runner, args);}}}

其实在Spring官网已经对@Order注解的作用做了很详细的描述

Your target beans can implement the org.springframework.core.Ordered interface or use the @Order or standard @Priority annotation if you want items in the array or list to be sorted in a specific order. Otherwise, their order follows the registration order of the corresponding target bean definitions in the container.

You can declare the @Order annotation at the target class level and on @Bean methods, potentially for individual bean definitions (in case of multiple definitions that use the same bean class). @Order values may influence priorities at injection points, but be aware that they do not influence singleton startup order, which is an orthogonal concern determined by dependency relationships and @DependsOn declarations.
@Order值可能会影响注入点的优先级,但是要注意它们不会影响单例启动顺序,单例启动顺序是由依赖关系和@DependsOn声明决定的正交关系

Note that the standard javax.annotation.Priority annotation is not available at the @Bean level, since it cannot be declared on methods. Its semantics can be modeled through @Order values in combination with @Primary on a single bean for each type.

  • 作者:幸福的老倭瓜
  • 原文链接:https://blog.csdn.net/weixin_44655917/article/details/110080911
    更新时间:2022年11月23日11:29:40 ,共 2911 字。