1. AOP란?
AOP는 핵심적인 로직을 구현하는데 있어서 핵심적인 로직과는 무관하지만 보조적으로 중간에 삽입해야 하는 로직들에 대해서 외부로 따로 빼놓고 실행될때 자동으로 중간에 삽입하여 실행하도록 하는 것입니다. 마치 java에서 함수를 따로 만들어 놓고 필요할때마다 가져다 쓰는 느낌과 유사하다고 볼수 있습니다. 하지만 AOP는 함수를 호출하는 과정과는 다르게 단 한줄의 추가도 없이 실행되는 핵심로직의 실행전이나 실행 후 혹은 앞뒤에 붙여서 동작하도록 만들 수 있습니다.
예를들어 로깅을 하는 작업이라던가 세션의 관리등은 어떠한 비즈니스 로직을 작성하는데 있어서 핵심관심은 아니지만 삽입을 해야만 하는 작업들이면서 반복적으로 여기저기서 많이 사용하는 코드들인데 이를 AOP가 알아서 핵심로직 사이사이에 삽입되도록 합니다.
2. AOP 용어
AOP의 용어에 대에서 알아보겠습니다.
[1] Pointcut
pointcut은 어디에 aop를 삽입할지에 대한 내용을 정의합니다.
예를들어 특정 패키지의 특정 method를 지정하여 해당 method에만 aop를 삽입한다던가 혹은 전체 패키지를 대상으로 포인트컷을 지정하여 aop를 반영 할 수도 있습니다.
[2] Joinpoint
pointcut이 where이라면 Joinpoint는 when입니다.
aop를 삽입할 함수를 정했다면 언제 aop를 실행할지를 정해줘야 하는데 Joinpoint의 종류로는 함수의
실행전(before), 실행후(after), 실행전후(around), 반환된 후(AfterReturning), 예외가 던져지는 시점(AfterThrowing)
이렇게 5가지가 있습니다.
[3] Advice
aop로 작성되는 로직 자체를 의미합니다.
3. 환경설정
우선 pom.xml에 라이브러리를 추가해줍니다.
만약 이미 있다면 그대로 사용하시면 됩니다.
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
다음은 aop-context.xml 파일 생성입니다. 기존의 servlet-context.xml에 정의하셔도 상관없지만 저는 따로 xml파일을 만들었습니다.
aop-context.xml 파일의 내용입니다. 그대로 복붙해서 사용하셔도 되고 직접 만드실거라면 namespace에서 aop와 beans를 등록해주셔야 합니다.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<aop:aspectj-autoproxy/>
</beans>
따로 xml파일을 만들었으니 당연히 web.xml에 등록을 해주셔야 합니다. <param-value>부분에 등록하도록 합니다.
<!-- Servlet 환경설정 -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/servlet-context.xml
/WEB-INF/spring/aop-context.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
다음은 advice 클래스를 생성할 차례입니다. 위에서 설명한바오 같이 한마디로 aop로직이 담긴 class입니다.
@Aspect
@Component
public class SampleAop {
@Before("execution(* *..service.*.*(..))")
public void test() throws Throwable {
System.out.println("aop test");
}
}
위에서 joinPoint에 대해서 알아봤었습니다. 조인포인트는 어노테이션으로 관리가 되어지는데 위의 예시에는 before로 되어 있음으로 선택된 메소드의 실행 전에 실행이 됩니다.
또한 조인포인트(위의 예시에서는 @Before)의 ( )속 내용은 exceution 표현식으로 이 aop의 로직이 어느 메소드에 붙어서 동작할지를 결정해 줍니다. execution의 표현식을 아래에서 자세히 알아보겠습니다.
[ex] excution( 접근제어자[생략가능] 리턴타입 패키지경로.클래스.메서드(파라미터))
[ex] @Before("execution(public String com.test.sample.sample.controller.SampleController.home(..))")
com.test.sample.sample.controller 패키지의
SampleController 클래스의
home메서드 중 public에 void면서 파라미터가 0개 이상인 ( (..)는 파라미터 0개 이상을 의미 )
메서드에 aop로직을 before로 적용
[ex] @Before("execution(* *..service.*.*(..))")
service패키지 안에 있는 모든 종류의 메소드에 전부 적용
4. AOP에서 request, response 객체를 사용하는 방법
Aop에서 response, request객체를 사용해야 하는경우가 있을 수 있습니다. 이 경우에는 파라메타로 각 객체를 받는 방법도 있지만 좀 더 간단한 방법으로 aop내에서 바로 httpServeltRequest, response객체에 대하여 접근을 하는 것입니다. 아래의 코드를 통해서 접근이 가능합니다.
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
'Spring > Spring' 카테고리의 다른 글
[Spring] 멀티 파일업로드, 파일다운로드 구현 (0) | 2019.10.13 |
---|---|
[Spring] Logback, log4jdbc를 이용한 시스템로그, DB로그 출력방법 (0) | 2019.08.30 |
[Spring] 컨트롤러와 프론트 사이에서 값 전달하는 방법의 종류 (7) | 2019.08.03 |
[Spring] 에서 타일즈(Tiles) 세팅 및 사용법 (0) | 2019.07.21 |
[Spring] 프레임워크 Web.xml 세팅방법 (1) | 2019.07.15 |
댓글