※ Spring AOP 용어
Spring을 사용한 AOP에서는 다음과 같은 용어를 이해하는 것이 매우 중요하다
● Joinpoint : ‘클래스의 인스턴스 생성 시점’, ‘메소드 호출 시점’ 및 ‘예외 발생 시점’ 과 같이 어플리케이션을 실행할 때 특정 작업이 시작되는 시점을 의미.
● Advice : 조인포인트에 삽입되어 동작할 수 있는 코드를 말함.
● Pointcut : 여러 개의 조인포인트를 하나로 결합한(묶은) 것을 말함.
● Advisor : 어드바이스와 포인트컷을 하나로 묶어 취급한 것을 말함.
● Weaving : 어드바이스를 핵심 로직 코드에 삽입하는 것을 말함.
● Target : 핵심 로직을 구현하는 클래스.
● Aspect : 여러 객체에 공통으로 적용되는 공통 관점 사항을 말함.
기본 예제 실습 해 보기 --------------
MyCoreClass.java
package pack;
public class MyCoreClass {
public void foo() {
System.out.println("핵심 메소드 foo()");
}
public void bar() {
System.out.println("핵심 메소드 bar()");
}
}
MyBean.java
package pack;
public class MyBean {
private MyCoreClass dep;
public void setDep(MyCoreClass dep) {
this.dep = dep;
}
public void execute() {
dep.foo();
dep.bar();
}
}
MyAdvice.java --- Aspect
package pack;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class MyAdvice implements MethodBeforeAdvice {
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println(method + " 전에 보안 처리");
}
}
Main.java
package pack;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:aoptest.xml");
MyBean bean1 = (MyBean) context.getBean("myBean1");
MyBean bean2 = (MyBean) context.getBean("myBean2");
System.out.println("Bean 1 수행");
bean1.execute();
System.out.println("\nBean 2 수행");
bean2.execute();
}
}
aoptest.xml
<?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"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd"><bean id="myBean1" class="pack.MyBean">
<property name="dep">
<ref local="target1" />
</property>
</bean>
<bean id="myBean2" class="pack.MyBean">
<property name="dep">
<ref local="target2" />
</property>
</bean>
<bean id="myTarget" class="pack.MyCoreClass" />
<bean id="target1" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref local="myTarget" />
</property>
<property name="interceptorNames">
<list> <!-- advice를 직접 target에 적용 -->
<value>advice</value>
</list>
</property>
</bean>
<bean id="target2" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref local="myTarget" />
</property>
<property name="interceptorNames">
<list> <!-- advice와 pointcut을 설정해서 적용 -->
<value>advisor</value>
</list>
</property>
</bean>
<bean id="advice" class="pack.MyAdvice" />
<bean id="advisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice">
<ref local="advice" />
</property>
<property name="pointcut">
<bean class="org.springframework.aop.aspectj.AspectJExpressionPointcut">
<property name="expression">
<value>execution(* foo*(..))</value> <!-- execution(* pack.*.*(..)) -->
</property>
</bean>
</property>
</bean>
</beans>
Annotation 사용 예제 --------------
Apple.java - 인터페이스
package aaa;
public interface Apple {
public void coreProcess();
}
AppleImpl.java
package aaa;
public class AppleImpl implements Apple {
@Override public void coreProcess() { System.out.println("핵심 메소드 수행"); }
}
AnnotLoggingAspect.java - advice bean
package aaa;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class AnnotLoggingAspect {
@Around("execution(public * aaa.*.core*(..))")
public void logging(ProceedingJoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName(); // 핵심 메소드명 얻기
try {
System.out.println("before : " + methodName);
joinPoint.proceed();
System.out.println("after : " + methodName);
} catch (Throwable e) {
System.out.println("예외가 발생했어요!");
}
}
}
appContext.xml
<?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-3.2.xsd">
<aop:aspectj-autoproxy />
<bean id="apple" class="aaa.AppleImpl" />
<bean class="aaa.AnnotLoggingAspect" />
</beans>
Main.java
package aaa;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
String configLocation = "appContext.xml";
ApplicationContext context = new ClassPathXmlApplicationContext( configLocation);
Apple apple = (Apple) context.getBean("apple");
apple.coreProcess();
}
}
***** 수행 결과 *****
before : coreProcess 핵심 메소드 수행
after : coreProcess
참고 :
http://mudchobo.tistory.com/252
http://isstory83.tistory.com/115