Spring AOP with Annotations
스프링 웹프로젝트에서 Annotation을 이용한 AOP 작성 예 ( Spring Annotation based AOP example )
개요
스프링을 이용한 웹프로젝트에서 AOP를 사용하는 간단한 예이다
테스트 환경
Windows 7, JDK 1.7, Tomcat 8, Spring 3.2, Eclipse luns, STS, Maven,
라이브러리 설치
스프링의 기본 라이브러리 외에 다음과 같은 추가적인 라이브러리가 필요함
pom.xml
<!-- AOP start -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.2</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>3.2.11.RELEASE</version>
</dependency>
<!-- AOP start -->
WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<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</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
Aspect 클래스를 정의함
package org.kdea.aop;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class SimpleAspect {
@Pointcut("execution(* org.kdea.aop.*.*(..))")
private void allClass() {} // Pointcut 의 이름(allClass())을 선언함
@Pointcut("execution(* org.kdea.aop.SimpleService.getMsg(..))")
private void getMsg() {} // Pointcut 의 이름(getMsg())을 선언함
@Before("getMsg()") // Pointcut 의 이름을 사용하여 Advice를 선언함
public void beforeAdvice(){
System.out.println("beforeAdvice()");
}
@After("getMsg()")
public void afterAdvice(){
System.out.println("afterAdvice()");
}
@AfterReturning(pointcut="getMsg()", returning="retVal")
public void afterReturningAdvice(Object retVal){
String val = null;
if(retVal==null) val = "리턴 값 없음";
else val = retVal.toString();
System.out.println("afterReturningAdvice:" + val );
}
@AfterThrowing(pointcut="getMsg()", throwing="ex")
public void AfterThrowingAdvice(IllegalArgumentException ex){
System.out.println("에러발생: " + ex.toString());
}
}
SimpleService.java
package org.kdea.aop;
import org.springframework.stereotype.Service;
@Service("simpleService")
public class SimpleService {
private String msg;
public void setMsg(String msg) {
this.msg = msg;
System.out.println("setMsg()");
}
public String getMsg() {
System.out.println("getMsg()");
return msg;
}
}
서블릿 설정파일에 Aspect 클래스와 Aspect 가 적용될 서비스 클래스를 빈으로 등록함
WEB-INF/spring/servlet-context.xml
<context:annotation-config/>
<mvc:annotation-driven/>
<aop:aspectj-autoproxy />
<beans:bean id="simpleAspect" class="org.kdea.aop.SimpleAspect"/>
<beans:bean id="simpleService" class="org.kdea.aop.SimpleService"/>
콘트롤러 클래스에서 AOP가 적용될 서비스 클래스를 인젝션으로 받아서 사용함
AOPTestController.java
package org.kdea.aop;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class AOPTestController {
@Autowired
SimpleService simpleService; // 서비스 클래스에 @Service 를 적용하거나 설정파일에 빈으로 등록하면 이렇게 선언만으로 인젝션 가능함
@RequestMapping("/aop/test")
public void aopTest() {
simpleService.setMsg("AOP Test");
simpleService.getMsg();
}
}
테스트
웹브라우저에서 http://localhost:8080/ContextName/aop/test 으로 접속하고 콘솔창에서 메시지를 확인한다
위의 설정내용이 문제 없이 실행된다면 다음과 같은 콘솔 메시지를 확인할 수 있다.
setMsg()
beforeAdvice()
getMsg()
afterAdvice()
afterReturningAdvice:AOP Test