Эта статья участвовала в третьем этапе курса «High Yield Update» тренировочного лагеря для создателей Nuggets. Подробнее см.:Dig Li Project | Идет третий этап тренировочного лагеря создателя, «написание» личного влияния.
Конфигурацию контейнера Spring можно выполнить двумя способами: один на основе XML-файлов, а другой — на основе аннотаций. Внедрение аннотации выполняется перед внедрением XML. Поэтому, когда оба используются одновременно, конфигурация XML переопределяет свойства, введенные аннотацией.
В этой статье в основном будут представлены аннотации @Required, @Autowired, @PostConstruct, @PreDestroy и @Resource.
Эти аннотацииcontext:annotation-config/представлять. По сути, введение этой конфигурации будет неявно регистрировать AutoWiredAnnotationBeanPostProcessor (предоставляя @Autowired), CommonAnnotationBeanPostProcessor (предоставляя @PostConstruct, @PreDestroy, @Resource), RequiredAnnotationBeanPostProcessor (предоставляя @Required), тем самым обеспечивая функции каждой аннотации.
Ниже мы представим функции каждой аннотации отдельно.
@Required
@Required обычно используется в методах, указывая, что параметры метода должны быть заполнены конфигурацией или автозагрузкой. Обычно, если требуется свойство, мы будем использовать эту аннотацию.
Однако, начиная с Spring Framework 5.1, аннотация @Required официально устарела в пользу использования внедрения конструктора для необходимых свойств или использования пользовательской реализации InitializingBean.afterPropertiesSet() и методов установки свойств bean-компонента.
Пример кода выглядит следующим образом:
public class RequiredBean {
private BeanA beanA;
@Required
public void setBeanA(BeanA beanA){
this.beanA=beanA;
}
}
@Autowired
@Autowired автоматически вставляет необходимые поля, параметры и т. д. Аннотация @Inject JSR 330 может заменить аннотацию Spring @Autowired.
Вы можете аннотировать конструктор с помощью @Autowired следующим образом:
public class AutowiredBean {
private BeanA beanA;
@Autowired
public AutowiredBean(BeanA beanA){
this.beanA=beanA;
}
}
Начиная с Spring Framework 4.3, если целевой компонент определяет только один конструктор, больше нет необходимости использовать аннотацию @Autowired для таких конструкторов. Однако, если доступно несколько конструкторов, по крайней мере один из них должен быть аннотирован, чтобы указать контейнеру, какой из них использовать.
@Autowired также может быть аннотирован для традиционных методов установки, как показано в следующем примере:
public class AutowiredBean {
private BeanB beanB;
@Autowired
public void setBeanB(BeanB beanB){
this.beanB=beanB;
}
}
Также можно применять аннотации к любому имени и нескольким параметрам следующим образом:
@Autowired
public void configAB(BeanA beanA , BeanB beanB){
this.beanA=beanA;
this.beanB=beanB;
}
@Autowired также можно использовать в таких полях:
@Autowired
private BeanC beanC;
Вы также можете получить все bean-компоненты этого конкретного типа из ApplicationContext, добавив аннотации к полям или методам, которым требуется массив этого типа, как показано в следующем примере:
@Autowired
private BeanC[] beanCList;
Если вы хотите, чтобы элементы в массиве или списке были упорядочены в определенном порядке, целевой компонент может реализовать интерфейс org.springframework.core.Ordered, или вы можете использовать аннотации @Order или стандартные @Priority. В противном случае их порядок соответствует порядку регистрации, определенному соответствующим целевым компонентом в контейнере.
Экземпляры карты также могут быть внедрены, если ключ имеет тип String. Значение Map включает в себя все bean-компоненты, типы которых совпадают, а ключи — это имя bean-компонента. Следующее:
@Autowired
public void configMapA(Map<String,BeanA> mapA){
this.mapA=mapA;
}
@Autowired имеет обязательный атрибут, если bean-компонент для внедрения может не существовать, он может быть следующим:
@Autowired(required = false)
public void setBeanC(BeanC beanC){
}
Рекомендуется использовать атрибут «required» @Autowired вместо использования аннотации @Required в методе установки. Атрибут «обязательный» указывает, что атрибут необходим для автозагрузки, и если он не может быть загружен автоматически, этот атрибут игнорируется. Для @Required, если значение не определено, будет сообщено об исключении.
Необязательные свойства определенных зависимостей также могут быть выражены через java.util.Optional в Java 8, как показано в следующем примере:
@Autowired
public void setMovieFinder(Optional<BeanC> BeanC) {
}
В Spring Framework 5.0 вы также можете использовать аннотацию @Nullable:
@Autowired
public void setMovieFinderC(@Nullable BeanC beanC) {
}
Spring может использовать @Autowired для автоматического разрешения некоторых bean-компонентов по умолчанию, таких как: BeanFactory, ApplicationContext, Environment, ResourceLoader, ApplicationEventPublisher и MessageSource. Эти интерфейсы и их интерфейсы расширения (например, ConfigurableApplicationContext или ResourcePatternResolver). ApplicationContext автоматически внедряется следующим образом:
@Autowired
private ApplicationContext context;
Примечание. Аннотации @Autowired, @Inject, @Value и @Resource обрабатываются в Spring BeanPostProcessor, что означает, что вы не можете использовать эти аннотации в своих собственных типах BeanPostProcessor, BeanFactoryPostProcessor.
@primary
При внедрении по типу может быть несколько кандидатов, и предпочтительный объект может быть представлен аннотацией @Primary. Следующее:
@Configuration
public class ConfigBean {
@Bean
@Primary
public BeanA firstBeanA() { return new BeanA(); }
@Bean
public BeanA secondBeanA() { return new BeanA();}
}
@Qualifier
@Primary — это эффективный способ использовать автозагрузку по типу в нескольких экземплярах, но если вам нужен более детальный контроль над внедряемыми bean-компонентами, вы можете использовать @Qualifier. Следующее:
@Bean
@Qualifier("main")
public BeanC beanC() { return new BeanC();}
@Autowired
@Qualifier("main")
private BeanA beanA;
@Autowired
public void setBeanA(@Qualifier("main") BeanA beanA){
}
Значение квалификатора не уникально, это просто критерий фильтра.
@Autowired обычно используется для сопоставления по типу, а @Resource — для сопоставления по имени.
Также возможно создание пользовательских аннотаций:
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Genre {
String value();
}
Дженерики
В дополнение к аннотации @Qualifier также можно использовать общие типы Java в качестве неявной формы квалификации. Например, предположим, что у вас есть следующая конфигурация:
public class StringStore implements Store<String> {
}
public class IntegerStore implements Store<Integer> {
}
@Bean
public StringStore stringStore() {
return new StringStore();
}
@Bean
public IntegerStore integerStore() {
return new IntegerStore();
}
public class GenericBean {
@Autowired
private Store<String> s1; // <String> qualifier, injects the stringStore bean
@Autowired
private Store<Integer> s2; // <Integer> qualifier, injects the integerStore bean
// Inject all Store beans as long as they have an <Integer> generic
// Store<String> beans will not appear in this list
@Autowired
private List<Store<Integer>> s;
}
@Resource
@Resource используется в полях или методах установки, по умолчанию @Resource вводится по имени.
public class ResourceBean {
@Resource(name = "beanA")
private BeanA BeanA;
}
Если имя не указано явно, имя по умолчанию получается из имени поля или метода установки.
При использовании @Resource, если явное имя не указано и аналогично @Autowired, @Resource находит совпадение основного типа вместо указанного bean-компонента и разрешает известные разрешимые зависимости: BeanFactory, ApplicationContext, ResourceLoader, ApplicationEventPublisher и интерфейс MessageSource.
@PostConstruct и @PreDestroy
Эти две аннотации в основном используются в качестве обратных вызовов жизненного цикла. Следующее:
public class ConstructBean {
@PostConstruct
public void populateMovieCache() {
// populates the movie cache upon initialization...
}
@PreDestroy
public void clearMovieCache() {
// clears the movie cache upon destruction...
}
}
Как и @Resource, типы аннотаций @PostConstruct и @PreDestroy являются частью стандартной библиотеки Java JDK 6–8. Однако весь пакет javax.annotation был отделен от основных модулей Java в JDK 9 и в конечном итоге удален в JDK 11. Артефакт javax.annotation-api теперь должен быть доступен через maven Central, если это необходимо, просто добавьте его в путь к классам приложения, как и любую другую библиотеку.
Код этой статьи может относиться кannotation-config
Дополнительные руководства см.блог флайдина