关于Spring中@Order注解的使用

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

先来一段代码:

public interface DefaultService {
    void send();
}
@Component
@Order(2)
public class ServiceA implements DefaultService{
    public ServiceA() {
        System.out.println("constructor ServiceA");
    }

    @Override
    public void send() {
        System.out.println("ServiceA.send");
    }
}
@Component
@Order(1)
public class ServiceB implements DefaultService{
    public ServiceB() {
        System.out.println("constructor ServiceB");
    }

    @Override
    public void send() {
        System.out.println("ServiceB.send");
    }
}
@Component
public class SortedService {

    @Autowired
    private List<DefaultService> list;
    @Autowired
    private Map<String, DefaultService> map;

    public void demo() {
        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)
public class RunnerA implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("RunnerA.run");
    }
}
@Component
@Order(1)
public class RunnerB implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("RunnerB.run");
    }
}
@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext ctx = SpringApplication.run(DemoApplication.class, args);
        
        //RunnerB.run
        //RunnerA.run
    }
}
private void callRunners(ApplicationContext context, ApplicationArguments args) {
		List<Object> runners = new ArrayList<>();
		runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
		runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
		// 容器已经完成了初始化后,排序后调用接口实现类
		AnnotationAwareOrderComparator.sort(runners);
		for (Object runner : new LinkedHashSet<>(runners)) {
			if (runner instanceof ApplicationRunner) {
				callRunner((ApplicationRunner) runner, args);
			}
			if (runner instanceof CommandLineRunner) {
				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.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值