【问题标题】:Autowiring conflict in spring core with the xml configurationSpring核心中的自动装配冲突与xml配置
【发布时间】:2019-08-29 13:38:37
【问题描述】:

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 &lt;bean id="dao" class="package.IDao" autowire="byName"&gt;&lt;/bean&gt;,我需要更多关于它的解释。

【问题讨论】:

标签: java spring dependency-injection


【解决方案1】:

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

你可以像下面这样使用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 属性 声明,我需要更多解释

使用注解

@Autowired 用于 bean 声明方法通过(另一个)声明的 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 的属性,并且在 ApplicationContext 中定义了一个 foo bean,则将 foo bean 分配给目标的 foo 属性。
  • byType:使用 byType 自动装配时,Spring 会尝试连接每个 通过自动使用相同类型的 bean 在目标 bean 上的属性 ApplicationContext
  • constructor:这个功能就像byType 连线一样,只是它使用构造函数而不是setter 来执行注入。 Spring 尝试在构造函数中匹配最大数量的参数。因此,如果您的 bean 有两个构造函数,一个接受 String,一个接受 StringInteger,并且您的 ApplicationContext 中同时有 StringInteger bean,Spring使用两个参数的构造函数。
  • default:Spring 将在 constructorbyType 模式之间进行选择 自动地。如果您的 bean 具有默认(无参数)构造函数,则 Spring 使用 byType;否则,它使用构造函数。
  • no:这是默认的

所以,在你的情况下,你需要做这样的事情(但是,我不推荐它。为什么?你需要将 Vehicle 类声明为一个 bean 和一个不正确的组件,请参阅 @ 987654324@。另一方面,我不确定您是否可以将其声明为 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:我没有测试任何发布的代码。

【讨论】:

  • 感谢您的帮助
【解决方案2】:

您可以使用@Primary 代替@Qualifier

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

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

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

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

属性具有主要属性:

<bean primary="true|false"/>

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-03
    • 2017-03-31
    • 2013-10-14
    • 1970-01-01
    • 2018-09-18
    • 1970-01-01
    • 2020-09-09
    • 2018-06-15
    相关资源
    最近更新 更多