Spring:为什么我们自动连接接口而不是实现的类?

sta*_*low 136 java spring dependency-injection

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();
}
Run Code Online (Sandbox Code Playgroud)

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

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

Vik*_*dor 213

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

只要只有一个接口实现,并且该实现在@Component启用S​​pring的组件扫描时进行注释,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();
}
Run Code Online (Sandbox Code Playgroud)

您的bean配置应如下所示:

<bean id="b" class="B" />
<bean id="c" class="C" />
<bean id="runner" class="MyRunner" />
Run Code Online (Sandbox Code Playgroud)

或者,如果您在包中存在组件扫描,那么您应该@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();
}
Run Code Online (Sandbox Code Playgroud)

然后,workerMyRunner将与类型的实例注入B.

  • 如果将限定符设置为“b”,那么这不是完全等同于“IA worker=new B();”吗?为什么要使用 DI 容器?对我来说,您似乎可以使用基于构造函数的依赖注入并手动实例化类 (2认同)