Взяв за ссылку пост Spring @Autowired и @Qualifier
У нас есть этот пример, чтобы исправить конфликт автопроводки:
public interface Vehicle {
public void start();
public void stop();
}
Есть два bean-компонента, Car
и Bike
, реализующие Vehicle
интерфейс.
@Component(value = "car")
public class Car implements Vehicle {
@Override
public void start() {
System.out.println("Car started");
}
@Override
public void stop() {
System.out.println("Car stopped");
}
}
@Component(value = "bike")
public class Bike implements Vehicle {
@Override
public void start() {
System.out.println("Bike started");
}
@Override
public void stop() {
System.out.println("Bike stopped");
}
}
@Component
public class VehicleService {
@Autowired
@Qualifier("bike")
private Vehicle vehicle;
public void service() {
vehicle.start();
vehicle.stop();
}
}
Это очень хороший пример решения этой проблемы.
Но когда у меня такая же проблема, но без этих балисов в контексте приложения:
<context:component-scan></context:component-scan>
<context:annotation-config></context:annotation-config>
Все вопросы решаются с помощью аннотации @Qualifier
, но в моем случае мы не используем бальзам, разрешающий использовать аннотацию.
Вопрос в том :
Как я могу исправить эту проблему, просто используя конфигурацию в контексте приложения, вот и все, без использования аннотаций?
Я много искал и Я обнаружил, что люди говорят об атрибуте autowire
в объявлении bean-компонента <bean id = "dao" class = "package.IDao" autowire = "byName"></bean>
, и мне нужно больше объяснений по этому поводу.
Вы можете использовать @Начальный вместо @Qualifier
@Primary
@Component(value = "bike")
public class Bike implements Vehicle {
we use @Primary to give higher preference to a bean when there are multiple beans of the same type.
We can use @Primary directly on the beans
Вы также можете установить основной атрибут в XML:
property has primary attribute:
<bean primary = "true|false"/>
If a @Primary-annotated class is declared via XML, @Primary annotation metadata is ignored, and is respected instead.
How can I fix this issue just using the configuration in application context?
Вы можете использовать тег qualifier
, как показано ниже (см. https://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-autowired-annotation-qualifiers)
<context:annotation-config/>
<beans>
<bean class = "your_pkg_route.Vehicle">
<qualifier value = "bike"/>
</bean>
</beans>
</context:annotation-config>
I found people talking about autowire attribute in the bean declaration and I need more explanation about it
Использование аннотации
@Autowired
, используемый в методе объявления bean-компонента, вводит определенные зависимости (другим) объявленным bean-компонентом. Теперь, если ваши зависимости находятся в том же контексте вашего приложения, вам вообще не нужно использовать аннотацию @Autowired
, потому что Spring может понять их самостоятельно. Итак, если ваши зависимости находятся вне контекста вашего приложения, вы можете его использовать.
Например, возьмите в качестве ссылки приведенный ниже код:
@Autowired
@Bean
public MyBean getMybean(Dependency1 depdency1, Dependency2 depdency2) {
return new MyBean(depdency1.getSomeStuff(), depdency2.getSomeOtherStuff());
}
Здесь @Autowired
найдет экземпляр Dependency1
и Dependency2
и предоставит их для создания экземпляра MyBean
.
Использование xml-конфигурации
From Про Spring 5... Spring поддерживает пять режимов автоматического подключения.
byName
: при использовании byName
автосвязывания Spring пытается связать каждое свойство с компонентом с тем же именем. Таким образом, если целевой компонент имеет свойство с именем foo
и компонент foo
определен в ApplicationContext
, компонент foo
назначается свойству foo
цели.byType
: при использовании byType
автосвязывания Spring пытается связать каждый из
свойств целевого компонента путем автоматического использования компонента того же типа в
ApplicationContext
.constructor
: это работает так же, как byType
проводка, за исключением того, что для выполнения инъекции используются конструкторы, а не сеттеры. Spring пытается сопоставить максимально возможное количество аргументов в конструкторе. Таким образом, если ваш bean-компонент имеет два конструктора, один из которых принимает String
, а другой принимает String
и Integer
, и у вас есть как String
, так и Integer
bean-компонент в вашем ApplicationContext
, Spring использует конструктор с двумя аргументами.default
: Spring будет выбирать между режимами constructor
и byType
.
автоматически. Если ваш компонент имеет конструктор по умолчанию (без аргументов), Spring использует
byType
; в противном случае он использует конструктор.no
: это значение по умолчаниюИтак, в вашем случае вам нужно будет сделать что-то вроде этого (НО, я бы НЕ рекомендовал это. Почему?, вам нужно будет объявить класс Vehicle
как bean-компонент и компонент, что неверно, см. Spring: @Component против @Bean. С другой стороны Я не уверен, что вы могли бы использовать его, просто объявив его как bean-компонент):
// xml config
<context:annotation-config/>
<beans>
// use the primary tag here too! in order to say this the primary bean
// this only works when there are only two implementations of the same interface
<bean id = "bike" primary = "true" class = "your_pkg_route.Bike"/>
<bean id = "car" class = "your_pkg_route.Car"/>
<bean autowire = "byName" class = "your_pkg_route.VehicleService"/>
<beans>
</context:annotation-config>
// VehicleService
@Component
public class VehicleService {
private Vehicle bike; // call attribute 'bike' so it is autowired by its name
public void service() {
//...
}
}
Как вы можете видеть, попытка сделать это с помощью конфигурации xml сопряжена с множеством сложностей, поэтому я бы порекомендовал вам использовать параметр аннотации, если это возможно.
Похожие сообщения:
PS: я не тестировал ни один из опубликованных кодов.
Спасибо за помощь