接口解析

Advisor中包含两个重要 数据 Advice为要执行的增强方法 PointcutAdvisor 为判断当前方法有没有 被加强的权限。
在实现时 只要想spring中注入Advisor的实现 就可以了 但是如果想要 控制 其先后顺序,可以实现 PriorityOrdered 和 Ordered
值越大越后执行,PriorityOrdered >Ordered >没有
代理生成的对象
public class XX$$EnhancerBySpringCGLIB$$62cdd9f4 extends XX implements SpringProxy, Advised, Factory
xx被代理对象,SpringProxy表明为代理后对象,Factory给对象赋值
注意 Factory中的setCallbacks方法,他就是给代理后的对象赋初始值的,你要代理执行的方法,原对象都是从这个方法赋值的。
赋值的第一个值就是 DynamicAdvisedInterceptor这个对象中保存了,要执行的的代理方法,和原对象,原对象要执行的方法
DynamicAdvisedInterceptor中的变量advised为ProxyFactory对象
ProxyFactory中的变量要注意 targetSource储存原对象,advisors储存代理要执行的方法。
其中 advisors是一个 advisor 的数组,advisor是一个接口他的两个方法 getAdvice返回值是一个Advice的对象,另一个不用管。
但是每一实现 advisor的实现类都不是直接实现,而是去实现它 的子接口 IntroductionAdvisor和PointcutAdvisor 也必须去实现 这个两个接口中的其中一个。原因是 在判断一个对象 是不是 需要被代理 他会转化为这个两个对象去判断,如果不是这个两个的实现类,那你的这个代理就代理了 全部 方法。
//判断 这个类 需不需要代理
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
// 代理全部对象
// It doesn't have a pointcut so we assume it applies.
return true;
}
}
比如我们用@Aspect注解方式实现 的 aop 他的advisor就是InstantiationModelAwarePointcutAdvisorImpl 实现的就是
PointcutAdvisor接口
spring事务也是实现这个接口
advisor中的Advice
advisor中的Advice对象保存了我们需要执行的增强方法
比如我们用@Aspect注解方式实现 的 aop 他的InstantiationModelAwarePointcutAdvisorImpl
如下
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfter:
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfterReturning:
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
根据不同的 不通得增强 返回的 是不同的对象
他们都继承 了Advice的子 接口 MethodInterceptor
因为 只有Advice的子接口MethodInterceptor有invoke方法
这个是写死 的。
//执行方法 增强的方法
return dm.interceptor.invoke(this);
dm就是下面这个类。
class InterceptorAndDynamicMethodMatcher {
final MethodInterceptor interceptor;
final MethodMatcher methodMatcher;
public InterceptorAndDynamicMethodMatcher(MethodInterceptor interceptor, MethodMatcher methodMatcher) {
this.interceptor = interceptor;
this.methodMatcher = methodMatcher;
}
}
在这个MethodInterceptor.invoke方法下 你想干嘛就干嘛。直接执行代码。还是反射调用 你想要执行的 方法。都行。
在
PointcutAdvisor中Pointcut
Pointcut使用来判断一个类的方法是不是需要被代理
public interface Pointcut {
// 类过滤器
ClassFilter getClassFilter();
// 方法判断器
MethodMatcher getMethodMatcher();
}
MethodMatcher
public interface MethodMatcher {
// 在判断的时候会执行这个方法 传入要判断的 类 与 方法 true 被代理
boolean matches(Method method, Class<?> targetClass);
boolean isRuntime();
boolean matches(Method method, Class<?> targetClass, Object... args);
}
ClassFilter
public interface ClassFilter {
//true 被代理
boolean matches(Class<?> clazz);
}
在判断 一个方法需不需要代理
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
// 去 执行 类的拦截 剔除不需要代理的类
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
for (Class<?> clazz : classes) {
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
// 去执行 方法 类 是否满足
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
最后 得到满足的advisor就放入DynamicAdvisedInterceptor 中的advised的 advisors 集合中。
还有一个 advisor 的子接口 IntroductionAdvisor 就不在 叙说了
本文深入探讨了Spring AOP的工作原理,重点介绍了Advisor组件的作用及其内部结构,包括Advice和PointcutAdvisor的重要作用。同时,文章详细解释了如何通过实现特定接口来控制增强方法的执行顺序,并介绍了代理对象的生成过程。
758

被折叠的 条评论
为什么被折叠?



