Spring源码之创建AOP代理(补)
2016-03-20 18:36
746 查看
在上一章节中,我们已经知道了如何获取增强器,但是我们还一件事还未做,那就是寻找匹配的增强器。下面我们来看这个功能的时序图。
findAdvisorsThatCanApply函数的主要功能是寻找所有增强器中适用于当前class的增强器。而对于正确的匹配就是由canApply方法来实现。
上面的return canApply(pca.getPointcut(),targetClass,hasIntroductions)的方法其实是调用下面的canApply的方法。
1) 获取所有beanName,这一步骤所有在beanFactory中注册的Bean都会被提取出来。
2) 遍历所有beanName,并找出声明AspectJ注解的类,进行进一步的处理
3) 对标记为AspectJ注解的类进行增强的提取
4) 将提取结果加入缓存
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) 将提取结果加入缓存
相关文章推荐
- Maven+Spring 4+Spring MVC(二)
- RDD动态转换成DataFrame
- 20145101《Java程序设计》第三周学习总结
- Java - Collection
- 《Java程序设计》第3周学习总结
- Java - java.util.Iterator
- [置顶] Java、MySQL 、SQLite出错集
- Java - hashCode() - equals()
- Spring源码之创建AOP代理
- Spring源码之动态AOP自定义标签
- java集合框架
- Java - 正则表达式 - Pattern - Matcher
- Java数据类型
- 20145120 《Java程序设计》第3周学习总结
- Spring实现AOP源码分析
- struts 整合Hibernate 报错: no session or session was closed
- (java并发)ScheduledThreadPoolExcutor
- Can not find a java.io.InputStream with the name [inputStream] in the invocation stack. Check the <p
- IntelliJ IDEA spring mvc +mybatis 环境搭建服务器(中)
- java第二次作业