所有分类
  • 所有分类
  • 未分类

Spring注解–@Order的使用

简介

说明

本文用示例介绍@Order(顺序)注解的用法。

@Order的作用

  1. 多个 Bean 注入到集合时在集合中的顺序
  2. 指定AOP的优先级
  3. 控制ApplicationListener实现类的加载顺序
  4. 控制ApplicationRunner、CommandLineRunner实现类的加载顺序

@Order的使用

  • Integer.MIN_VALUE <= Order <= Integer.MAX_VALUE。
  • 最大最小优先级:@Order(Ordered.LOWEST_PRECEDENCE) / @Order(Ordered.HIGHEST_PRECEDENCE )
            Spring已有的顺序值:org/springframework/core/Ordered:
                int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;
                int LOWEST_PRECEDENCE = Integer.MAX_VALUE;
  • Order值越小,优先级越高!    
  • @Order的使用位置:  ElementType.TYPE, ElementType.METHOD, ElementType.FIELD

@Order不支持的操作

  1. 不能指定 bean 的加载顺序
    1. 它对于实例的 bean 之间的加载顺序,没有任何影响。
    2. 无论使用@Order还是实现Ordered接口,都不行
  2. 不能指定@AutoConfigureOrder外部依赖的 AutoConfig 的加载顺序(即定义在/META-INF/spring.factories文件中的配置 bean 优先级)
    1. 在当前工程中使用这个注解并没有什么鸟用。
    2. 同样的 @AutoConfigureBefore和 @AutoConfigureAfter这两个注解的适用范围和@AutoConfigureOrder一样。

官方注释

{@code @Order} defines the sort order for an annotated component. Since Spring 4.0, annotation-based ordering is supported for many kinds of components in Spring, even for collection injection where the order values of the target components are taken into account (either from their target class or from their {@code @Bean} method). While such order values may influence priorities at injection points, please be aware that they do not influence singleton startup order which is an orthogonal concern determined by dependency relationships and {@code @DependsOn} declarations (influencing a runtime-determined dependency graph). 

最开始 @Order 用于切面的优先级指定;Spring4.0 之后它的功能进行了增强,支持集合的注入时,指定集合中 bean 的顺序。它对于实例的 bean 之间的顺序,没有任何影响。

用法1:控制集合顺序

接口

package com.example.test;

public interface IBean {
}

实现类1

package com.example.test;

import lombok.Data;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

@Configuration
public class DemoConfig1 {
    @Bean
    @Order(2)
    public DemoBean1 demo1Service(){
        System.out.println("config-1 加载了");
        return new DemoBean1();
    }

    @Data
    private class DemoBean1 implements IBean{
        private String name;
        private Integer age;
    }
}

实现类2

package com.example.test;

import lombok.Data;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

@Configuration
public class DemoConfig2 {
    @Bean
    @Order(1)
    public DemoBean2 demo2Service(){
        System.out.println("config-2 加载了");
        return new DemoBean2();
    }

    @Data
    private class DemoBean2 implements IBean{
        private String name;
        private String phone;
    }
}

测试类

package com.example.test;

import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class CollectionIOC {
    public CollectionIOC(List<IBean> iBeans) {
        for (IBean iBean : iBeans) {
            System.out.println(iBean.getClass().getName());
        }
    }
}

 执行结果

config-1 加载了
config-2 加载了
com.example.test.DemoConfig2$DemoBean2
com.example.test.DemoConfig1$DemoBean1

颠倒顺序

config-1 加载了
config-2 加载了
com.example.test.DemoConfig1$DemoBean1
com.example.test.DemoConfig2$DemoBean2

@Order放到这三个位置有相同的效果:@Bean、Bean类、@Component

例如:

package com.example.test;

import lombok.Data;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

@Configuration
public class DemoConfig2 {
    @Bean
    public DemoBean2 demo2Service(){
        System.out.println("config-2 加载了");
        return new DemoBean2();
    }

    @Data
    @Order(1)
    private class DemoBean2 implements IBean{
        private String name;
        private String phone;
    }
}
package com.example.test;

import lombok.Data;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

@Configuration
public class DemoConfig2 {
    @Bean
    @Order(1)
    public DemoBean2 demo2Service(){
        System.out.println("config-2 加载了");
        return new DemoBean2();
    }

    @Data
    private class DemoBean2 implements IBean{
        private String name;
        private String phone;
    }
}

用法2:AOP顺序

见:Spring之AOP-控制AOP的执行顺序 – 自学精灵

用法3:ApplicationListener顺序

见:SpringBoot-自定义事件-同步与异步 – 自学精灵

用法4:ApplicationRunner等顺序

见:SpringBoot-启动时执行的方法 – 自学精灵

无效的场景

@Bean + @Order,@Configuration+@Order都是无法确定顺序的。

@Bean + @Order(无效)

package com.example.test;

import lombok.Data;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

@Configuration
public class DemoConfig1 {
    @Bean
    @Order(1)
    public DemoBean1 demo1Service(){
        System.out.println("config-1 加载了");
        return new DemoBean1();
    }

    @Data
    private class DemoBean1 {
        private String name;
        private Integer age;
    }
}
package com.example.test;

import lombok.Data;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

@Configuration
public class DemoConfig2 {
    @Bean
    @Order(2)
    public DemoBean2 demo2Service(){
        System.out.println("config-2 加载了");
        return new DemoBean2();
    }

    @Data
    private class DemoBean2 {
        private String name;
        private String phone;
    }
}

 执行结果

config-1 加载了
config-2 加载了

执行结果(颠倒Order)

config-1 加载了
config-2 加载了

 @Configuration+@Order(无效)

package com.example.test;

import lombok.Data;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

@Configuration
@Order(1)
public class DemoConfig1 {
    @Bean
    public DemoBean1 demo1Service(){
        System.out.println("config-1 加载了");
        return new DemoBean1();
    }

    @Data
    private class DemoBean1 {
        private String name;
        private Integer age;
    }
}
package com.example.test;

import lombok.Data;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

@Configuration
@Order(2)
public class DemoConfig2 {
    @Bean
    public DemoBean2 demo2Service(){
        System.out.println("config-2 加载了");
        return new DemoBean2();
    }

    @Data
    private class DemoBean2 {
        private String name;
        private String phone;
    }
}

执行结果 

config-1 加载了
config-2 加载了

执行结果(颠倒@Order)

config-1 加载了
config-2 加载了
0

评论0

请先

显示验证码
没有账号?注册  忘记密码?

社交账号快速登录