Spring Core与xml配置中的自动装配冲突

时间:2019-04-08 11:52:03

标签: java spring dependency-injection

以帖子Spring @Autowired and @Qualifier

为参考

我们有这个示例来解决自动装配冲突:

public interface Vehicle {
     public void start();
     public void stop();
}

有两个bean,CarBike实现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批注来解决,但就我而言,我们不会使用允许使用批注的栏杆。

问题是:

如何仅在应用程序上下文中使用配置来解决此问题,就是这样,不使用注释

我搜索了很多内容,I found people talking about autowire attribute in the bean declaration <bean id="dao" class="package.IDao" autowire="byName"></bean>,并且需要更多说明。

2 个答案:

答案 0 :(得分:7)

  

如何仅使用应用程序中的配置来解决此问题   上下文?

您可以像下面那样使用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>
  

我发现人们在谈论bean中的autowire属性   宣言,我需要更多的解释

使用注释

在bean声明方法上使用的

@Autowired通过(另一个)声明的bean注入定义的依赖项。现在,如果依赖项位于应用程序的同一上下文中,则根本不需要使用@Autowired批注,因为Spring能够自行找出它们。因此,如果您的依赖项不在您的应用上下文中,那么您可以使用它。

例如,参考以下代码:

@Autowired
@Bean
public MyBean getMybean(Dependency1 depdency1, Dependency2 depdency2) {
    return new MyBean(depdency1.getSomeStuff(), depdency2.getSomeOtherStuff());
}

在这里,@Autowired将找到Dependency1Dependency2的实例,并将为创建MyBean的实例提供它们。

使用xml配置

Pro Spring 5起... Spring支持五种自动装配模式。

  • byName:使用byName自动装配时,Spring尝试将每个属性连接到同名的bean。因此,如果目标bean具有名为foo的属性,并且在foo中定义了ApplicationContext bean,则foo bean被分配给以下对象的foo属性目标。
  • byType:使用byType自动装配时,Spring尝试连接每个 通过自动使用相同类型的Bean在目标Bean上的属性 ApplicationContext
  • constructor:此功能类似于byType接线,不同之处在于它使用构造函数而不是setter来执行注入。 Spring尝试匹配构造函数中可以匹配的最大数量的参数。因此,如果您的bean有两个构造函数,一个接受String,另一个接受StringInteger,并且您同时拥有String和{{1 }}在Integer中的bean中,Spring使用了两个参数的构造函数。
  • ApplicationContext:Spring将在defaultconstructor模式之间进行选择 自动。如果您的bean具有默认(无参数)构造函数,则Spring使用 byType;否则,它将使用构造函数。
  • byType:这是默认设置

因此,在您的情况下,您需要执行类似的操作(但是,我不建议这样做。为什么?,您需要将no类声明为Bean和不正确的组件,参见Spring: @Component versus @Bean。另一方面,我不确定是否可以仅将其声明为bean而使用它:

Vehicle

如您所见,尝试使用xml config进行此操作有很多麻烦,因此,我建议您尽可能使用注释选项。

相关帖子:

PS:我尚未测试任何发布的代码。

答案 1 :(得分:5)

您可以使用@Primary代替@Qualifier

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

当有多个相同类型的bean时,我们使用@Primary赋予bean更高的优先级。

     

我们可以直接在bean上使用@Primary

您还可以在XML中设置主要属性:

  

属性具有主要属性:

<bean primary="true|false"/>
     

如果通过XML声明了@Primary注释的类,则@Primary注释元数据将被忽略,而是被尊重。