171

例子

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();
}

谁可以给我解释一下这个。

  • spring 如何知道使用哪种多态类型。
  • 我需要@Qualifier还是@Resource
  • 为什么我们自动装配接口而不是实现的类?
4

3 回答 3

254

spring 如何知道使用哪种多态类型。

只要接口只有一个实现,并且该实现被注释为@Component启用了 Spring 的组件扫描,Spring 框架就可以找到 (interface, implementation) 对。如果未启用组件扫描,则必须在 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();
}

然后workerinMyRunner将被注入一个 type 的实例B

于 2012-10-15T15:57:35.983 回答
1

此外,它可能会导致日志中出现一些警告,例如Cglib2AopProxy Unable to proxy method。这里描述了许多其他原因为什么在服务层和 dao 层中总是有单个实现接口?

于 2015-09-22T11:29:38.893 回答
0

仅当我在 .XML 配置文件中声明以下 bean 时它才对我有用,因为@Autowired是一个后期处理

<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"></bean>
于 2022-02-05T22:06:00.423 回答