위 내용은 https://youtu.be/C6nsjqrCJq4 백기선님의 유튜브에서 발췌했습니다.
만약 위와 같은 에러가 발생했다라면?
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'defaultMyService' could not be injected as a 'com.example.demo.DefaultMyService' because it is a JDK dynamic proxy that implements:
com.example.demo.MyService
Action:
Consider injecting the bean as one of its interfaces or forcing the use of CGLib-based proxies by setting proxyTargetClass=true on @EnableAsync and/or @EnableCaching.
들어가기
의존성 주입시, 인터페이스가 있는 경우, 인터페이스 타입을 쓰라고 권장하고 있습니다. 실제로 유지보수하고 있는 서비스의 클래스 구조를 살펴보면 인터페이스&인터페이스구현체 가 짝꿍처럼 만들어집니다.
물론 객체지향을 추구하는 부분도 있습니다. 확장성을 위한 부분도 있습니다. 동영상에서 말하는 더 큰 문제는 따로 있습니다.
다시한번, 인터페이스를 쓰지 않을 때 더 큰 문제가 발생할 수 있습니다. 언제 발생할 수 있을까? Spring Boot 에서는 spring.aop.proxy-target-class 해당 속성이 기본으로는 true로 설정되어 있습니다.
이 설정의 의미는 무엇일까요?
Aop Proxy 를 생성할 때 클래스를 기반으로 Proxy 를 생성할 것인가? 인터페이스 기반으로 Proxy를 생성할 것인가? 를 의미합니다.
클래스 기반으로 Proxy 를 생성시 cgLib, 인터페이스 기반으로 만들 때는 jdk에 들어있는 다이나믹프록시를 사용합니다.
Aop 클래스가 필요하지 않는 상황에서는 문제가 없지만,Hibernate 를 사용할 상황에서는 문제가 발생합니다.
해당 속성을 False 로 하고 아래코드을 동작시킨다면, 가장 상위에 있는 에러를 발견할 수 있습니다.
import javax.transaction.Transactional;
public interface MyService {
@Transactional
void doSomething();
}
@SpringBootApplication
public class DemoApplication {
@Autowired
DefaultMyService myService;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
ApplicationRunner applicationRunner() {
return (args) -> {
myService.doSomething();
};
}
}
DefaultMyService 가 아니라 MyService 로 지정할 경우에는 예외가 발생하지 않습니다.
이쯤에서 왜 안되는지 다시한번 생각해봅시다.
> MyService ---> DefaultMyService
> MyService ---> ProxyMyService
똑같은 MySerivce 를 subClass로 사용하지만, DefaultMyService 와 ProxyMySerivce 는 다른 객체입니다.
만약 spring.aop.proxy-target-class 을 True 로 설정한다면 이제 아래와 같은 계층 구조를 가지게 될 것입니다.
> MyService ---> DefaultMyService ----> ProxyMyService
그럼 생성자 주입시, 인터페잇 또는 구현체를 넣어도 아무런 문제가 발생하지 않습니다.
'Spring 이해하기' 카테고리의 다른 글
SpringMVC 에서 말하는 MessageConverter 코드로 이해하기 (6) | 2021.08.15 |
---|---|
[JPA] JoinColumn vs mappedBy (0) | 2021.06.13 |
[JPA] Collection 을 업데이트 할때, add()와 addAll() 을 조심하자. (0) | 2021.06.05 |
Spring Data JDBC 가볍게 살펴보기 - 1 (0) | 2021.05.09 |
Gradlew Command 살펴보기 (0) | 2021.01.27 |
댓글