您的位置:首页 > 编程语言 > Java开发

Spring源码之创建AOP代理(补)

2016-03-20 18:36 746 查看
在上一章节中,我们已经知道了如何获取增强器,但是我们还一件事还未做,那就是寻找匹配的增强器。下面我们来看这个功能的时序图。



1. AbstractAdvisorAutoProxyCreator

在AbstractAdvisorAutoProxyCreator的类,重点实现寻找匹配的增强器是在方法findAdvisorsThatCanApply中。

protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
return AopUtils.<strong>findAdvisorsThatCanApply(candidateAdvisors, beanClass)</strong>;
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}

2. AopUtils

我们继续跟踪代码的findAdvisorsThatCanApply的方法,进入代码可以看到,这里主要做的事情是处理引介增强、对于普通bean的处理。

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor && <strong>canApply(candidate, clazz)</strong>) {
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;
}

findAdvisorsThatCanApply函数的主要功能是寻找所有增强器中适用于当前class的增强器。而对于正确的匹配就是由canApply方法来实现。

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 <strong>canApply(pca.getPointcut(), targetClass, hasIntroductions)</strong>;
}
else {
// It doesn't have a pointcut so we assume it applies.
return true;
}
}

上面的return canApply(pca.getPointcut(),targetClass,hasIntroductions)的方法其实是调用下面的canApply的方法。

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();
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}

Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
classes.add(targetClass);
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;
}

3.总结

Spring的AOP代理,其中所要做的事情无非就是两步:获取增强方法或者增强器,和根据获取的增强进行代理。当然,对于获取增强方法或增强器,思路如下:

1) 获取所有beanName,这一步骤所有在beanFactory中注册的Bean都会被提取出来。

2) 遍历所有beanName,并找出声明AspectJ注解的类,进行进一步的处理

3) 对标记为AspectJ注解的类进行增强的提取

4) 将提取结果加入缓存
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: