Ответ 1
Перенос XML в @Configuration
Можно перенести xml в @Configuration
в несколько шагов:
-
Создайте аннотированный класс
@Configuration
:@Configuration public class MyApplicationContext { }
-
Для каждого
<bean>
создайте метод, аннотированный@Bean
:@Configuration public class MyApplicationContext { @Bean(name = "someBean") public SomeClass getSomeClass() { return new SomeClassImpl(someInterestingProperty); // We still need to inject someInterestingProperty } @Bean(name = "anotherBean") public AnotherClass getAnotherClass() { return new AnotherClassImpl(getSomeClass(), beanFromSomewhereElse); // We still need to inject beanFromSomewhereElse } }
-
Чтобы импортировать
beanFromSomewhereElse
нам нужно импортировать его определение. Это может быть определено в XML, и мы будем использовать@ImportResource
:@ImportResource("another-application-context.xml") @Configuration public class MyApplicationContext { ... }
Если bean-компонент определен в другом классе
@Configuration
мы можем использовать аннотацию@Import
:@Import(OtherConfiguration.class) @Configuration public class MyApplicationContext { ... }
-
После того, как мы импортировали другие XML или классы
@Configuration
, мы можем использовать@Configuration
, которые они объявляют в нашем контексте, объявив закрытый член класса@Configuration
следующим образом:@Autowired @Qualifier(value = "beanFromSomewhereElse") private final StrangeBean beanFromSomewhereElse;
Или используйте его непосредственно в качестве параметра в методе, который определяет компонент, который зависит от этого
beanFromSomewhereElse
используя@Qualifier
следующим образом:@Bean(name = "anotherBean") public AnotherClass getAnotherClass(@Qualifier (value = "beanFromSomewhereElse") final StrangeBean beanFromSomewhereElse) { return new AnotherClassImpl(getSomeClass(), beanFromSomewhereElse); }
-
Импорт свойств очень похож на импорт bean-компонента из другого класса xml или
@Configuration
. Вместо использования@Qualifier
мы будем использовать@Value
со свойствами следующим образом:@Autowired @Value("${some.interesting.property}") private final String someInterestingProperty;
Это можно использовать и с выражениями SpEL.
-
Чтобы Spring мог обрабатывать такие классы как контейнеры bean-компонентов, нам нужно пометить это в нашем основном XML файле, поместив этот тег в контекст:
<context:annotation-config/>
Теперь вы можете импортировать классы
@Configuration
точно так же, как при создании простого компонента:<bean class="some.package.MyApplicationContext"/>
Есть способы полностью избежать весенних XML, но они не входят в сферу применения этого ответа. Вы можете найти один из этих вариантов в моем блоге, на котором я основываю свой ответ.
Преимущества и недостатки использования этого метода
По сути, я нахожу этот метод объявления бинов гораздо более удобным, чем использование XML, из-за нескольких преимуществ, которые я вижу:
- Опечатки - классы
@Configuration
компилируются, а опечатки просто не позволяют компиляции - Сбой быстро (время компиляции) - если вы забудете внедрить bean-компонент, вы потерпите неудачу во время компиляции, а не во время выполнения, как в XML
- Проще ориентироваться в IDE - между конструкторами bean-компонентов, чтобы понять дерево зависимостей.
- Можно легко отладить запуск конфигурации
Недостатков не так много, как я их вижу, но есть несколько, о которых я мог бы подумать:
- Злоупотребление - Код легче злоупотреблять, чем XML
- С помощью XML вы можете определять зависимости на основе классов, которые недоступны во время компиляции, но предоставляются во время выполнения. С классами
@Configuration
вы должны иметь классы, доступные во время компиляции. Обычно это не проблема, но есть случаи, когда это может быть.
Итог: прекрасно сочетать XML, @Configuration
и аннотации в контексте вашего приложения. Spring не заботится о методе, которым был объявлен боб.