PointcutAdvisor:Pointcut和Advice的组合
建议订阅博主专栏,从下到上系统手写spring源码,体会其中过程!
Advisor是包含一个Pointcut和一个Advice的组合,Pointcut用于捕获JoinPoint,Advice决定在JoinPoint执行某种操作。实现了一个支持aspectj表达式的AspectJExpressionPointcutAdvisor。
新增以下接口和类
- Advisor:该接口提供返回Advice的功能,能够返回自定义的拦截器,比如之前写的MethodBeforeAdvice等。
- PointcutAdvisor:该接口继承了额Advisor接口,提供获取Pointcut方法。
- AspectJExpressionPointcutAdvisor:该类扩展了AspectJExpressionPointcut类,将AspectJExpressionPointcut类作为属性聚合到类中,并提供了Advice和匹配表达式两个属性和相关接口。
public class AspectJExpressionPointcutAdvisor implements PointcutAdvisor {
private AspectJExpressionPointcut pointcut;
private Advice advice;
private String expression;
public void setExpression(String expression){
this.expression = expression;
pointcut = new AspectJExpressionPointcut(expression);
}
@Override
public Pointcut getPointcut() {
return pointcut;
}
@Override
public Advice getAdvice() {
return advice;
}
// 设置方法拦截
public void setAdvice(Advice advice){
this.advice = advice;
}
}
- 测试方法:方法中将之前涉及到的代理AdvisedSupport和表达式匹配以及Before切面等结合起来,等知识点汇总起来。
@Test
public void testAdvisor() throws Exception{
WorldService worldService = new WorldServiceImpl();
//Advisor是Pointcut和Advice的组合
String expression = "execution(* org.springframework.test.service.WorldService.explode(..))";
AspectJExpressionPointcutAdvisor pointcutAdvisor = new AspectJExpressionPointcutAdvisor();
pointcutAdvisor.setExpression(expression);
MethodBeforeAdviceInterceptor methodInterceptor = new MethodBeforeAdviceInterceptor(new WorldServiceBeforeAdvice());
//注入方法拦截器
pointcutAdvisor.setAdvice(methodInterceptor);
//获取匹配到的类
ClassFilter classFilter = pointcutAdvisor.getPointcut().getClassFilter();
if(classFilter.matches(worldService.getClass())){
AdvisedSupport advisedSupport = new AdvisedSupport();
//对匹配到的类进行代理
TargetSource targetSource = new TargetSource(worldService);
advisedSupport.setTargetSource(targetSource);
advisedSupport.setMethodInterceptor((MethodInterceptor) pointcutAdvisor.getAdvice());
advisedSupport.setMethodMatcher(pointcutAdvisor.getPointcut().getMethodMatcher());
advisedSupport.setProxyTargetClass(true); //JDK or CGLIB
WorldService proxy = (WorldService)new ProxyFactory(advisedSupport).getProxy();
proxy.explode();
}
}