유지보수하는 작업은 쉬운 작업이 아니다. 첫 번째 그림과 같이 하나하나 전부 작성하여 적용하는 것과 두 번째 그림과 같이 별도로 분리하여 작성 후 원하는 곳에 공통 관심 사항을 적용하도록 하는 방법은 차이가 매우 크다.
공통 관심 사항(cross-cutting concern), 핵심 관심 사항(core concern)으로 분리한다.
package hello.hello_spring;
import hello.hello_spring.aop.TimeTraceAop;
import hello.hello_spring.controller.MemberController;
import hello.hello_spring.repository.MemberRepository;
import hello.hello_spring.service.MemberService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringConfig {
private final MemberRepository memberRepository;
public SpringConfig(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Bean
public MemberService memberService() {
return new MemberService(memberRepository);
}
@Bean
public MemberController memberController() {
return new MemberController(memberService());
}
// AOP 역시 스프링 빈으로 등록(=@ComponentScan)
@Bean
public TimeTraceAop timeTraceAop() {
return new TimeTraceAop();
}
}
package hello.hello_spring.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class TimeTraceAop {
@Around("execution(* hello.hello_spring.*(..))")
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
System.out.println("START : " + joinPoint.toString());
try {
return joinPoint.proceed();
} finally {
long finish = System.currentTimeMillis();
long timeMs = finish - start;
System.out.println("ENd : " + joinPoint.toString() + " " + timeMs + "ms");
}
}
}