Spring的@Order

一、简述

注解@Order或者接口Ordered的作用是定义Spring IOC容器中Bean的执行顺序的优先级,而不是定义Bean的加载顺序,Bean的加载顺序不受@Order或Ordered接口的影响。值越小拥有越高的优先级,可为负数。

例如:
@Order(-1)优先于@Order(0)
@Order(1)优先于@Order(2)

1️⃣@Order的注解源码解读

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Documented
public @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();
}

二、示例

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

@Configuration
@Order(2)
public class OrderAConfig {
    @Bean
    public OrderAService oa() {
        System.out.println("OrderAService 执行了");
        return new OrderAService();
    }
    class OrderAService {

    }
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

@Configuration
@Order(1)
public class OrderBConfig {
    @Bean
    public OrderBService ob() {
        System.out.println("OrderBService 执行了");
        return new OrderBService();
    }
    class OrderBService {
    }
}
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class OrderMain {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context =
                new AnnotationConfigApplicationContext("com.xxp.mchopin.annotation.order");
    }
}

结果如下:
OrderBService 执行了
OrderAService 执行了

三、IOC容器是如何根据优先级值来先后执行程序的

貌似根据名字来搞得

看如下的启动main方法

@SpringBootApplication
public 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 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);
        return context;
    } catch (Throwable var9) {
   this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
        throw new IllegalStateException(var9);
    }
}
private void callRunners(ApplicationContext context, ApplicationArguments args) {
    List 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);
    }
}
 

                            
                        
                    
                    
                    

你可能感兴趣的:(Spring的@Order)