1.开始步骤--获取AopProxy主流程

ProxyCreatorSupport.java

    /*** Subclasses should call this to get a new AOP proxy. They should <b>not</b>* create an AOP proxy with <code>this</code> as an argument.*/protected final synchronized AopProxy createAopProxy() {if (!this.active) {activate();}return getAopProxyFactory().createAopProxy(this);}

2.获取AopProxy实现  --DefaultAopProxyFactory.java

ProxyFactoryBean类继承了AdvisedSupport类,后者继承了ProxyConfig类并定义了操作advisor 和interceptor的接口,以支持AOP。当BeanFactory实例化ProxyFactoryBean时,根据配置文件的定义将关于 advice,pointcut,advisor,所代理的接口和接口实现类的所有信息传给ProxyFactoryBean。

当客户程序调用BeanFactory的getBean方法时,ProxyFactory使用JdkDynamicAopProxy实例化 BeanImpl类,并用JdkDynamicAopProxy的invoke方法执行advice。至于执行advice的时机,由 ProxyFactoryBean调用RegexpMethodPointcutAdvisor进行判断。
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {Class targetClass = config.getTargetClass();if (targetClass == null) {throw new AopConfigException("TargetSource cannot determine target class: " +"Either an interface or a target is required for proxy creation.");}if (targetClass.isInterface()) {return new JdkDynamicAopProxy(config);}if (!cglibAvailable) {throw new AopConfigException("Cannot proxy target class because CGLIB2 is not available. " +"Add CGLIB to the class path or specify proxy interfaces.");}return CglibProxyFactory.createCglibProxy(config);}else {return new JdkDynamicAopProxy(config);}}

3.获取AopProxy的执行路径

    public Object getProxy(ClassLoader classLoader) {if (logger.isDebugEnabled()) {logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());}Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);}

4.激发拦截器链主过程

 1     /**
 2      * Implementation of <code>InvocationHandler.invoke</code>.
 3      * <p>Callers will see exactly the exception thrown by the target,
 4      * unless a hook method throws an exception.
 5      */
 6     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
 7         MethodInvocation invocation = null;
 8         Object oldProxy = null;
 9         boolean setProxyContext = false;
10
11         TargetSource targetSource = this.advised.targetSource;
12         Class targetClass = null;
13         Object target = null;
14
15         try {
16             if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
17                 // The target does not implement the equals(Object) method itself.
18                 return (equals(args[0]) ? Boolean.TRUE : Boolean.FALSE);
19             }
20             if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
21                 // The target does not implement the hashCode() method itself.
22                 return new Integer(hashCode());
23             }
24             if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
25                     method.getDeclaringClass().isAssignableFrom(Advised.class)) {
26                 // Service invocations on ProxyConfig with the proxy config...
27                 return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
28             }
29
30             Object retVal = null;
31
32             if (this.advised.exposeProxy) {
33                 // Make invocation available if necessary.
34                 oldProxy = AopContext.setCurrentProxy(proxy);
35                 setProxyContext = true;
36             }
37
38             // May be <code>null</code>. Get as late as possible to minimize the time we "own" the target,
39             // in case it comes from a pool.
40             target = targetSource.getTarget();
41             if (target != null) {
42                 targetClass = target.getClass();
43             }
44
45             // Get the interception chain for this method.
46             List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
47
48             // Check whether we have any advice. If we don't, we can fallback on direct
49             // reflective invocation of the target, and avoid creating a MethodInvocation.
50             if (chain.isEmpty()) {
51                 // We can skip creating a MethodInvocation: just invoke the target directly
52                 // Note that the final invoker must be an InvokerInterceptor so we know it does
53                 // nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
54                 retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
55             }
56             else {
57                 // We need to create a method invocation...
58                 invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
59                 // Proceed to the joinpoint through the interceptor chain.
60                 retVal = invocation.proceed();
61             }
62
63             // Massage return value if necessary.
64             if (retVal != null && retVal == target && method.getReturnType().isInstance(proxy) &&
65                     !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
66                 // Special case: it returned "this" and the return type of the method
67                 // is type-compatible. Note that we can't help if the target sets
68                 // a reference to itself in another returned object.
69                 retVal = proxy;
70             }
71             return retVal;
72         }
73         finally {
74             if (target != null && !targetSource.isStatic()) {
75                 // Must have come from TargetSource.
76                 targetSource.releaseTarget(target);
77             }
78             if (setProxyContext) {
79                 // Restore old proxy.
80                 AopContext.setCurrentProxy(oldProxy);
81             }
82         }
83     }

5.获取拦截器链DefaultAdvisorChainFactory.java

    public List getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, Class targetClass) {// This is somewhat tricky... we have to process introductions first,// but we need to preserve order in the ultimate list.List interceptorList = new ArrayList(config.getAdvisors().length);boolean hasIntroductions = hasMatchingIntroductions(config, targetClass);AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();Advisor[] advisors = config.getAdvisors();for (int i = 0; i < advisors.length; i++) {Advisor advisor = advisors[i];if (advisor instanceof PointcutAdvisor) {// Add it conditionally.PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(targetClass)) {MethodInterceptor[] interceptors = registry.getInterceptors(advisor);MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();if (MethodMatchers.matches(mm, method, targetClass, hasIntroductions)) {if (mm.isRuntime()) {// Creating a new object instance in the getInterceptors() method// isn't a problem as we normally cache created chains.for (int j = 0; j < interceptors.length; j++) {interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptors[j], mm));}}else {interceptorList.addAll(Arrays.asList(interceptors));}}}}else if (advisor instanceof IntroductionAdvisor) {IntroductionAdvisor ia = (IntroductionAdvisor) advisor;if (config.isPreFiltered() || ia.getClassFilter().matches(targetClass)) {Interceptor[] interceptors = registry.getInterceptors(advisor);interceptorList.addAll(Arrays.asList(interceptors));}}else {Interceptor[] interceptors = registry.getInterceptors(advisor);interceptorList.addAll(Arrays.asList(interceptors));}}return interceptorList;}

6.激发拦截链工作实现 ---ReflectiveMethodInvocation.java

    public Object proceed() throws Throwable {//    We start with an index of -1 and increment early.if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {return invokeJoinpoint();}Object interceptorOrInterceptionAdvice =this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {// Evaluate dynamic method matcher here: static part will already have// been evaluated and found to match.InterceptorAndDynamicMethodMatcher dm =(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {return dm.interceptor.invoke(this);}else {// Dynamic matching failed.// Skip this interceptor and invoke the next in the chain.return proceed();}}else {// It's an interceptor, so we just invoke it: The pointcut will have// been evaluated statically before this object was constructed.return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);}}

转载于:https://www.cnblogs.com/davidwang456/archive/2013/03/19/2969417.html

spring aop实现过程之二Spring AOP中拦截器链相关推荐

  1. Spring AOP源码解析-拦截器链的执行过程

    一.简介 在前面的两篇文章中,分别介绍了 Spring AOP 是如何为目标 bean 筛选合适的通知器,以及如何创建代理对象的过程.现在得到了 bean 的代理对象,且通知也以合适的方式插在了目标方 ...

  2. Spring AOP 源码分析 - 拦截器链的执行过程

    1.简介 本篇文章是 AOP 源码分析系列文章的最后一篇文章,在前面的两篇文章中,我分别介绍了 Spring AOP 是如何为目标 bean 筛选合适的通知器,以及如何创建代理对象的过程.现在我们的得 ...

  3. spring---aop(3)---Spring AOP的拦截器链

    写在前面 时间断断续续,这次写一点关于spring aop拦截器链的记载.至于如何获取spring的拦截器,前一篇博客已经写的很清楚(spring---aop(2)---Spring AOP的JDK动 ...

  4. 【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【拦截器机制】

    [Java EE (Struts2 + Spring + Hibernate)开发]:Struts2(二)之[拦截器机制] 本文地址:http://blog.csdn.net/shanglianlm/ ...

  5. Spring异步调用原理及SpringAop拦截器链原理

    一.Spring异步调用底层原理 开启异步调用只需一个注解@EnableAsync @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTI ...

  6. Spring+SpringMVC+MyBatis深入学习及搭建(十七)——SpringMVC拦截器

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7098753.html 前面讲到:Spring+SpringMVC+MyBatis深入学习及搭建(十六)--S ...

  7. Spring Boot:(五)静态资源和拦截器处理

    Spring Boot:(五)静态资源和拦截器处理 前言 本章我们来介绍下SpringBoot对静态资源的支持以及很重要的一个类WebMvcConfigurerAdapter. 正文 前面章节我们也有 ...

  8. 关于Spring中拦截器的使用

    关于Spring中拦截器的使用 1 拦截器的概述 1 拦截器说明及应用场景 2 Spring中的拦截器 HandlerInterceptor 3 流程说明 2 简单使用案例 1 准备环境 1 准备文件 ...

  9. springmvc学习笔记二:重定向,拦截器,参数绑定

    springmvc学习笔记二:重定向,拦截器,参数绑定 Controller方法返回值 返回ModelAndView controller方法中定义ModelAndView对象并返回,对象中可添加mo ...

最新文章

  1. python格式化html库_用Python格式化HTML代码
  2. UI设计培训:UI构思创意技巧和方法
  3. 【android】android中activity的生命周期
  4. 八十二、Python | Leetcode贪心算法系列
  5. vue2.0+stylus实现星级评定组件,computed计算属性实现全星半星,动态改变星级,多种星星规格
  6. 【C# 调用 Go 语言】0x1 Hello Golang
  7. Spring Boot中的高级配置文件管理
  8. 大学物理实验长度的测量实验报告_大学物理实验教案长度和质量的测量两篇
  9. jstat gc各参数含义
  10. 2013年美国国情咨文总结
  11. 详述RFID服装智能管理方案
  12. vos3000_v7.x版本的快速安装方法
  13. ENVI/IDL编程:相对辐射校正-直方图匹配
  14. python培训班-python培训班哪家好
  15. 只有程序员才能读懂的三国演义(一)
  16. Python模拟随机游走
  17. Oracle数据库实例之进程架构(二)
  18. 史记花絮(四)——宋微子世家
  19. html像素小鸟小游戏,微信小游戏-像素鸟游戏
  20. string.h头文件的简单运用

热门文章

  1. python生成器杨辉三角_python 生成器生成杨辉三角的方法(必看)
  2. java 日志输出 上下文_java – 使用ServletContextListener和SLF4J在contextDestroyed上没有日志输出...
  3. python两个数据表中的对应数据相加
  4. bootstrap 点击加号 表格_bootstrap中的输入组按钮,点击加号加1,减1子
  5. ai怎么画循环曲线,怎么用 Adobe Illustrator 画出曲率连续的曲线?
  6. java 获取操作系统临时目录_获取当前操作系统的临时目录对象或者地址
  7. activity中fragment 返回键不退出_优雅地处理加载中(loading),重试(retry)和无数据(empty)等...
  8. 中过滤记录中时间_水肥一体化中如何选择过滤器
  9. kib,mib和mb,kb的区别
  10. Ubuntu20.04软件源更换