前面完成了所有增强器的解析,但是对于所有的增强器来讲,并不一定适用于当前bean,还需要进行挑选。具体的实现在findAdvisorsThatCanApply方法中实现。
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class beanClass, String beanName) {
//设置当前正在创建代理的beanNAme,ThreadLocal类型的变量
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
//过滤已经得到的advisors
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
//设置当前正在创建代理的beanNAme位null,表示当前线程创建完了,可以下一个
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
继续看看findAdvisorsThatCanApply方法
先介绍一下aop中的增强类型
- 前置增强 (org.springframework.aop.BeforeAdvice) 表示在目标方法执行前来实施增强
- 后置增强 (org.springframework.aop.AfterReturningAdvice) 表示在目标方法执行后来实施增强
- 环绕增强 (org.aopalliance.intercept.MethodInterceptor) 表示在目标方法执行前后同时实施增强
- 异常抛出增强 (org.springframework.aop.ThrowsAdvice) 表示在目标方法抛出异常后来实施增强
- 引介增强 (org.springframework.aop.introductioninterceptor) 表示在目标类中添加一些新的方法和属性
其中,引介增强是一种特殊的增强。他可以在目标类中添加属性和方法,通过拦截定义一个接口,让目标代理实现这个接口。他的连接点是类级别的,而前面的几种则是方法级别的。
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();
//首先出引介增强,引介增强(目标类中添加一些新的方法和属性,可以用户自己实现IntroductionAdvisor来进行自定义处理)
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) {
//引介增强已经处理过这里不处理
continue;
}
//只处理普通增强
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
findAdvisorsThatCanApply函数的主要功能就是寻找所有的增强器中适用于当前class的增强器。其中匹配的主要逻辑在canApply方法中
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
//引介增强和普通的增强的处理不一样,对于真正的匹配在canApply中实现的
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;
}
}
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
//获取ClassFilter(过滤器限制切入点或介绍与给定目标类集的匹配)并通过需要代理的类的类名来匹配
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
//获取切点的MethodMatcher方法匹配器
MethodMatcher methodMatcher = pc.getMethodMatcher();
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
//如果是引介增强类型的方法匹配器起则转化为引介增强的
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
//将需要代理的类相关的接口转化为set集合的,跟这个类所有有关的接口,父接口的接口也包括
Set<Class> classes = new LinkedHashSet<Class>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
classes.add(targetClass);
//便利所有的class类的所有的方法,并去匹配对应的方法看是否存在对应的切点方法
for (Class<?> clazz : classes) {
Method[] methods = clazz.getMethods();
for (Method method : methods) {
if ((introductionAwareMethodMatcher != null &&
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
找到匹配的代理之后就是创建地代理创建代理
网友评论