WEB/SPRING
6.5 스프링 AOP
JC0
2024. 2. 10. 14:19
Spring AOP 주요 용어
Aspect | 공통 기능을 모듈화한 기본 모듈이다. |
Target | 부가기능을 부여할 대상이다. |
Join point | 어드바이스가 적용될 수 있는 위치를 말한다. |
Advice | 타겟에게 제공할 부가기능을 담은 모듈이다. |
Point cut | 어드바이스를 적용할 조인 포인트를 선별하는 기능 |
Advisor | 포인트컷 + 어드바이저 |
스프링 aop를 적용해서 테스트를 실행했다.
NameMathchMethodPointcut의 getClassFilter 메서드를 구현해서 클래스 필터를
"HelloT"로 시작하는 클래스에 매칭시키고
NameMathchMethodPointcut.setMappedName("sayH")로 sayH로 시작하는 메서드에 필터를 적용했다.
ProxyFactoryBean 생성 후에 target을 설정해주고 advisor에 포인트컷과 어드바이스를 적용해서
오브젝트를 가져온 후에 메서드를 실행시켜주면 클래스 필터와 메서드 필터를 통과한 부분에만 적용되는 것을
볼 수 있다.
HelloToby와 HelloTarget 클래스는 필터를 통과하고 sayHello와 sayHi 메서드가 메서드 필터를 통과해서
toUpperCase()메서드를 통해 대문자로 변경된 결과가 보여진다.
public class DynamicProxyTest {
@Test
public void classNamePointcutAdvisor(){
NameMatchMethodPointcut classMethodPointcut = new NameMatchMethodPointcut(){
public ClassFilter getClassFilter(){
return new ClassFilter(){
public boolean matches(Class<?> clazz){
return clazz.getSimpleName().startsWith("HelloT");
}
};
}
};
classMethodPointcut.setMappedName("sayH*");
checkAdviced(new HelloTarget(), classMethodPointcut, true);
class HelloWorld extends HelloTarget {};
checkAdviced(new HelloWorld(), classMethodPointcut, false);
class HelloToby extends HelloTarget{};
checkAdviced(new HelloToby(), classMethodPointcut, true);
}
private void checkAdviced(Object target, Pointcut pointcut, boolean adviced){
ProxyFactoryBean pfBean = new ProxyFactoryBean();
pfBean.setTarget(target);
pfBean.addAdvisor(new DefaultPointcutAdvisor(pointcut, new UppercaseAdvice()));
Hello proxiedHello = (Hello) pfBean.getObject();
if(adviced){
Assertions.assertThat(proxiedHello.sayHello("Toby")).isEqualTo("HELLO TOBY");
Assertions.assertThat(proxiedHello.sayHi("Toby")).isEqualTo("HI TOBY");
Assertions.assertThat(proxiedHello.sayThankYou("Toby")).isEqualTo("Thank You Toby");
System.out.println("애즈펙트 적용");
System.out.println(proxiedHello.sayHello("Toby"));
System.out.println(proxiedHello.sayHi("Toby"));
System.out.println(proxiedHello.sayThankYou("Toby"));
System.out.println("--------------------------------------");
}else {
Assertions.assertThat(proxiedHello.sayHello("Toby")).isEqualTo("Hello Toby");
Assertions.assertThat(proxiedHello.sayHi("Toby")).isEqualTo("Hi Toby");
Assertions.assertThat(proxiedHello.sayThankYou("Toby")).isEqualTo("Thank You Toby");
System.out.println("애즈펙트 적용 xxxx");
System.out.println(proxiedHello.sayHello("Toby"));
System.out.println(proxiedHello.sayHi("Toby"));
System.out.println(proxiedHello.sayThankYou("Toby"));
System.out.println("--------------------------------------");
}
}
static interface Hello {
String sayHello(String name);
String sayHi(String name);
String sayThankYou(String name);
}
static class HelloTarget implements Hello {
public String sayHello(String name) {
return "Hello " + name;
}
public String sayHi(String name) {
return "Hi " + name;
}
public String sayThankYou(String name) {
return "Thank You " + name;
}
}
static class HelloUppercase implements Hello {
Hello hello;
public HelloUppercase(Hello hello) {
this.hello = hello;
}
public String sayHello(String name) {
return hello.sayHello(name).toUpperCase();
}
public String sayHi(String name) {
return hello.sayHi(name).toUpperCase();
}
public String sayThankYou(String name) {
return hello.sayThankYou(name).toUpperCase();
}
}
static class UppercaseAdvice implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable {
String ret = (String)invocation.proceed();
return ret.toUpperCase();
}
}
}