Spring : 왜 우리는 구현 된 클래스가 아닌 인터페이스를 자동 와이어 링합니까?


142

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?
  • 왜 우리는 구현 된 클래스가 아닌 인터페이스를 자동 와이어 링합니까?

10
인터페이스를 자동 와이어 링하여 다른 구현으로 연결할 수 있습니다 . 이는 클래스가 아니라 인터페이스에 대한 코딩 포인트 중 하나입니다.
Dave Newton

다른 구현으로 연결합니다. 질문을 이해하지 못합니다.
Dave Newton

인터페이스에서 배선하는 경우 Impl 클래스 내에 액세스해야하는 기본 가시성 메서드가 있으면 어떻게됩니까? 공용 인터페이스에는 기본 수정자가 포함될 수 없으므로 해당 메소드 스텁을 인터페이스에 추가 할 수 없습니다.
jlewkovich


1
하나의 구현을위한 인터페이스를 만드는 것은 자바 세계에서 받아 들여지는 어리석은 관행이라고 생각합니다. 그 결과 많은 가비지 코드가 생겨 났지만 모두 SOLID 및 OOP 규칙을 준수하게 된 것을 기쁘게 생각합니다. 가이드를 사용하고 역사의 쓰레기통에 봄을 던지십시오.
avgolubev

답변:


224

스프링은 어떤 다형성 유형을 사용해야하는지 어떻게 알 수 있습니까?

인터페이스의 단일 구현 만 있고 해당 구현 @Component에 Spring의 구성 요소 스캔이 활성화되어있는 한 Spring 프레임 워크는 (인터페이스, 구현) 쌍을 찾을 수 있습니다. 컴포넌트 스캔이 사용 가능하지 않으면 application-config.xml (또는 동등한 스프링 구성 파일)에서 Bean을 명시 적으로 정의해야합니다.

@Qualifier 또는 @Resource가 필요합니까?

구현이 두 개 이상인 경우 각 구현을 규정해야하며 자동 배선 중에 @Qualifier주석을 사용하여 주석과 함께 올바른 구현을 주입 해야합니다 @Autowired. @Resource (J2EE 시맨틱)를 사용하는 name경우이 주석 의 속성을 사용하여 Bean 이름을 지정해야합니다 .

왜 우리는 구현 된 클래스가 아닌 인터페이스를 자동 와이어 링합니까?

첫째, 일반적으로 인터페이스에 코드를 작성하는 것이 좋습니다. 둘째, 스프링의 경우 런타임에 모든 구현을 주입 할 수 있습니다. 일반적인 사용 사례는 테스트 단계에서 모의 ​​구현을 주입하는 것입니다.

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

그런 다음 workerin MyRunner유형의 인스턴스가 주입됩니다 B.


@stackoverflow 질문을 편집하는 것은 의미가 없으며 새로운 코드가 답에 속합니다. 그렇지 않으면 질문은 스스로 대답했을 것이기 때문에 의미가 없습니다.
Dave Newton

Vikdor-편집을 참조하십시오. 그것이 클래스와 주입 된 객체에 주석을 달 수있는 올바른 방법입니까?
stackoverflow

1
@VictorDombrovsky가 @Autowired @Qualifier("a1") a;유효합니까?
Lucky

1
@ 행운을 빌어 요 실수했습니다. 나는 의미@Autowired @Qualifier("a1") A a;
빅터 Dombrovsky에게

1
구현에서 @Profile을 사용하여 프로그램 인수 또는 응용 프로그램 속성을 통해 해당 인터페이스에 삽입 할 구현을 제어 할 수도 있습니다.
b15

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.