Конфликт автопроводки в ядре пружины с конфигурацией xml - PullRequest
7 голосов
/ 08 апреля 2019

Принимая в качестве ссылки пост 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 id="dao" class="package.IDao" autowire="byName"></bean>, и мне нужно больше объяснений по этому поводу.

Ответы [ 2 ]

7 голосов
/ 08 апреля 2019

Как я могу исправить эту проблему, просто используя конфигурацию в контексте приложения?

Вы можете использовать тег 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>

Я нашел людей, говорящих об атрибуте autowire в объявлении bean, и мне нужно больше объяснений по этому поводу

Использование аннотации

@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

С Pro Spring 5 ... Spring поддерживает пять режимов автоматического подключения.

  • byName: При использовании автоматического подключения byName Spring пытается связать каждое свойство с бином с одинаковым именем.Таким образом, если целевой компонент имеет свойство с именем foo, а в ApplicationContext определен компонент foo, компоненту 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 класс как компонент и компонент, который не является корректным, см. 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: я не проверял ни один из опубликованных кодов.

5 голосов
/ 08 апреля 2019

Вы можете использовать @ Primary вместо @Qualifier

@Primary
@Component(value="bike")
public class Bike implements Vehicle {

мы используем @Primary, чтобы отдавать предпочтение бину, когда есть несколько бинов одного типа.

Мы можем использовать @Primary непосредственно на бобах

Вы также можете установить основной атрибут в XML :

свойство имеет основной атрибут:

<bean primary="true|false"/>

Если @ Primary-аннотированный класс объявлен через XML, метаданные @Primary annotation игнорируются и вместо этого учитываются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...