spring AopUtils分析

AopUtils是spring aop中很常用的一个工具类,提供了许多通用方法:

一、isJdkDynamicProxy

public static boolean isJdkDynamicProxy(@Nullable Object object) {
	return (object instanceof SpringProxy && Proxy.isProxyClass(object.getClass()));
}

1)、方法描述:
判断当前对象是否是由JDK动态代理产生的代理对象
2)、执行逻辑:
1⃣️ 首先判断对象是否实现SpringProxy接口(注:spring产生的代理对象都会实现SpringProxy接口,具体原理可以参见:具体原理研究
2⃣️ 继而判断当前对象是否是JDK动态代理产生的代理对象。
只有当两者都满足的时候,才会返回true,表示该对象是spring JDK动态代理方式产生的代理对象。
3)、实现原理:
JDK动态代理产生的代理对象1⃣️会继承Proxy类,2⃣️已经产生的代理对象将会保存在proxyClassCache中,使用此方种式进行判断。(注:JDK动态代理产生的代理类都会有$Proxy前缀,笔者认为这里还可以根据类的名称进行判断,不过既然JDK的Proxy类已经提供了对应的功能,我们也不必要再造轮子了。)

 public static boolean isProxyClass(Class<?> cl) {
      return Proxy.class.isAssignableFrom(cl) && proxyClassCache.containsValue(cl);
   }

二、isCglibProxy

public static boolean isCglibProxy(@Nullable Object object) {
	return (object instanceof SpringProxy && ClassUtils.isCglibProxy(object));
}

1)、方法描述:
判断当前对象是否是由CGLIB产生的代理对象
2)、执行逻辑:
1⃣️ 首先判断对象是否实现SpringProxy接口;
2⃣️ 继而使用ClassUtils.isCglibProxy方法判断当前对象是否是CGLIB产生的代理对象。
只有当两者都满足的时候,才会返回true,表示该对象是由CGLIB产生的代理对象。
3)、实现原理:
CGLIB产生的代理类名中会包含$$符号,使用此种方式进行判断,具体判断逻辑如下:

public static boolean isCglibProxy(Object object) {
	return isCglibProxyClass(object.getClass());
}

public static boolean isCglibProxyClass(@Nullable Class<?> clazz) {
	return (clazz != null && isCglibProxyClassName(clazz.getName()));
}
public static boolean isCglibProxyClassName(@Nullable String className) {
	return (className != null && className.contains(CGLIB_CLASS_SEPARATOR));
}

三、isAopProxy

public static boolean isAopProxy(@Nullable Object object) {
	return (object instanceof SpringProxy &&
			(Proxy.isProxyClass(object.getClass()) || ClassUtils.isCglibProxyClass(object.getClass())));
}

1)、方法描述:
判断当前对象是否是AOP代理对象
2)、执行逻辑:
1⃣️ 首先判断对象是否实现SpringProxy接口;
2⃣️ 继而使用如下代码判断当前对象是否是AOP代理对象。

(Proxy.isProxyClass(object.getClass()) || ClassUtils.isCglibProxyClass(object.getClass())

3)、实现原理:
代理对象无非两种,JDK动态代理产生的代理对象或者CGLIB产生的代理对象,这里进行了或运算,无论当前对象是JDK动态代理产生的代理对象,还是CGLIB产生的代理对象,只要满足其一,就代表当前对象是AOP代理对象。

四、isEqualsMethod

public static boolean isEqualsMethod(@Nullable Method method) {
	return ReflectionUtils.isEqualsMethod(method);
}

1)、方法功能:
判断当前方法是否是Equals方法。
… isHashCodeMethod、isToStringMethod也是如此,分别判断当前方法是否是HashCode、toString方法,在这里不再赘述。

五、canApply

//判断targetClass类是否匹配切点的切入条件,或者说判断pc切点能否应用在targetClass类上
public static boolean canApply(Pointcut pc, Class<?> targetClass) ;

具体实现如下所示:

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;
		}

		MethodMatcher methodMatcher = pc.getMethodMatcher();
		if (methodMatcher == MethodMatcher.TRUE) {
			// No need to iterate the methods if we're matching any method anyway...
			return true;
		}

		IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
		if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
			introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
		}

		Set<Class<?>> classes = new LinkedHashSet<>();
		if (!Proxy.isProxyClass(targetClass)) {
			classes.add(ClassUtils.getUserClass(targetClass));
		}
		classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

		//判断类中的方法是否匹配切点函数
		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;
	}

六、findAdvisorsThatCanApply

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) 

1)、方法描述:
根据candidateAdvisors,挑选出可以应用在clazz类上的Advisor集合。

if (candidateAdvisors.isEmpty()) {
	return candidateAdvisors;
	}
	List<Advisor> eligibleAdvisors = new ArrayList<>();
	for (Advisor candidate : candidateAdvisors) {
		if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
			eligibleAdvisors.add(candidate);
		}
	}
	boolean hasIntroductions = !eligibleAdvisors.isEmpty();
	for (Advisor candidate : candidateAdvisors) {
		if (candidate instanceof IntroductionAdvisor) {
			// already processed
			continue;
		}
		if (canApply(candidate, clazz, hasIntroductions)) {
			eligibleAdvisors.add(candidate);
		}
	}
	return eligibleAdvisors;

2)、实现原理:
通过上面的代码块,我们可以看到,该方法最终是通过调用canApply方法来判断对应的Advisor能否应用在目标clazz上。

七、invokeJoinpointUsingReflection

@Nullable
public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args)
		throws Throwable {
	ReflectionUtils.makeAccessible(method);
	return method.invoke(target, args);
	...	
}

1)、方法描述:
使用反射调用目标方法。
2)、执行过程:
1⃣️首先调用了ReflectionUtils.makeAccessible(method),相当于method.setAccsessible(true),避免了反射调用过程中的安全检查。
2⃣️执行反射调用。

    原文作者:Spring Boot
    原文地址: https://blog.csdn.net/wt_better/article/details/84791590
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞