The function of annotating @Order or interface Ordered is to define the priority of the execution order of the bean in Spring IOC container, rather than define the load order of the bean. The load order of the bean is not affected by the @Order or Ordered interface;
1. Interpretation of @Order's annotation source code
@Retention() @Target({, , }) @Documented public @interface Order { /** * The default is the lowest priority, the smaller the value, the higher the priority */ int value() default Ordered.LOWEST_PRECEDENCE; }
- Annotations can be used in classes (interfaces, enumerations), methods, and field declarations (including enumeration constants);
- The annotation has an int type parameter, which can be not passed, and the default is the lowest priority;
- Through the values of the constant class, we can infer that the smaller the parameter value, the higher the priority;
Interface class
package ; public interface Ordered { int HIGHEST_PRECEDENCE = -2147483648; int LOWEST_PRECEDENCE = 2147483647; int getOrder(); }
3. Create BlackPersion and YellowPersion classes, both of which implement CommandLineRunner
The class that implements the CommandLineRunner interface will be executed after the Spring IOC container is loaded, which is suitable for preloading classes and other resources; ApplicationRunner can also be used, and the usage method and effect are the same.
package ; import ; import ; import ; /** * @Description: Description * @ProjectName: spring-parent * @Version: 1.0 */ @Component @Order(1) public class BlackPersion implements CommandLineRunner { @Override public void run(String... args) throws Exception { ("----BlackPersion----"); } }
package ; import ; import ; import ; /** * @Description: Description * @ProjectName: spring-parent * @Version: 1.0 */ @Component @Order(0) public class YellowPersion implements CommandLineRunner { @Override public void run(String... args) throws Exception { ("----YellowPersion----"); } }
4. Start the application and print the results
----YellowPersion---- ----BlackPersion----
We can adjust the priority of the execution order of the class by adjusting the value of @Order, that is, the execution order; of course, we can also replace the @Order annotation with the Ordered interface, and the effect is the same
5. At this point, you may wonder how the IOC container executes the program according to the priority value. Let’s take a look at how the container loads the component.
- See the following method to start main
@SpringBootApplication public class CommonBootStrap { public static void main(String[] args) { (, args); } }
This does not require too much explanation, enter the run method...
public ConfigurableApplicationContext run(String... args) { StopWatch stopWatch = new StopWatch(); (); ConfigurableApplicationContext context = null; Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList(); (); SpringApplicationRunListeners listeners = (args); (); Collection exceptionReporters; try { ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); ConfigurableEnvironment environment = (listeners, applicationArguments); (environment); Banner printedBanner = (environment); context = (); exceptionReporters = (, new Class[]{}, context); (context, environment, listeners, applicationArguments, printedBanner); (context); (context, applicationArguments); (); if () { (new StartupInfoLogger()).logStarted((), stopWatch); } (context); //This is the key point, calling the specific execution method (context, applicationArguments); } catch (Throwable var10) { (context, var10, exceptionReporters, listeners); throw new IllegalStateException(var10); } try { (context); return context; } catch (Throwable var9) { (context, var9, exceptionReporters, (SpringApplicationRunListeners)null); throw new IllegalStateException(var9); } } private void callRunners(ApplicationContext context, ApplicationArguments args) { List<Object> runners = new ArrayList(); (().values()); (().values()); //The key point is here, sort it in the defined priority order (runners); Iterator var4 = (new LinkedHashSet(runners)).iterator(); //Calling specific method while(()) { Object runner = (); if (runner instanceof ApplicationRunner) { ((ApplicationRunner)runner, args); } if (runner instanceof CommandLineRunner) { ((CommandLineRunner)runner, args); } } } private void callRunner(ApplicationRunner runner, ApplicationArguments args) { try { //Execution method (args); } catch (Exception var4) { throw new IllegalStateException("Failed to execute ApplicationRunner", var4); } } private void callRunner(CommandLineRunner runner, ApplicationArguments args) { try { //Execution method (()); } catch (Exception var4) { throw new IllegalStateException("Failed to execute CommandLineRunner", var4); } }
Here, the examples of priority classes and their execution principles have been analyzed; however, it should be emphasized that @Order and Ordered do not affect the loading order of the class but affect the order of execution after the bean is loaded such as the IOC container (priority);
Personally, I understand that the underlying layer of loading code must support priority execution of programs, otherwise even if Ordered and @Order are configured, it will not work.
Personal power is always small. Everyone is welcome to discuss and work hard to grow together! !
GitHub source code:/mingyang66/spring-parent
This is the end of this article about the use of Spring @Order annotations. For more related Spring @Order annotations, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!