示例
interface IA
{
public void someFunction();
}
@Resource(name="b")
class B implements IA
{
public void someFunction()
{
//busy code block
}
public void someBfunc()
{
//doing b things
}
}
@Resource(name="c")
class C implements IA
{
public void someFunction()
{
//busy code block
}
public void someCfunc()
{
//doing C things
}
}
class MyRunner
{
@Autowire
@Qualifier("b")
IA worker;
worker.someFunction();
}
有人可以向我解释一下。
@Qualifier
还是@Resource
? 答案 0 :(得分:195)
spring如何知道要使用哪种多态类型。
只要接口只有一个实现,并且在启用Spring的组件扫描的情况下使用@Component
注释该实现,Spring框架就可以找到(接口,实现)对。如果未启用组件扫描,则必须在application-config.xml(或等效的spring配置文件)中显式定义bean。
我需要@Qualifier还是@Resource?
如果您有多个实现,那么您需要对每个实现进行限定,并且在自动布线期间,您需要使用@Qualifier
注释来注入正确的实现,以及@Autowired
注解。如果您正在使用@Resource(J2EE语义),那么您应该使用此批注的name
属性指定bean名称。
为什么我们要自动连接接口而不是实现的类?
首先,对一般的接口进行编码始终是一个好习惯。其次,在spring的情况下,您可以在运行时注入任何实现。一个典型的用例是在测试阶段注入模拟实现。
interface IA
{
public void someFunction();
}
class B implements IA
{
public void someFunction()
{
//busy code block
}
public void someBfunc()
{
//doing b things
}
}
class C implements IA
{
public void someFunction()
{
//busy code block
}
public void someCfunc()
{
//doing C things
}
}
class MyRunner
{
@Autowire
@Qualifier("b")
IA worker;
....
worker.someFunction();
}
您的bean配置应如下所示:
<bean id="b" class="B" />
<bean id="c" class="C" />
<bean id="runner" class="MyRunner" />
或者,如果您在包中存在组件扫描,那么您应该使用@Component
限定每个类,如下所示:
interface IA
{
public void someFunction();
}
@Component(value="b")
class B implements IA
{
public void someFunction()
{
//busy code block
}
public void someBfunc()
{
//doing b things
}
}
@Component(value="c")
class C implements IA
{
public void someFunction()
{
//busy code block
}
public void someCfunc()
{
//doing C things
}
}
@Component
class MyRunner
{
@Autowire
@Qualifier("b")
IA worker;
....
worker.someFunction();
}
worker
中的MyRunner
将注入B
类型的实例。
答案 1 :(得分:1)
此外,它可能会导致像Cglib2AopProxy Unable to proxy method这样的日志中出现一些警告。此处描述了许多其他原因Why always have single implementaion interfaces in service and dao layers?