当前位置: 首页 >服务端 > 浅谈Spring @Order注解的使用(转)

浅谈Spring @Order注解的使用(转)

注解@Order或者接口Ordered的作用是定义Spring IOC容器中Bean的执行顺序的优先级,而不是定义Bean的加载顺序,Bean的加载顺序不受@Order或Ordered接口的影响;

1.@Order的注解源码解读

@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})@Documentedpublic @interface Order {/** * 默认是最低优先级,值越小优先级越高 */int value() default Ordered.LOWEST_PRECEDENCE;}
  • 注解可以作用在类(接口、枚举)、方法、字段声明(包括枚举常量);
  • 注解有一个int类型的参数,可以不传,默认是最低优先级;
  • 通过常量类的值我们可以推测参数值越小优先级越高;

2.Ordered接口类

package org.springframework.core;public interface Ordered {int HIGHEST_PRECEDENCE = -2147483648;int LOWEST_PRECEDENCE = 2147483647;int getOrder();}

3.创建BlackPersion、YellowPersion类,这两个类都实现CommandLineRunner
实现CommandLineRunner接口的类会在Spring IOC容器加载完毕后执行,适合预加载类及其它资源;也可以使用ApplicationRunner,使用方法及效果是一样的。

package com.yaomy.common.order;import org.springframework.boot.CommandLineRunner;import org.springframework.core.annotation.Order;import org.springframework.stereotype.Component;/** * @Description: Description * @ProjectName: spring-parent * @Version: 1.0 */@Component@Order(1)public class BlackPersion implements CommandLineRunner {@Overridepublic void run(String... args) throws Exception {System.out.println("----BlackPersion----");}}
package com.yaomy.common.order;import org.springframework.boot.CommandLineRunner;import org.springframework.core.annotation.Order;import org.springframework.stereotype.Component;/** * @Description: Description * @ProjectName: spring-parent * @Version: 1.0 */@Component@Order(0)public class YellowPersion implements CommandLineRunner {@Overridepublic void run(String... args) throws Exception {System.out.println("----YellowPersion----");}}

4.启动应用程序打印出结果

----YellowPersion--------BlackPersion----

我们可以通过调整@Order的值来调整类执行顺序的优先级,即执行的先后;当然也可以将@Order注解更换为Ordered接口,效果是一样的

5.到这里可能会疑惑IOC容器是如何根据优先级值来先后执行程序的,那接下来看容器是如何加载component的

  • 看如下的启动main方法
    @SpringBootApplicationpublic class CommonBootStrap {public static void main(String[] args) {SpringApplication.run(CommonBootStrap.class, args);}}

    这个不用过多的解释,进入run方法。。

  • public ConfigurableApplicationContext run(String... args) {StopWatch stopWatch = new StopWatch();stopWatch.start();ConfigurableApplicationContext context = null;Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();this.configureHeadlessProperty();SpringApplicationRunListeners listeners = this.getRunListeners(args);listeners.starting();Collection exceptionReporters;try {ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);this.configureIgnoreBeanInfo(environment);Banner printedBanner = this.printBanner(environment);context = this.createApplicationContext();exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);this.refreshContext(context);this.afterRefresh(context, applicationArguments);stopWatch.stop();if (this.logStartupInfo) {(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);}listeners.started(context);//这里是重点,调用具体的执行方法this.callRunners(context, applicationArguments);} catch (Throwable var10) {this.handleRunFailure(context, var10, exceptionReporters, listeners);throw new IllegalStateException(var10);}try {listeners.running(context);retu context;} catch (Throwable var9) {this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);throw new IllegalStateException(var9);}}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);Iterator var4 = (new LinkedHashSet(runners)).iterator();//循环调用具体方法while(var4.hasNext()) {Object runner = var4.next();if (runner instanceof ApplicationRunner) {this.callRunner((ApplicationRunner)runner, args);}if (runner instanceof CommandLineRunner) {this.callRunner((CommandLineRunner)runner, args);}}}private void callRunner(ApplicationRunner runner, ApplicationArguments args) {try {//执行方法runner.run(args);} catch (Exception var4) {throw new IllegalStateException("Failed to execute ApplicationRunner", var4);}}private void callRunner(CommandLineRunner runner, ApplicationArguments args) {try {//执行方法runner.run(args.getSourceArgs());} catch (Exception var4) {throw new IllegalStateException("Failed to execute CommandLineRunner", var4);}}

    到这里优先级类的示例及其执行原理都分析完毕;不过还是要强调下@Order、Ordered不影响类的加载顺序而是影响Bean加载如IOC容器之后执行的顺序(优先级);

  • 原文地址:https://blog.csdn.net/yaomingyang/article/details/86649072

 

来源链接:https://www.cnblogs.com/muxi0407/p/11611098.html

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。





本文链接:https://www.javaclub.cn/server/113065.html

标签:Spring注解
分享给朋友:

“浅谈Spring @Order注解的使用(转)” 的相关文章