sprng5.2.9 cglb aop总结

本文深入探讨了Spring AOP的工作原理,重点介绍了Advisor组件的作用及其内部结构,包括Advice和PointcutAdvisor的重要作用。同时,文章详细解释了如何通过实现特定接口来控制增强方法的执行顺序,并介绍了代理对象的生成过程。

接口解析
在这里插入图片描述
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 就不在 叙说了

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值