Med*_*edo 7 java spring dependency-injection
以Spring @Autowired和@Qualifier为参考
我们有以下示例可解决自动装配冲突:
public interface Vehicle {
public void start();
public void stop();
}
Run Code Online (Sandbox Code Playgroud)
有两个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();
}
}
Run Code Online (Sandbox Code Playgroud)
这是解决此问题的一个很好的例子。
但是,当我遇到相同的问题但在应用程序上下文中没有这些问题时:
<context:component-scan></context:component-scan>
<context:annotation-config></context:annotation-config>
Run Code Online (Sandbox Code Playgroud)
所有问题都可以通过使用@Qualifier注释来解决,但在我的情况下,我们不会使用允许使用注释的平台。
问题是 :
我如何仅使用应用程序上下文中的配置来解决此问题,而不使用注释?
我进行了很多搜索,发现有人autowire在bean声明中谈论属性,因此<bean id="dao" class="package.IDao" autowire="byName"></bean>我需要更多解释。
如何仅在应用程序上下文中使用配置来解决此问题?
您可以使用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>
Run Code Online (Sandbox Code Playgroud)
我发现有人在bean声明中谈论autowire属性,我需要更多有关它的解释
使用注释
@Autowired在bean声明方法上使用的方法将(另一个)已声明的bean注入定义的依赖项。现在,如果依赖项位于应用程序的同一上下文中,则根本不需要使用@Autowired批注,因为Spring能够自行找出它们。因此,如果您的依赖项不在您的应用上下文中,则可以使用它。
例如,参考以下代码:
@Autowired
@Bean
public MyBean getMybean(Dependency1 depdency1, Dependency2 depdency2) {
return new MyBean(depdency1.getSomeStuff(), depdency2.getSomeOtherStuff());
}
Run Code Online (Sandbox Code Playgroud)
在这里,@Autowired会发现一个实例Dependency1,并Dependency2并为他们提供创作的一个实例MyBean。
使用xml配置
从Pro Spring 5开始,Spring支持五种自动装配模式。
byName:使用byName自动装配时,Spring尝试将每个属性连接到同名的Bean。因此,如果目标Bean具有一个名为的属性,foo并且在foo中定义了一个Bean ApplicationContext,则该fooBean将分配给foo目标的属性。byType:使用byType自动装配时,Spring尝试通过自动使用中的相同类型的bean 来连接目标bean上的每个属性
ApplicationContext。constructor:此功能类似于byType接线,除了它使用构造函数而不是setter来执行注入。Spring尝试匹配构造函数中可以匹配的最大数量的参数。因此,如果您的bean有两个构造函数,一个接受a,另一个接受a String和Stringan Integer,并且您String的Integerbean 和a都包含ApplicationContext,则Spring使用两个参数的构造函数。default:Spring将自动在constructor和byType模式之间进行选择。如果您的bean具有默认(无参数)构造函数,则Spring使用
byType; 否则,它使用构造函数。no:这是默认设置因此,在您的情况下,您需要执行以下操作(但是,我不建议这样做。为什么?,您需要将Vehicleclass 声明为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() {
//...
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,尝试使用xml config进行此操作有很多麻烦,因此,如果可能的话,我建议您使用注释选项。
相关文章:
PS:我尚未测试任何发布的代码。
您可以使用@Primary代替@Qualifier
@Primary
@Component(value="bike")
public class Bike implements Vehicle {
Run Code Online (Sandbox Code Playgroud)
当有多个相同类型的bean时,我们使用@Primary给予一个bean更高的优先级。
我们可以直接在bean上使用@Primary
您还可以在XML中设置主要属性:
属性具有主要属性:
Run Code Online (Sandbox Code Playgroud)<bean primary="true|false"/>如果通过XML声明了@Primary批注的类,则@Primary批注元数据将被忽略,而是被尊重。
| 归档时间: |
|
| 查看次数: |
415 次 |
| 最近记录: |