프록시를 사용하면 트랜잭션을 처리하는 객체와 비즈니스 로직을 처리하는 서비스 객체를 명확하게 분리할 수 있다.
스프링 AOP를 사용하기 위해선 프록시를 만들 객체가 스프링 빈에 등록이 되야한다.
@TestConfiguration
static class TestConfig{
@Bean
DataSource dataSource() {
return new DriverManagerDataSource(URL, USERNAME, PASSWORD);
}
@Bean
PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
@Bean
MemberRepositoryV3 memberRepositoryV3(){
return new MemberRepositoryV3(dataSource());
}
@Bean
MemberServiceV3_3 memberServiceV3_3() {
return new MemberServiceV3_3(memberRepositoryV3());
}
}
이제껏 했던 Test는 직접 트랜잭션매니저(PlatformTransactionManager
)를 이용한 방법이기 때문에 bean과는 무관한 테스트 였다. 스프링 AOP를 사용한 @Transactional
가 붙은 서비스 로직을 사용하기 위해선 @SpringBootTest
를 붙여야 한다.
AOP 적용 확인
@Test
void AppCheck() {
log.info("memberService class = {}", memberService.getClass());
log.info("memberRepository class = {}", memberRepository.getClass());
assertThat(AopUtils.isAopProxy(memberService)).isTrue();
}
memberService class = class hello.jdbc.service.MemberServiceV3_3$$EnhancerBySpringCGLIB$$e2abb52
memberRepository class = class hello.jdbc.repository.MemberRepositoryV3
MemberServiceV3_3$$EnhancerBySpringCGLIB -> AOP로 생성된 서비스 계층의 프록시
서비스계층의 프록시는 내부적으로 트랜잭션 매니저를 사용해 트랜잭션을 시작하면서 데이터 소스에서 커넥션을 만든 후, 수동커밋 모드로 만들고 트랜잭션 동기화 매니저에 커넥션을 보관한다.
핵심로직이 수행될 떄는 실제 서비스 객체의 참조값으로 메서드를 호출한다.