Bean-инъекция через аннотацию
задний план
Говоря о Spring, мы обязательно упомянем IOC-контейнер и внедрение зависимостей DI.Спринг достигает эффекта инверсии управления, внедряя в IOC-контейнер методы маркировки классов как bean-компонентов. Итак, когда мы впервые столкнулись с bean-компонентами, мы должны использовать xml-файлы и внедрять их один за другим, как показано ниже.
<bean id="bean" class="beandemo.Bean" />
Если наш проект, как правило, очень большой, нам нужно использовать сотни bean-компонентов, что очень громоздко писать. Затем Spring помогает нам реализовать метод внедрения через аннотации. Просто добавьте соответствующие аннотации перед классами, которые вам нужно внедрить, и Spring поможет нам отсканировать их для внедрения.
пакет сканирования xml
<context:component-scan base-package="com.company.beandemo"/>
Общая форма инъекции через аннотацию
При нормальных обстоятельствах инъекция bean-компонентов имеет самый простой и понятный способ добиться инъекций.Следующую ерунду говорить не будем, а код выложим первым.
- Класс бобов
public class MyBean{
}
- Класс конфигурации
//创建一个class配置文件
@Configuration
public class MyConfiguration{
//将一个Bean交由Spring进行管理
@Bean
public MyBean myBean(){
return new MyBean();
}
}
- Тестовый класс
Немного отличаясь от xml, здесь, в тесте, созданием экземпляра является уже не ClassPathXmlApplicationContext, а полученный экземпляр AnnotationConfigApplicationContext.
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfiguration.class);
MyBean myBean = cotext.getBean("myBean",MyBean.class);
System.out.println("myBean = " + myBean);
MyBean в приведенном выше коде — это Bean, для управления которым нам нужен Spring, это всего лишь простой класс. В MyConfiguration мы сначала помечаем класс аннотацией @Configuration, которая указывает, что класс является классом конфигурации Spring, который будет загружаться при загрузке конфигурации.
В MyConfiguration мы видим, что есть метод, который возвращает экземпляр MyBean, и этот метод помечен аннотацией @Bean, указывающей, что это метод внедрения Bean, и следующий возвращаемый Bean будет внедрен в IOC.
Внедрение bean-компонентов через конструктор
Когда мы создаем экземпляр Bean, мы можем использовать конструктор Bean для внедрения реализации Bean. смотри прямо на код
- Класс бобов
@Component
public class MyBeanConstructor {
private AnotherBean anotherBeanConstructor;
@Autowired
public MyBeanConstructor(AnotherBean anotherBeanConstructor){
this.anotherBeanConstructor = anotherBeanConstructor;
}
@Override
public String toString() {
return "MyBean{" +
"anotherBeanConstructor=" + anotherBeanConstructor +
'}';
}
}
- Другой класс
@Component(value="Bean的id,默认为类名小驼峰")
public class AnotherBean {
}
- Класс конфигурации
@Configuration
@ComponentScan("com.company.annotationbean")
public class MyConfiguration{
}
Здесь мы можем обнаружить, что он отличается от кода, внедряемого обычным способом.Давайте посмотрим, что означают новые аннотации:
- @AutoWired
Просто и грубо, прямой перевод означает автоматическую сборку :wrench: , я так и не понял, почему она называется автоматической сборкой :wrench: ? Прочтите объяснение следующей аннотации, и вы все узнаете. Если вы укажете идентификатор bean-компонента при внедрении здесь, используйте аннотацию @Qualifier
- @Component (одноэлементный режим по умолчанию)
Какие? ? Это переводится на запчасти, как это похоже на ремонт автомобиля? ? Да, как Spring управляет бобами, так и ремонтирует автомобили. Когда нам нужно превратить класс в Bean, который может быть инжектирован Spring, добавляем компонент аннотации @Conmonent, тогда мы можем собрать его как компонент при загрузке Bean:wrench: в эту машину IOC
Здесь у нас есть несколько других аннотаций, которые также могут выполнять эту функцию, то есть уточненный @Component:
-
- @Controller аннотируется на уровне контроллера
- @Service аннотируется на уровне службы
- @Repository аннотируется на уровне dao
- @ComponentScan("")
Или перевод, сканирование частей, давайте посмотрим, какие "части" (классы) нужно загрузить на "склад деталей" в скобках, Spring просканирует пакет и введет в него все классы, помеченные @Component.
Инъекцию через метод построения здесь понять несложно.Когда мы собираем часть MyBean, то вдруг обнаруживаем, что она должна быть установлена в IOC на основе AnotherBean, тогда мы будем автоматически собирать ее каждый раз при сборке MyBean :wrench:An Входит другой компонент. Возьмите :chestnut: например:
Или возьмем, к примеру, автомобиль: нужно ли нам начинать, прежде чем нажать на педаль газа? ? Контент AutoWired тут как стартовый.Если не запустить, будет бесполезно, если нажмете на акселератор, и он не уйдет.
Внедрить Beans через метод set
Мы можем установить атрибут метода для внедрения реализации Бина, посмотрите на код, который он
- класс MyBean
@Component
public class MyBeanSet {
private AnotherBean anotherBeanSet;
@Autowired
public void setAnotherBeanSet(AnotherBean anotherBeanSet) {
this.anotherBeanSet = anotherBeanSet;
}
@Override
public String toString() {
return "MyBeanSet{" +
"anotherBeanSet=" + anotherBeanSet +
'}';
}
}
- Класс конфигурации и тестовый класс
То же, что и предыдущий, не опубликовано
Здесь мы обнаруживаем, что у нас есть @AutoWired в методе установки.В отличие от предыдущего, мы не подключаем автоматически объект :wrench: при создании экземпляра класса, а вместо этого подключаем его, когда установщик вызывается явно.
Внедрить Beans через свойства
Наши предыдущие два метода внедрения, такие как время, отличаются, и кодов больше.Если это через атрибуты, это
@Component
public class MyBeanProperty {
@Autowired
private AnotherBean anotherBeanProperty;
@Override
public String toString() {
return "MyBeanProperty{" +
"anotherBeanProperty=" + anotherBeanProperty +
'}';
}
}
Здесь мы видим, что нам нужно использовать объект экземпляра AnotherBean в нашем классе, и мы можем автоматически подключить его через @AutoWired.
Для некоторых небольших партнеров, которые спрашивают о частных свойствах, как Spring загружает их в IOC? Рекомендую посмотреть отражение
Внедрить бины через список
- класс MyBeanList
@Component
public class MyBeanList {
private List<String> stringList;
@Autowired
public void setStringList(List<String> stringList) {
this.stringList = stringList;
}
public List<String> getStringList() {
return stringList;
}
}
- Класс MyConfiguration
@Configuration
@ComponentScan("annoBean.annotationbean")
public class MyConfiguration {
@Bean
public List<String> stringList(){
List<String> stringList = new ArrayList<String>();
stringList.add("List-1");
stringList.add("List-2");
return stringList;
}
}
Здесь мы внедряем MyBeanList, и элементы списка будут внедряться один за другим. Вот еще один способ внедрить список
- Класс MyConfiguration
@Bean
//通过该注解设定Bean注入的优先级,不一定连续数字
@Order(34)
public String string1(){
return "String-1";
}
@Bean
@Order(14)
public String string2(){
return "String-2";
}
Внедрение того же типа, что и универсальный тип в список, автоматически соответствует типу.Даже если нет никакого смысла в списке, это просто тип String, но он будет внедрен через компонент списка.
Приоритет второго метода выше, чем у первого метода.Когда оба существуют, если вы хотите принудительно использовать первый метод, вам нужно указать идентификатор компонента.
Внедрить бобы через карту
@Component
public class MyBeanMap {
private Map<String,Integer> integerMap;
public Map<String, Integer> getIntegerMap() {
return integerMap;
}
@Autowired
public void setIntegerMap(Map<String, Integer> integerMap) {
this.integerMap = integerMap;
}
}
@Bean
public Map<String,Integer> integerMap(){
Map<String,Integer> integerMap = new HashMap<String, Integer>();
integerMap.put("map-1",1);
integerMap.put("map-2",2);
return integerMap;
}
@Bean
public Integer integer1(){
return 1;
}
@Bean
public Integer integer2(){
return 2;
}
Есть также два способа внедрения Beans типа Map, и второе значение приоритета выше, чем первое.
Выше приведены несколько способов внедрения Bean через аннотации.Вы можете сравнить способ внедрения xml.