Запрашивая порядок загрузки bean-компонентов в Интернете, я увидел большое количество статей, использующих@Order
Аннотация используется для управления порядком загрузки бобов. Я не знаю, действительно ли студенты, которые написали эти сообщения в блоге, проверили их. Эта статья надеется указать на эти неправильные позы, чтобы друзья, которые смотрят текст, могли знать.@Order
конкретные сценарии применения
Оригинальный адрес:Неправильное использование порядка загрузки Bean в серии руководств по SpringBoot опровергает слухи
I. Строительство окружающей среды
Создайте проект maven, файл pom выглядит следующим образом (конкретный код проекта можно получить в конце статьи)
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7</version>
<relativePath/> <!-- lookup parent from update -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</pluginManagement>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
2. Неправильная осанка
Ниже мы познакомим вас с двумя типичными неправильными вариантами использования аннотаций.@Order
,Один@AutoConfigureOrder
I. @Order
Err.case1: Добавить примечание к ЗАКАЗУ
Распространенным заблуждением является то, что, добавив аннотацию Order к классу, вы можете указать порядок инициализации между bean-компонентами.Чем меньше значение порядка, тем выше приоритет.Далее давайте на самом деле проверим, так ли это.
Мы создаем два DemoBean, указав разный порядок порядка
@Order(4)
@Component
public class BaseDemo1 {
private String name = "base demo 1";
public BaseDemo1() {
System.out.println(name);
}
}
@Order(3)
@Component
public class BaseDemo2 {
private String name = "base demo 2";
public BaseDemo2() {
System.out.println(name);
}
}
Согласно предыдущей точке зрения, маленькое значение порядка имеет высокий приоритет, поэтому сначала нужно инициализировать BaseDemo2, после чего будет выполнен фактический тест.Вывод выглядит следующим образом.
err.case2: добавьте @Order в метод объявления Bean в классе конфигурации
В дополнение к автоматическому сканированию, описанному выше, у Бина есть еще один способ пройти@Bean
Аннотация, давайте продемонстрируем неправильный случай указания порядка загрузки бина в классе конфигурации
Точно так же мы создаем два новых тестовых компонента
public class BaseDemo3 {
private String name = "base demo 3";
public BaseDemo3() {
System.out.println(name);
}
}
public class BaseDemo4 {
private String name = "base demo 4";
public BaseDemo4() {
System.out.println(name);
}
}
Затем определите bean-компонент в классе конфигурации.
@Configuration
public class ErrorDemoAutoConf {
@Order(2)
@Bean
public BaseDemo3 baseDemo3() {
return new BaseDemo3();
}
@Order(1)
@Bean
public BaseDemo4 baseDemo4() {
return new BaseDemo4();
}
}
Аналогично, если@Order
Аннотация действительна, тогдаBaseDemo4
сначала нужно инициализировать
Как видно из приведенного выше фактического вывода теста, аннотация @Order не действует в приведенном выше методе. Если вам интересно, вы можете попробовать. Измените порядок двух методов в приведенном выше классе конфигурации, вы найдете тотBaseDemo4
загрузить сначала
err.case3: аннотация @Order украшает класс конфигурации
Это также распространенная ошибка, когда думают, что аннотация @Order используется для указания порядка загрузки классов конфигурации, но так ли это на самом деле?
Создаем два класса тестовой конфигурации
@Order(1)
@Configuration
public class AConf {
public AConf() {
System.out.println("AConf init!");
}
}
@Order(0)
@Configuration
public class BConf {
public BConf() {
System.out.println("BConf init");
}
}
Если аннотация @Order вступит в силу, то сначала будет инициализирован класс конфигурации BConf, так что давайте проверим его
Из приведенных выше результатов видно, что BConf не загружается первым, конечно, такая ситуация использования фактически ничем не отличается от первого случая ошибки Класс конфигурации также является bean-компонентом, который не вступает в силу раньше, и, конечно же, он здесь не вступит в силу.
Значит, это вызвано нашим непониманием?@Order
После помещения его в класс конфигурации, имеет ли Бин, определенный в этом классе конфигурации, приоритет над Бин, определенным в другом классе конфигурации?
Аналогично, давайте проверим этот случай, мы определяем три bean-компонента, два conf
public class Demo1 {
private String name = "conf demo bean 1";
public Demo1() {
System.out.println(name);
}
}
public class Demo2 {
private String name = "conf demo bean 2";
public Demo2() {
System.out.println(name);
}
}
public class Demo3 {
private String name = "conf demo bean 3";
public Demo3() {
System.out.println(name);
}
}
Затем мы ставим Demo1, Demo3 в одну конфигурацию и Demo2 в другую конфигурацию.
@Order(2)
@Configuration
public class AConf1 {
@Bean
public Demo1 demo1() {
return new Demo1();
}
@Bean
public Demo3 demo3() {
return new Demo3();
}
}
@Order(1)
@Configuration
public class BConf1 {
@Bean
public Demo2 demo2() {
return new Demo2();
}
}
Если аннотация @Order фактически управляет порядком загрузки bean-компонентов в классе конфигурации, то bean-компоненты в BConf1 должны быть загружены первыми, то есть Demo2 будет иметь приоритет над Demo1, Demo3 и фактическим тестом, вывод будет следующим следует
Вышеприведенный результат отличается от того, что мы ожидали, поэтому@Order
Также неправильно использовать аннотации для определения порядка классов конфигурации.
2. @AutoConfigureOrder
С точки зрения именования, эта аннотация используется для указания порядка классов конфигурации.Однако есть много случаев неправильного использования этой аннотации, и большинство из них заключается в том, что они не совсем понимают сценарии ее использования.
Далее, давайте продемонстрируем неправильное использование регистра
Создайте два новых класса конфигурации в проекте и используйте аннотации напрямую.
@Configuration
@AutoConfigureOrder(1)
public class AConf2 {
public AConf2() {
System.out.println("A Conf2 init!");
}
}
@Configuration
@AutoConfigureOrder(-1)
public class BConf2 {
public BConf2() {
System.out.println("B conf2 init!");
}
}
Когда аннотация вступит в силу, BConf будет загружаться с приоритетом
Судя по результату, он отличается от того, что мы ожидали; так влияет ли эта аннотация на порядок bean-компонентов в классе конфигурации, а не на сам класс конфигурации?
Точно так же мы разрабатываем кейс для проверки
public class DemoA {
private String name = "conf demo bean A";
public DemoA() {
System.out.println(name);
}
}
public class DemoB {
private String name = "conf demo bean B";
public DemoB() {
System.out.println(name);
}
}
public class DemoC {
private String name = "conf demo bean C";
public DemoC() {
System.out.println(name);
}
}
Соответствующий класс конфигурации
@Configuration
@AutoConfigureOrder(1)
public class AConf3 {
@Bean
public DemoA demoA() {
return new DemoA();
}
@Bean
public DemoC demoC() {
return new DemoC();
}
}
@Configuration
@AutoConfigureOrder(-1)
public class BConf3 {
@Bean
public DemoB demoB() {
return new DemoB();
}
}
Если DemoB загружается позже, это означает, что указанный выше пункт неверен, и результаты измерений следующие.
Итак, возникает вопрос,@AutoConfigureOrder
В этой аннотации не указан порядок классов конфигурации, и она тоже называется этим именем, почему? Это не заблуждение!!!
Далее мы смотрим на@Order
и@AutoConfigureOrder
правильный способ использования
III. Инструкции по применению
1. @Order
Сначала взгляните на официальную аннотацию этой аннотации.
{@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 использовалась для указания приоритета аспектов, ее функция была расширена после версии 4.0 для поддержки внедрения коллекции, указывающей порядок бинов в коллекции.
И специально указано, что это не влияет на порядок между bean-компонентами экземпляра; это предложение также можно проверить в соответствии с нашим тестом выше.
Далее нужно рассмотреть сценарий указания порядка при инжекте коллекции через аннотацию @Order
Во-первых, мы определяем два bean-компонента для реализации одного и того же интерфейса и добавляем@Order
аннотация
public interface IBean {
}
@Order(2)
@Component
public class AnoBean1 implements IBean {
private String name = "ano order bean 1";
public AnoBean1() {
System.out.println(name);
}
}
@Order(1)
@Component
public class AnoBean2 implements IBean {
private String name = "ano order bean 2";
public AnoBean2() {
System.out.println(name);
}
}
Затем в тестовый компонент введитеIBean
list, нам нужно проверить, соответствует ли порядок бобов в этом списке тому, что мы определили@Order
Правила непротиворечивы
@Component
public class AnoTestBean {
public AnoTestBean(List<IBean> anoBeanList) {
for (IBean bean : anoBeanList) {
System.out.println("in ano testBean: " + bean.getClass().getName());
}
}
}
По нашим ожиданиям, в коллекции anoBeanList anoBean2 должен стоять впереди
Из приведенного выше вывода также видно, что порядок в списке такой, как мы и ожидали, иAnoOrderBean1
иAnoOrderBean2
Порядок загрузки не имеет ничего общего с аннотациями
2. @AutoConfigureOrder
Эта аннотация используется для указания порядка загрузки файла конфигурации, но она не действовала в предыдущем тесте, так как же правильно использовать?
@AutoConfigureOrder
Применяется к порядку AutoConfig во внешне зависимых пакетах и не может использоваться для указания порядка в этом пакете.
Чтобы проверить вышеприведенное утверждение, мы снова создаем два новых проекта и указываем порядок классов автоматической настройки.
Проект 1 настроен следующим образом:
@AutoConfigureOrder(1)
@Configuration
@ComponentScan(value = {"com.git.hui.boot.order.addition"})
public class AdditionOrderConf {
public AdditionOrderConf() {
System.out.println("additionOrderConf init!!!");
}
}
Обратите внимание, что если класс автоконфигурации должен быть загружен правильно, он должен находиться в папке проекта./META-INF/spring.factories
определено в файле
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.git.hui.boot.order.addition.AdditionOrderConf
Конфигурация второго проекта выглядит следующим образом:
@Configuration
@AutoConfigureOrder(-1)
@ComponentScan("com.git.hui.boot.order.addition2")
public class AdditionOrderConf2 {
public AdditionOrderConf2() {
System.out.println("additionOrderConf2 init!!!");
}
}
Затем добавляем конфигурацию внутри проекта
@AutoConfigureOrder(10)
@Configuration
public class OrderConf {
public OrderConf() {
System.out.println("inner order conf init!!!");
}
}
Поскольку аннотации применяются к порядку классов автоматической конфигурации во внешних пакетах зависимостей, среди трех вышеприведенных классов конфигурации AdditionOrderConf2 стоит перед AdditionOrderConf1, если он правильный, и OrderConf не будет затронут аннотациями. быть лучше, чем внешние зависимости, и следующий вывод также может поддержать наше объяснение (конечно, чтобы убедиться, что это правда, вы также должны настроить порядок следующих двух классов конфигурации внешнего проекта и посмотреть, изменится ли порядок загрузки соответственно, мы его здесь опускаем )
IV. Резюме
Эта статья в основном представляет онлайн@Order
и@AutoConfigureOrder
Приведены распространенные жесты неправильного использования и варианты правильного использования.
Вот несколько простых предложений, чтобы ввести правильную осанку
-
@Order
Аннотации не могут указывать порядок загрузки bean-компонентов, они применяются к приоритетам AOP, и когда несколько bean-компонентов вводятся в коллекцию, порядок bean-компонентов в коллекции -
@AutoConfigureOrder
Задает порядок загрузки внешне зависимых AutoConfig (т. е. определенных в/META-INF/spring.factories
приоритет конфигурационного компонента в файле), нет смысла использовать эту аннотацию в текущем проекте. - такой же
@AutoConfigureBefore
и@AutoConfigureAfter
Сфера применения этих двух аннотаций и@AutoConfigureOrder
Такой же
0. Проект
- проект:GitHub.com/JuneB/tickets…
- Исходный модуль: -GitHub.com/JuneB/tickets… - GitHub.com/JuneB/tickets… - GitHub.com/JuneB/tickets…
1. Блог одного пепла
Это не так хорошо, как письмо.Вышеупомянутое содержание чисто из семьи.Из-за ограниченных личных способностей неизбежно есть упущения и ошибки.Если вы найдете ошибки или у вас есть лучшие предложения, вы можете критиковать и исправлять их.
Ниже представлен серый личный блог, в котором записываются все посты в блоге по учебе и работе, приглашаю всех посетить
- Блог One Ash Личный блогblog.hhui.top
- Блог One Ash - специальный весенний блогspring.hhui.top