java, spring

[Spring] AOP 설정과 실습

isaac.kim 2021. 8. 21. 00:13
728x90
반응형

[Spring] AOP 설정과 실습

 

이전 글을 꼭 읽으시는 것을 추천합니다.

2021.08.20 - [Spring] - [Spring]AOP, Aspect-Oriented Programming/관점 지향 프로그래밍 개념 이해하기

 

 

AOP 기능은 주로 Java API를 이용해서 클래스(POJO-Plain Old Java Object)들에 적용합니다.

Controller에 적용이 불가능한 것은 아니지만, Controller의 경우 인터셉터나 필터 등을 이용합니다.

 

AOP 실습은

1) 서비스 계층의 메서드 호출 시 모든 파라미터들을 로그로 기록하고,

2) 메서드들의 실행 시간을 기록하도록 합니다.

 

AOP 프로젝트 생성

Spring Legacy Project로 하나 생성합니다.

 

예제 프로젝트는 스프링 5.1.5, Java 버전은 1.8을 사용하므로 pom.xml 파일을 수정합니다.

 

pom.xml 수정

스프링의 AOP는 AspectJ라는 라이브러리의 도움을 많이 받기 때문에 스프링 버전을 고려해서 AspectJ의 버전 역시 1.9.0으로 버전을 높여 줍니다. 프로젝트는 최종적으로 테스트 코드를 통해 동작하게 될 것이므로 spring-test, lombok을 추가하고, Junit의 버전을 변경합니다.

 

pom.xml 수정

AOP 설정과 관련해 가장 중요한 라이브러리는 AspectJ Weaver라는 라이브러리입니다. 스프링은 AOP 처리가 된 객체를 생성할 때  AspectJ Weaver 라이브러리의 도움을 받아서 동작하므로, pom.xml에 추가해야 합니다.

 

pom.xml 수정

서비스 계층 설계

com.isaac.service 패키지 아래, SampleService 인터페이스와 doAdd 메서드를 작성합니다.

다음은 SampleServiceImpl 클래스를 작성합니다. 반드시 @Service라는 어노테이션을 추가해서 스프링에서 빈으로 사용될 수 있도록 설정합니다.

 

Advice 작성

위 SampleServiceImpl 클래스의 doAdd 메서드를 보면, 이전 실습했던 메서드들에 항상 작성했던 log.info( ) 등을 이용해 로그를 기록해 오던 부분이 빠진 것을 볼 수 있습니다. 로그를 기록하는 일은 '반복적이면서 핵심 로직도 아니고, 필요하기는 한 기능이기 때문에' 관심사로 간주할 수 있습니다. AOP의 개념에서 Advice는 '관심사'를 실제로 구현한 코드이므로 지금부터 로그를 기록해주는 LogAdvice를 설계합니다.

 

AOP 기능의 설정은 XML 방식이 있기는 하지만, 이 책의 예제는 어노테이션만을 이용해서 AOP 관련 설정을 진행합니다. 예제 프로젝트에 com.isaac.aop 패키지를 생성하고, LogAdvice라는 클래스를 추가합니다.

LogAdvice는 AOP에서 사용되는 약간의 어노테이션들을 이용해서 아래와 같이 구성합니다.

LogAdvice 클래스를 살펴보겠습니다.

 

@Aspect 어노테이션은 객체가 Aspect를 구현한 것임으로 나타내기 위해 사용합니다.

@Component는 AOP와는 관계가 없지만 스프링에서 빈(bean)으로 인식하기 위해 사용합니다.

logBefore( )는 @Before어노테이션을 적용하고 있습니다. @Before는 BeforeAdvice를 구현한 메서드에 추가합니다.

@After, @AfterReturning, @AfterThrowing, @Around 역시 동일한 방식으로 적용합니다.

 

Advice와 관련된 어노테이션들은 내부적으로 Pointcut을 지정합니다. Pointcut은 별도의 @Pointcut으로 지정해 사용할 수도 있습니다. @Before내부의 'execution.....' 문자열은 AspectJ의 표현식(expression)입니다. 'execution'의 경우 접근제한자와 특정 클래스의 메서드를 지정할 수 있습니다.  맨 앞의 '*'는 접근제한자를 의미하고, 맨 뒤의 '*'는 클래스의 이름과 메서드의 이름을 의미합니다.

AOP 설정

스프링 프로젝트에 AOP를 설정하는 것은 스프링 2버전 이후 자동으로 Proxy 객체를 만들어주는 설정을 추가하면 됩니다.

 

프로젝트의 root-content.xml을 선택해서 네임스페이스에 'aop'와 'context'를 추가합니다.

root-content.xml에 다음 내용을 추가합니다.

root-content.xml에서는 <context:component-scan>을 이용해서 'com.isaac.service' 패키지와 'com.isaac.aop' 패키지를 스캔합니다. 이 과정에서 SampleServiceImpl 클래스와 LogAdvice는 스프링의 빈(객체)으로 등록될 것이고, <aop:aspectj-autoproxy>를 이용해서 LogAdivce에 설정한 @Before가 동작하게 됩니다.

 

AOP가 적용된 후에는 SampleServiceImpl 클래스의 메서드 옆에 아이콘이 추가됩니다.

 

 

AOP 테스트

'src/test/java' 폴더 아래 'com.isaac.service' 패키지 생성, SampleServiceTests 클래스를 작성합니다.

SampleServiceTests 클래스

테스트 코드로 AOP 설정을 한 Target에 대해 Proxy 객체가 정상적으로 만들어져 있는지 확인해야 합니다. <aop:aspectj-autoproxy>가 정상적으로 모든 동작을 하고, LogAdvice에 설정 문제가 없다면 service 변수의 클래스는 단순히 SampleServiceImpl의 인스턴스가 아닌 생성된 Proxy 클래스의 인스턴스가 됩니다. testClass( )를 실행해 보면 아래와 같은 결과를 보게 됩니다.

 

테스트 실행

com.sun.proxy.$Proxy는 JDK의 다이나믹 프록시(dynamic Proxy) 기법이 적용된 결과입니다.

이를 이용해서 SampleServiceImpl에 있는 코드를 실행하는 테스트 코드를 작성합니다.

 

SampleServiceTests 클래스의 일부

SampleServiceImpl의 doAdd( )를 실행하면 LogAdvice의 설정이 같이 적용되어 아래와 같이 로그가 기록됩니다.


오늘은 AOP 설정과 AOP의 개념을 바탕으로 실습을 해보았습니다.

글이 도움이 되셨다면, ♥ 와 '광고' 클릭으로 블로거에게 많은 힘을 주실 수 있습니다!

 

728x90
반응형