-
Spring AOP개발/Spring 2020. 2. 2. 13:00
AOP(Aspect Oriented Programming) 란?
- 업무 로직을 포함하는 기능을 핵심기능
- 핵심 기능을 도와주는 부가적인 기능(로깅, 보안 체크)을 부가기능 이라고 부른다.
이러한 핵심 기능과 부가기능을 나누는 프로그래밍을 AOP라 한다.
OOP를 더욱 OOP 스럽게 만들어줌
class A { method a() { AAAA doSometing(); BBBB } } class B { method b() { AAAA doSomething(); BBBB } }
예를 들어 어떠한 핵심기능을 하는 doSomething()를 전후로 AAAA와 BBBB라는 기능이 필요할때의 코드는 위와 같을것이다.
하지만 위에서 중복되는 AAAA와 BBBB는 필요하지만 핵심기능과는 관련없는 기능이다. 이는 코드의 간결성도 떨어지고, 객체지향에서 추구하는 단일책임원칙(Single responsibility principle)에도 위배 된다.
이러한 코드의 형태를 띄는 대표적인 예는 Logging이나 Transaction 처리 등이 있다.
class AAAABBBB { method aaaabbbb(JoinPoint point) { AAAA point.execute(); BBBB } }
이를 해결하기 위해 위와 같은 방식으로 부가기능을 다른 클래스로 빼는 형태로 구현한다.
Spring에서는 @Aspect 어노테이션을 통해 AOP를 쉽게 구현할 수 있도록 해준다.
@interface LogExecutionTime
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface LogExecutionTime { }
LogAspect
@Component @Aspect public class LogAspect { Logger logger = LoggerFactory.getLogger(LogAspect.class); @Around("@annotation(LogExecutionTime)") public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable { StopWatch stopWatch = new StopWatch(); stopWatch.start(); Object proceed = joinPoint.proceed(); stopWatch.stop(); logger.info(stopWatch.prettyPrint()); return proceed; } }
실제 @LogExecutionTime 적용 메소드
@LogExecutionTime @GetMapping("/owners/find") public String initFindForm(Map<String, Object> model) { model.put("owner", new Owner()); return "owners/findOwners"; }
위 예제는 메소드를 처리에 걸리는 시간을 로그로 보여주는 기능을 AOP로 추가한 것이다.
@interface LogExecutionTime을 통해 어노테이션을 정의하고, LogAspect에서 그 기능을 구현한것 이다.
Spring의 StopWatch를 통해 메소드의 처리시간을 구하고 ProcedingJoinPoint 인터페이스를 통해 전달된 initFindForm 메소드를 전후로
StopWatch.start()와 StopWatch.stop()을 실행하여 그 메소드의 처리시간을 구하고 Logger를 통해 로그를 출력후 기존 initFindForm의 return값을 반환하는것을 볼 수 있다. 위 예제 코드에서 기존 initFindForm메소드의 로직은 변경와 코드의 추가 없이 로그 출력기능만 추가 된 것을 볼 수 있다.
이것이 AOP가 가진 강력함 이다.
예제 출처 백기선의 스프링 강좌
'개발 > Spring' 카테고리의 다른 글
Spring Rest docs 적용 (0) 2020.11.19 Spring PSA (0) 2020.02.02 Spring 개념 정리 (0) 2020.02.02