Spring 핵심원리 고급편 - Pointcut 만들기

목차

참고

본 포스트는 김영한의 스프링 핵심 원리 - 고급편 내용을 참고해 만들었습니다.

Pointcut 인터페이스

PointcutgetClassFilter 메서드와 getMethodMatcher 메서드를 이용해 필터링 을 진행한다.
둘다 TRUE 를 반환해야 Advice 를 적용할 수 있다

  • getClassFilter : Class 조건으로 Filter 하는 메서드
  • .getMethodMatcher : Method 조건으로 Filter 하는 메서드
public interface Pointcut {

// 클래스 조건으로 필터링
ClassFilter getClassFilter();

// 메서드 조건으로 필터링
MethodMatcher getMethodMatcher();

Pointcut TRUE = TruePointcut.INSTANCE;
}

Pointcut 적용하기

save 메서드는 Advice 로직을 적용하지만, find 메서드에서는 Advice 로직을 적용하지 않도록 설정하기

  • Pointcut 인터페이스를 구현을 통해 Class 를 이용한 ClassFilter 와 Method 를 이용한 MethodMatcher 를 Overriding 한다.
  • 두 메소드가 true 를 반환해야 PointCut 을 적용할 수 있다.
// Pointcut 생성
static class MyPointCut implements Pointcut{

@Override
public ClassFilter getClassFilter() {
return ClassFilter.TRUE;
}

@Override
public MethodMatcher getMethodMatcher() {
return new MyMethodMatcher();
}
}

MethodMatcher 인터페이스를 구현 Method 이름이 save 일 경우 true 를 반환해 부가 기능이 수행 될 수 있도록 한다.

static class MyMethodMatcher implements MethodMatcher{

private String matchName = "save";

@Override
public boolean matches(Method method, Class<?> targetClass) {
boolean result = method.getName().equals(matchName);
log.info("포인트 컷 호출 method = {} targetClass = {}", method.getName(), targetClass);
log.info("포인트 컷 결과 result = {}", result);
return result;
}

@Override
public boolean isRuntime() {
return false;
}

@Override
public boolean matches(Method method, Class<?> targetClass, Object... args) {
return false;
}
}

PointCut 을 Advisor 에 적용한다.

ServiceInterface target = new ServiceImpl();
ProxyFactory proxyFactory = new ProxyFactory(target);

// Advisor 인터페이스의 가장 일반적인 구현체
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(new MyPointCut(), new TimeAdvice());

// Proxy Factory 에 적용할 Advisor 를 지정한다.
proxyFactory.addAdvisor(advisor);
ServiceInterface proxy = (ServiceInterface) proxyFactory.getProxy();

proxy.save();
proxy.find();

00:05:44.717 [Test worker] INFO hello.proxy.advisor.AdvisorTest - 포인트 컷 호출 method = save targetClass = class hello.proxy.common.service.ServiceImpl
00:05:44.720 [Test worker] INFO hello.proxy.advisor.AdvisorTest - 포인트 컷 결과 result = true
00:05:44.723 [Test worker] INFO hello.proxy.common.advice.TimeAdvice - TimeProxy 실행
00:05:44.723 [Test worker] INFO hello.proxy.common.service.ServiceImpl - save 호출
00:05:44.723 [Test worker] INFO hello.proxy.common.advice.TimeAdvice - TimeProxy 종료 resultTime = 0
00:05:44.723 [Test worker] INFO hello.proxy.advisor.AdvisorTest - 포인트 컷 호출 method = find targetClass = class hello.proxy.common.service.ServiceImpl
00:05:44.724 [Test worker] INFO hello.proxy.advisor.AdvisorTest - 포인트 컷 결과 result = false
00:05:44.724 [Test worker] INFO hello.proxy.common.service.ServiceImpl - find 호출
Share