인터페이스 빈 주입을 해야하는 이유
2022. 5. 15. 23:34ㆍSpring
왜 인터페이스 빈 주입을 해야할까?
- 실무에서 개발을 할 때 인터페이스 구현을 받은 클래스에 빈주입을 하고 있는 와중 사수님이 되도록이면 클래스에 빈주입보다는 인터페이스에 빈 주입을 하는것이 확장성에도 좋다고 말씀하셨다...😳 (찾아봐야겠군...)
그렇다면 뭐가 좋은지 찾아보자
- 비슷한 내용으로 백기선님의 영상을 한번 살펴보고 Let s get it
인터페이스가 있을 땐 그걸 쓰는 이유 with whiteShip
전체코드
인터페이스
public interface MyService { void doSomething(); }
서비스
@Service public class MyserviceImpl implements MyService { @Override public void doSomething() { System.out.println("hello Im Impl Service"); } }
application.properties
spring.aop.proxy-target-class=false
정리
위와 같은 서비스가 있다. 그렇다면 Controller에서 Service를 두 가지 방법으로 주입 받을 수 있다.
- MyService 를 타입으로 하는 (인터페이스 타입) 빈주입
- MyServiceImpl 을 타입으로 하는 (클래스 타입) 빈주입
또한 properties 파일을 보게되면
proxy-target-class
설정을 false로 하였는데, 다음 설정은 클래스를 이용한@Service
빈 주입을 할 수 없다는 뜻이다.Spring Boot
에서는Default
값이true
이다.
그렇다면 Controller에서는 어떻게 빈 주입을 해야할까?
Example Code
@Autowired MyServiceImpl myService; @Bean ApplicationRunner applicationRunner() { return (args) -> { myService.doSomthing(); }; }
위와 같은 코드에서 빌드를 하게되면 어떻게 될까?
→ 에러가 발생한다. (Why???)
빈 주입 현황
- MyService → DefaultMyService
- MyService → ProxyMyService
ProxyMyService
는MyService
타입이다.DefaultMyService
도MyService
타입이다.- 하지만...!
ProxyMyService
는DefaultMyService
타입이 아니다.
그렇기 때문에 밑의 코드처럼 MyServiceImpl로 빈 주입을 받아 올 수 없는 것이다.
@Autowired
MyServiceImpl myService;
@Bean
ApplicationRunner applicationRunner() {
return (args) -> {
myService.doSomthing();
};
}
- 그렇기 때문에 직관적으로 상충이 된다.
MyServiceImpl
클래스를 보면 @Service 어노테이션을 붙여서 내가 빈주입을 하겠다. 라고 했는데 에러가 났으니...? - 그래서 Spring Boot에서는
spring.aop.proxy-target-class=false
의 코드가 true 로 Default 값으로 되어있다. 그래서 Spring Boot에서 위와 같은 코드를 실행하여도 문제 없다.!!! Spring Boot에서는 MyService → DefaultService → ProxyMyService 로 변경해놓았다. (spring.aop.proxy-target-class=ture
일 때 )
결론
- MyService 타입으로 하는 (인터페이스 타입) 빈 주입
@Autowired private MyService myservice;
- 구현 상속 관계 : MyService → MyServiceImpl
- 프록시 상속 관계 : MyService → ProxyMyService
따라서 ProxyMyService 가 인터페이스인 MyService를 상속 받는다.
- MyServiceImpl을 타입으로 하는 (클래스 타입) 빈 주입
@Autowired private MyServiceImpl myService;
- 구현 상속 관계 : MyService → MyServiceImpl
- 프록시 상속 관계 : MyServiceImpl → ProxyMyService
- MyService → DefaultService → ProxyMyService*
'Spring' 카테고리의 다른 글
In-memory 왜써? TestContainer쓰자! (0) | 2024.07.11 |
---|---|
RequiredArgsConstructor VS Qualifier 빈 주입 (0) | 2022.05.15 |
[Spring] BDDMockito VS Mockito (0) | 2021.08.12 |
[Spring] TDD VS BDD (0) | 2021.08.12 |
@Mock객체를 사용해서 Page타입 객체 테스트코드 작성하기 (3) | 2021.07.29 |