jack716
71
2017-09-05 23:26:17
6
5120

스프링 @Autowired와 인터페이스관련 질문드립니다


스프링을 배우고 있는데요

아래처럼


@Controller
public class HomeController {
        // 경우 1번
        @Autowired
        private ServiceInterface service;

        // 경우 2번
        @Autowired
        private Service service;

        @RequestMapping(value = "/", method = RequestMethod.GET)
        public String home(Locale locale, Model model) {
                return "main";
        }
}


경우 1처럼

@Autowired

private 인터페이스 service;

라고 하는 경우


경우 2처럼

private 인터페이스를 구현한 클래스 service;

라고 하는 경우가 있던데요..



물론 둘 다 작동은 되던데,,

어떤게 더 제대로 쓰는건가요 ?


구현한 클래스에 @Service 어노테이션을 붙여주기 때문에 저는 경우 1번처럼 알고 있었다가

경우 2번으로 쓰는 예제를 발견하고 또 저렇게 해보니 작동이 되기에 질문드립니다...

0
0
  • 답변 6

  • 알트키
    128
    2017-09-06 00:31:26

    저도 아직 공부하고입장이지만. 정확히 모르겠습니다.

    인터페이스 이름이 Service인가요? ServiceInterface 인건가요? 혹시 Bean 으로 만들어 두신건가요?


    저도 오토와이어드를 어떻게 좀더 제대로 써볼가 하다가 찾은것이 있는데요..

    필드에 오토와이어드를 했을때보다 생성자에 하는쪽이 좀더 안전하고 좋다고 들었습니다. 아래 링크로 대체하겠습니다.

    https://stackoverflow.com/questions/40620000/spring-autowire-on-properties-vs-constructor

    http://olivergierke.de/2013/11/why-field-injection-is-evil/



    0
  • javaing
    2k
    2017-09-06 01:29:58
    // 경우 1번
    @Autowired
    private Service service;
    
    // 경우 2번
    @Autowired
    private ServiceImpl service;


    2번의 방법으로 하실 경우 ServiceImpl이라는 클래스에 제한되기 때문에 1번의 방법처럼 인터페이스를 사용합니다



    0
  • jack716
    71
    2017-09-06 08:46:35 작성 2017-09-06 08:47:04 수정됨

    알트키님 javaing님 두분다 답변 감사합니다

    0
  • asd
    16k
    2017-09-06 08:52:49

    다형성에 관련된 주제인데요. 기본적으로 Autowired는 그냥 변수에 값을 넣어주는것 뿐이기때문에 인터페이스로 참조하든, 구현클래스로 참조하든 타입만 맞으면 돌아가는덴 아무런 지장이 없습니다.

    Autowired의 작동방식은

    1. 타입이 일치하는가

    2. 빈 명과 변수명이 일치하는가

    로 작동합니다. 즉 인터페이스로 참조해도 문제가 없지만 만약 그 인터페이스를 구현한 구현클래스가 2개 이상일경우 1번 조건에서 타입이 일치하는게 2개 이상이므로 어떤걸 주입해야할지 알 수 없어 예외가 발생합니다. 다만 2개 이상의 빈 중 변수명과 일치하는 명칭을 가진 빈이 있다면 그 빈을 주입하게되는데요. 이런경우 가독성부분에 상당히 문제가 생기기때문에 Autowired를 사용할때는 보통 1번 조건만 생각하고 사용합니다. 구현클래스가 2개 이상일 경우는 @Qualifier를 쓰거나 @Resource 애노테이션을 사용하고요.


    다시 본론으로 돌아와서 '인터페이스로 참조하는게 좋은가, 구현클래스로 참조하는게 좋은가?'에 대해선 이펙티브 자바 규칙을 인용하겠습니다.

    규칙 52. 객체를 참조할 때는 그 인터페이스를 사용하라

    0
  • jack716
    71
    2017-09-06 18:56:48

    LichKing님 답변 감사합니다.

    0
  • seya330
    128
    2017-09-07 11:48:36

    저도 아직 배우는 입장이지만 service라는 변수로 di받은 경우에 사용하는 함수가 인터페이스 내에 정의되어 있는 함수만 사용할 경우에는 결합도를 느슨히 하기위해 인터페이스를 사용하고, 인터페이스내에 정의되어 있지 않은 serviceImpl  객체 내에만 정의되어 있는 함수를 사용할 경우가 있을 때 에는 serviceImpl 로 di를 받는다고 알고 있습니다.

    0
  • 로그인을 하시면 답변을 등록할 수 있습니다.