首页 > 代码库 > Spring源码学习笔记(7)
Spring源码学习笔记(7)
Spring源码学习笔记(七)
前言--
最近花了些时间看了《Spring源码深度解析》这本书,算是入门了Spring的源码吧。打算写下系列文章,回忆一下书的内容,总结代码的运行流程。推荐那些和我一样没接触过SSH框架源码又想学习的,阅读郝佳编著的《Spring源码深度解析》这本书,会是个很好的入门
写前说句话, 开篇不尴尬 ---- 接下的这一篇当中, 我们将来回顾 Spring 中 AOP 功能的实现流程。 早上精力充沛, 开始新一天的学习 \(^o^)/~
接触过 Spring 框架的同学都知道, Spring 中使用的两个功能无非就是依赖注入的 DI 以及面向切面编程的 AOP, 其中 AOP 又包括了动态 AOP 和静态 AOP 两个方向。 首先,我们来看看 Spring 是如何实现我们最常接触到的动态 AOP 的。
动态AOP
启用 Spring 的 AOP 功能, 需要我们在 Spring 的配置文件中添加 <aop:aspectj-autoproxy/> 。我们将从这个配置为入口看看 AOP 的实现过程。
在 AopNamespaceHandler 中, 有一下初始化代码:
1 public class AopNamespaceHandler extends NamespaceHandlerSupport { 2 public AopNamespaceHandler() { 3 } 4 5 public void init() { 6 this.registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser()); 7 //第一步: 在此注册 AOP 功能 8 this.registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser()); 9 this.registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator()); 10 this.registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser()); 11 } 12 }
进入 AspectJAutoProxyBeanDefinitionParser 类中, 发现该类实现了 BeanDefinitionParser 接口, 所以查看该类的 parse() 方法, 其实现逻辑:
1 public BeanDefinition parse(Element element, ParserContext parserContext) { 2 //第一步: 注册 AnnotationAwareAspectJAutoProxyCreator 3 4 AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element); 5 this.extendBeanDefinition(element, parserContext); 6 return null; 7 }
进入 registerAspectJAnnotationAutoProxyCreatorIfNecessary() 方法中查看实现逻辑:
1 public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(ParserContext parserContext, Element sourceElement) { 2 //第一步: 注册 AutoProxyCreator 的 BeanDefinition 3 BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext.getRegistry(), parserContext.extractSource(sourceElement)); 4 //第二步: 处理 proxy-target-class 和 expose-proxy 属性 5 useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement); 6 //第三步: 通知监听器, beanDefinition 的 className 为 AnnotationAwareAspectJAutoProxyCreator 7 registerComponentIfNecessary(beanDefinition, parserContext); 8 }
进入 registerAspectJAnnotationAutoProxyCreatorIfNecessary() 方法, 一步步查看三个方法中的每个方法.
首先 registerAspectJAnnotationAutoProxyCreatorIfNecessary(), 注册实现 AOP 功能的 AnnotationAwareAspectJAutoProxyCreator 类:
1 public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) { 2 // 第一步: 继续方法的调用 3 return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source); 4 }
1 private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) { 2 Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); 3 //第一步: 判断是否已经存在 AutoProxyCreator 且存在的 Creator 和当前的不一致, 需要决定使用哪个 4 if(registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) { 5 BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator"); 6 if(!cls.getName().equals(apcDefinition.getBeanClassName())) { 7 int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName()); 8 int requiredPriority = findPriorityForClass(cls); 9 if(currentPriority < requiredPriority) { 10 apcDefinition.setBeanClassName(cls.getName()); 11 } 12 } 13 //第二步: 存在 AutoProxyCreator 且与当前的一致, 则直接返回 14 return null; 15 } else { 16 //第三步: 重新创建 AutoProxyCreator 17 RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); 18 beanDefinition.setSource(source); 19 beanDefinition.getPropertyValues().add("order", Integer.valueOf(-2147483648)); 20 beanDefinition.setRole(2); 21 registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition); 22 return beanDefinition; 23 } 24 }
简单易懂, 条理清晰, 我喜欢 ~( ̄▽ ̄)~*
接下来在 registerAspectJAnnotationAutoProxyCreatorIfNecessary() 方法中, 第二步对 proxy-target-class 和 expose-proxy 属性的处理的 useClassProxyingIfNecessary() 逻辑:
1 private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Element sourceElement) { 2 if(sourceElement != null) { 3 //第一步: 处理 proxy-target-class 4 boolean proxyTargetClass = Boolean.valueOf(sourceElement.getAttribute("proxy-target-class")).booleanValue(); 5 if(proxyTargetClass) { 6 AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); 7 } 8 //第二步: 处理 expose-proxy 9 boolean exposeProxy = Boolean.valueOf(sourceElement.getAttribute("expose-proxy")).booleanValue(); 10 if(exposeProxy) { 11 AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry); 12 } 13 } 14 15 }
进入处理 proxy-target-class 属性的逻辑:
1 public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) { 2 if(registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) { 3 BeanDefinition definition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator"); 4 //第一步: 为 BeanDefinition 添加 proxyTargetClass 属性 5 definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE); 6 } 7 8 }
进入处理 expose-proxy 属性的逻辑:
1 static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) { 2 if(registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) { 3 BeanDefinition definition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator"); 4 //第一步: 为 BeanDefinition 添加 exposeProxy 属性 5 definition.getPropertyValues().add("exposeProxy", Boolean.TRUE); 6 } 7 8 }
实现的逻辑很简单, 为 BeanDefinition 添加了不同的属性。 Spring 使用 JDK 的动态代理 或者使用 CGLIB 创建代理类, 使用 proxy-target-class 配置来决定使用哪种方式,需要注意其中使用的区别:
1, 强制使用 CGLIB 生成代理类, 配置 <aop:config proxy-target-class="true"/>;
2, 使用 CGLIB 和 @AspectJ 自动代理时, 配置 <aop:aspectj-autoproxy proxy-target-class="true"/>;
3, 只有在类有实现接口的情况下, 才能使用 JDK 的动态代理生成代理类, 使用 CGLIB 的时候需要注意不能通知 final 方法;
而对于 expose-proxy 的是情况是, 在代理的目标类里, 类方法调用自身的方法时, 被调用方法不会再调用方法的增强逻辑, 若需要调用, 则需要配置:
<aop:aspectj-autoproxy expose-proxy="true"/>
讲了这么多, 发现我们只是看到了 Spring AOP 的入口方法以及基础的实现类, 而真正的创建 代理类 的逻辑我们并没有看到,因此,这就是我们接下来要做的事情。
上面讲到 Spring AOP 的基本的实现类是 AnnotationAwareAspectJAutoProxyCreator , 使用 IntelliJ 的功能, 我们瞄一下该类的层次结构:
可以看到 AnnotationAwareAspectJAutoProxyCreator 实现了 BeanPostProcessor 类,查看其实现的方法, 在父类 AbstractAutoProxyCreator 中:
1 public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 2 if(bean != null) { 3 //第一步: 构建对应 bean 的 className_beanName 的 key 4 Object cacheKey = this.getCacheKey(bean.getClass(), beanName); 5 if(!this.earlyProxyReferences.contains(cacheKey)) { 6 //第二步: 需要代理, 封装 bean 7 return this.wrapIfNecessary(bean, beanName, cacheKey); 8 } 9 } 10 11 return bean; 12 }
1 protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { 2 //第一步: 已经处理过直接返回 3 if(beanName != null && this.targetSourcedBeans.contains(beanName)) { 4 return bean; 5 } else 6 //第二步: 无需增强直接返回 7 if(Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { 8 return bean; 9 } //第三步: 略过 基础类 或者 配置了 不用代理 10 else if(!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) { 11 //第四步: 获取 增强器 12 Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null); 13 //第五步: 存在增强则增强 14 if(specificInterceptors != DO_NOT_PROXY) { 15 this.advisedBeans.put(cacheKey, Boolean.TRUE); 16 //第六步: 用增强器创建代理类 17 Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); 18 this.proxyTypes.put(cacheKey, proxy.getClass()); 19 return proxy; 20 } else { 21 this.advisedBeans.put(cacheKey, Boolean.FALSE); 22 return bean; 23 } 24 } else { 25 this.advisedBeans.put(cacheKey, Boolean.FALSE); 26 return bean; 27 } 28 }
看起来很简单, 是否爽了一把, 接下来分分点分析其中的逻辑。
一, 获取增强器
1 protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) { 2 List<Advisor> advisors = this.findEligibleAdvisors(beanClass, beanName); 3 return advisors.isEmpty()?DO_NOT_PROXY:advisors.toArray(); 4 }
1 protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { 2 //第一步: 查询所有的增强 3 List<Advisor> candidateAdvisors = this.findCandidateAdvisors(); 4 //第二步: 查询适合的增强 5 List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); 6 this.extendAdvisors(eligibleAdvisors); 7 if(!eligibleAdvisors.isEmpty()) { 8 eligibleAdvisors = this.sortAdvisors(eligibleAdvisors); 9 } 10 11 return eligibleAdvisors; 12 }
我不想解释, 你也不想听!!!( *^-^)ρ(*╯^╰)
查询所有的增强的方法 findCandidateAdvisors() 的实现逻辑, 在 AnnotationAwareAspectJAutoProxyCreator 类中:
1 protected List<Advisor> findCandidateAdvisors() { 2 //第一步: 调用父类加载 XML 文件的方法 3 List<Advisor> advisors = super.findCandidateAdvisors(); 4 //第二步: 类扩展父类实现的通过注解获取增强的方法 5 advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); 6 return advisors; 7 }
由前面的 Diagram 图可以看出, AnnotationAwareAspectJAutoProxyCreator 类继承 AbstractAdvisorAutoProxyCreator 类, 子类在父类获取 XML 文件的增强之外, 还实现了从 @AspectJ 获取增强的方法。
在 findCandidateAdvisors() 方法中, 第二步通过注解获取增强的方法 buildAspectJAvisors() 的实现逻辑:
1 public List<Advisor> buildAspectJAdvisors() { 2 List<String> aspectNames = null; 3 synchronized(this) { 4 aspectNames = this.aspectBeanNames; 5 if(aspectNames == null) { 6 List<Advisor> advisors = new LinkedList(); 7 List<String> aspectNames = new LinkedList(); 8 //第一步: 获取所有的 beanName 9 String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false); 10 String[] var18 = beanNames; 11 int var19 = beanNames.length; 12 //第二步: 遍历所有的 beanName 找出增强方法 13 for(int var7 = 0; var7 < var19; ++var7) { 14 String beanName = var18[var7]; 15 if(this.isEligibleBean(beanName)) { 16 //第三步: 获取 bean 的类型 17 Class<?> beanType = this.beanFactory.getType(beanName); 18 //第四步: 存在 AspectJ 注解 (此处的 advisorFactory 是 AbstractAspectJAdvisorFactory) 19 if(beanType != null && this.advisorFactory.isAspect(beanType)) { 20 aspectNames.add(beanName); 21 AspectMetadata amd = new AspectMetadata(beanType, beanName); 22 if(amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { 23 MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); 24 //第五步:解析 AspectJ 注解的增强方法 25 List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory); 26 //第六步: 加入缓存的操作 27 if(this.beanFactory.isSingleton(beanName)) { 28 this.advisorsCache.put(beanName, classAdvisors); 29 } else { 30 this.aspectFactoryCache.put(beanName, factory); 31 } 32 33 advisors.addAll(classAdvisors); 34 } else { 35 if(this.beanFactory.isSingleton(beanName)) { 36 throw new IllegalArgumentException("Bean with name ‘" + beanName + "‘ is a singleton, but aspect instantiation model is not singleton"); 37 } 38 39 MetadataAwareAspectInstanceFactory factory = new PrototypeAspectInstanceFactory(this.beanFactory, beanName); 40 this.aspectFactoryCache.put(beanName, factory); 41 advisors.addAll(this.advisorFactory.getAdvisors(factory)); 42 } 43 } 44 } 45 } 46 47 this.aspectBeanNames = aspectNames; 48 return advisors; 49 } 50 } 51 52 if(aspectNames.isEmpty()) { 53 return Collections.emptyList(); 54 } else { 55 List<Advisor> advisors = new LinkedList(); 56 Iterator var3 = aspectNames.iterator(); 57 //第七步: 加入缓存的操作 58 while(var3.hasNext()) { 59 String aspectName = (String)var3.next(); 60 List<Advisor> cachedAdvisors = (List)this.advisorsCache.get(aspectName); 61 if(cachedAdvisors != null) { 62 advisors.addAll(cachedAdvisors); 63 } else { 64 MetadataAwareAspectInstanceFactory factory = (MetadataAwareAspectInstanceFactory)this.aspectFactoryCache.get(aspectName); 65 advisors.addAll(this.advisorFactory.getAdvisors(factory)); 66 } 67 } 68 69 return advisors; 70 } 71 }
在 buildAspectJAdvisors() 方法中, 第五步获取增强器的 getAdvisors() 的实现, 实现在 ReflectiveAspectJAdvisorFactory 类中:
1 public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory maaif) { 2 //第一步: 获取标记为 AspectJ 的类 3 Class<?> aspectClass = maaif.getAspectMetadata().getAspectClass(); 4 //第二步: 获取标记为 AspectJ 的名字 5 String aspectName = maaif.getAspectMetadata().getAspectName(); 6 this.validate(aspectClass); 7 MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = new LazySingletonAspectInstanceFactoryDecorator(maaif); 8 List<Advisor> advisors = new LinkedList(); 9 //第三步: 获取所有的方法 10 Iterator var6 = this.getAdvisorMethods(aspectClass).iterator(); 11 //第四步: 遍历所有的方法 12 while(var6.hasNext()) { 13 Method method = (Method)var6.next(); 14 Advisor advisor = this.getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName); 15 if(advisor != null) { 16 advisors.add(advisor); 17 } 18 } 19 //第五步: 增强器不为空且配置增强延迟初始化则封装同步化实例增强器 20 if(!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { 21 Advisor instantiationAdvisor = new ReflectiveAspectJAdvisorFactory.SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory); 22 advisors.add(0, instantiationAdvisor); 23 } 24 //第六步: 获取 DeclareParents 注解 25 Field[] var12 = aspectClass.getDeclaredFields(); 26 int var13 = var12.length; 27 28 for(int var14 = 0; var14 < var13; ++var14) { 29 Field field = var12[var14]; 30 Advisor advisor = this.getDeclareParentsAdvisor(field); 31 if(advisor != null) { 32 advisors.add(advisor); 33 } 34 } 35 36 return advisors; 37 }
在 getAdvisors() 方法中, 第四步普通增强器的获取方法 getAdvisor() 方法的实现逻辑:
1 public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aif, int declarationOrderInAspect, String aspectName) { 2 this.validate(aif.getAspectMetadata().getAspectClass()); 3 //第一步: 切点信息的获取 封装类 4 AspectJExpressionPointcut ajexp = this.getPointcut(candidateAdviceMethod, aif.getAspectMetadata().getAspectClass()); 5 //第二步: 根据切点信息生成增强器 也是封装类 6 return ajexp == null?null:new InstantiationModelAwarePointcutAdvisorImpl(this, ajexp, aif, candidateAdviceMethod, declarationOrderInAspect, aspectName); 7 }
在 getAdvisor() 方法中, 第一步切点信息的获取方法 getPointcut() 方法的实现逻辑, 封装成 AspectJExpressionPointcut 类:
1 private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) { 2 //第一步: 获取方法上的注解 3 AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod); 4 if(aspectJAnnotation == null) { 5 return null; 6 } else { 7 //第二步: 封装获取的信息 8 AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class[0]); 9 ajexp.setExpression(aspectJAnnotation.getPointcutExpression()); 10 return ajexp; 11 } 12 }
第一步中获取方法上的注解 findAspectJAnnotationOnMethod() 方法的实现逻辑: (这个方法值得注意一下~~~~~~~~~~~~~)
1 protected static AbstractAspectJAdvisorFactory.AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) { 2 //第一步: 列举所有的 注解的类 3 Class<?>[] classesToLookFor = new Class[]{Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class}; 4 Class[] var2 = classesToLookFor; 5 int var3 = classesToLookFor.length; 6 //第二步:遍历所有的注解类 匹配注解信息 7 for(int var4 = 0; var4 < var3; ++var4) { 8 Class<?> c = var2[var4]; 9 AbstractAspectJAdvisorFactory.AspectJAnnotation<?> foundAnnotation = findAnnotation(method, c); 10 if(foundAnnotation != null) { 11 return foundAnnotation; 12 } 13 } 14 15 return null; 16 }
在 findAspectJAnnotationOnMethod() 方法中, 第二步获取指定方法上的注解并使用 AspectJAnnotation 封装信息的 findAnnotation() 实现逻辑:
1 private static <A extends Annotation> AbstractAspectJAdvisorFactory.AspectJAnnotation<A> findAnnotation(Method method, Class<A> toLookFor) { 2 //第一步: 匹配注解类 3 A result = AnnotationUtils.findAnnotation(method, toLookFor); 4 //第二步: 封装到类中 5 return result != null?new AbstractAspectJAdvisorFactory.AspectJAnnotation(result):null; 6 }
瞄一下匹配注解类的方法 AnnotationUtils.findAnnotation() 的实现逻辑:
1 public static <A extends Annotation> A findAnnotation(Method method, Class<A> annotationType) { 2 //第一步: 获取注解 3 A annotation = getAnnotation(method, annotationType); 4 //第二步: 获取 class 5 Class<?> clazz = method.getDeclaringClass(); 6 if(annotation == null) { 7 annotation = searchOnInterfaces(method, annotationType, clazz.getInterfaces()); 8 } 9 //第三步: 递归到父类去查找 10 while(annotation == null) { 11 clazz = clazz.getSuperclass(); 12 if(clazz == null || clazz.equals(Object.class)) { 13 break; 14 } 15 16 try { 17 //第四步: 获取类中指定的方法 及 方法上的注解 18 Method equivalentMethod = clazz.getDeclaredMethod(method.getName(), method.getParameterTypes()); 19 annotation = getAnnotation(equivalentMethod, annotationType); 20 } catch (NoSuchMethodException var5) { 21 ; 22 } 23 24 if(annotation == null) { 25 annotation = searchOnInterfaces(method, annotationType, clazz.getInterfaces()); 26 } 27 } 28 29 return annotation; 30 }
在 findAnnotation() 方法中, 深入的实现逻辑并看不懂, 应该是从 getAnnotation() 和 searchOnInterfaces() 方法入口, 方法的重载也很多, 容易晕!!!
避实就虚, 抱大腿, 回到 getAdvisor() 方法中, 封装增强器的 InstantiationModelAwarePointcutAdvisorImpl 类是 Advisor 的实现类, 瞄一下该类的构造器:
1 public InstantiationModelAwarePointcutAdvisorImpl(AspectJAdvisorFactory af, AspectJExpressionPointcut ajexp, MetadataAwareAspectInstanceFactory aif, Method method, int declarationOrderInAspect, String aspectName) { 2 // 例子 :@Before("test()") 3 //第一步: 被切入方法 test() 4 this.declaredPointcut = ajexp; 5 //第二步: 切入的方法 6 this.method = method; 7 this.atAspectJAdvisorFactory = af; 8 this.aspectInstanceFactory = aif; 9 this.declarationOrder = declarationOrderInAspect; 10 //第三步: 切面的名称 11 this.aspectName = aspectName; 12 //第四步:pointcut 是懒加载类型 13 if(aif.getAspectMetadata().isLazilyInstantiated()) { 14 Pointcut preInstantiationPointcut = Pointcuts.union(aif.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut); 15 this.pointcut = new InstantiationModelAwarePointcutAdvisorImpl.PerTargetInstantiationModelPointcut(this.declaredPointcut, preInstantiationPointcut, aif, (InstantiationModelAwarePointcutAdvisorImpl.SyntheticClass_1)null); 16 this.lazy = true; 17 } else { 18 //第五步: 单例 aspect 19 this.instantiatedAdvice = this.instantiateAdvice(this.declaredPointcut); 20 this.pointcut = this.declaredPointcut; 21 this.lazy = false; 22 } 23 24 }
在该构造方法中, 根据注解信息初始化对应的增强器 instantiateAdvice() 方法的实现逻辑:
1 private Advice instantiateAdvice(AspectJExpressionPointcut pcut) { 2 //第一步: 继续调用方法 3 return this.atAspectJAdvisorFactory.getAdvice(this.method, pcut, this.aspectInstanceFactory, this.declarationOrder, this.aspectName); 4 }
这里的 AspectJAdvisorFactory 类型的 atAspectJAdvisorFactory 对象是 ReflectiveAspectJAdvisorFactory 的实例,该类中的 getAdvice() 方法的实现逻辑:
1 public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut ajexp, MetadataAwareAspectInstanceFactory aif, int declarationOrderInAspect, String aspectName) { 2 Class<?> candidateAspectClass = aif.getAspectMetadata().getAspectClass(); 3 this.validate(candidateAspectClass); 4 AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod); 5 if(aspectJAnnotation == null) { 6 return null; 7 } else if(!this.isAspect(candidateAspectClass)) { 8 throw new AopConfigException("Advice must be declared inside an aspect type: Offending method ‘" + candidateAdviceMethod + "‘ in class [" + candidateAspectClass.getName() + "]"); 9 } else { 10 if(this.logger.isDebugEnabled()) { 11 this.logger.debug("Found AspectJ method: " + candidateAdviceMethod); 12 } 13 14 Object springAdvice; 15 //第一步: 对不同增强器的方法封装不同的类 16 switch(ReflectiveAspectJAdvisorFactory.SyntheticClass_1.$SwitchMap$org$springframework$aop$aspectj$annotation$AbstractAspectJAdvisorFactory$AspectJAnnotationType[aspectJAnnotation.getAnnotationType().ordinal()]) { 17 case 1: 18 springAdvice = new AspectJMethodBeforeAdvice(candidateAdviceMethod, ajexp, aif); 19 break; 20 case 2: 21 springAdvice = new AspectJAfterAdvice(candidateAdviceMethod, ajexp, aif); 22 break; 23 case 3: 24 springAdvice = new AspectJAfterReturningAdvice(candidateAdviceMethod, ajexp, aif); 25 AfterReturning afterReturningAnnotation = (AfterReturning)aspectJAnnotation.getAnnotation(); 26 if(StringUtils.hasText(afterReturningAnnotation.returning())) { 27 ((AbstractAspectJAdvice)springAdvice).setReturningName(afterReturningAnnotation.returning()); 28 } 29 break; 30 case 4: 31 springAdvice = new AspectJAfterThrowingAdvice(candidateAdviceMethod, ajexp, aif); 32 AfterThrowing afterThrowingAnnotation = (AfterThrowing)aspectJAnnotation.getAnnotation(); 33 if(StringUtils.hasText(afterThrowingAnnotation.throwing())) { 34 ((AbstractAspectJAdvice)springAdvice).setThrowingName(afterThrowingAnnotation.throwing()); 35 } 36 break; 37 case 5: 38 springAdvice = new AspectJAroundAdvice(candidateAdviceMethod, ajexp, aif); 39 break; 40 case 6: 41 if(this.logger.isDebugEnabled()) { 42 this.logger.debug("Processing pointcut ‘" + candidateAdviceMethod.getName() + "‘"); 43 } 44 45 return null; 46 default: 47 throw new UnsupportedOperationException("Unsupported advice type on method " + candidateAdviceMethod); 48 } 49 //第二步: 配置增强器 50 ((AbstractAspectJAdvice)springAdvice).setAspectName(aspectName); 51 ((AbstractAspectJAdvice)springAdvice).setDeclarationOrder(declarationOrderInAspect); 52 String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod); 53 if(argNames != null) { 54 ((AbstractAspectJAdvice)springAdvice).setArgumentNamesFromStringArray(argNames); 55 } 56 57 ((AbstractAspectJAdvice)springAdvice).calculateArgumentBindings(); 58 return (Advice)springAdvice; 59 } 60 }
从上面的 getAdvice() 方法中,我们可以看出, 对不同的注解 Spring 会生成不同的 Advice 进行处理。
对 @AtBefore 注解, 对应的是 AspectJMethodBeforeAdvice : (逻辑是对的, 但是找不到 AspectJMethodBeforeAdvice 和 MethodBeforeAdviceInterceptor 的关系 ( ̄~ ̄) !)
1 public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable { 2 private MethodBeforeAdvice advice; 3 4 public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) { 5 //第一步: 构造函数中传入一个 MethodBeforeAdvice 6 Assert.notNull(advice, "Advice must not be null"); 7 this.advice = advice; 8 } 9 //第二步: 调用 before() 方法 10 public Object invoke(MethodInvocation mi) throws Throwable { 11 this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis()); 12 return mi.proceed(); 13 } 14 }
其中的 advice 属性是 AspectJMethodBeforeAdvice 类的, 查看 before() 方法:
1 public void before(Method method, Object[] args, Object target) throws Throwable { 2 this.invokeAdviceMethod(this.getJoinPointMatch(), (Object)null, (Throwable)null); 3 }
1 protected Object invokeAdviceMethod(JoinPointMatch jpMatch, Object returnValue, Throwable ex) throws Throwable { 2 return this.invokeAdviceMethodWithGivenArgs(this.argBinding(this.getJoinPoint(), jpMatch, returnValue, ex)); 3 }
1 protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable { 2 //第一步: 获取参数 3 Object[] actualArgs = args; 4 if(this.aspectJAdviceMethod.getParameterTypes().length == 0) { 5 actualArgs = null; 6 } 7 8 try { 9 ReflectionUtils.makeAccessible(this.aspectJAdviceMethod); 10 //第二步: 调用方法 11 return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs); 12 } catch (IllegalArgumentException var4) { 13 throw new AopInvocationException("Mismatch on arguments to advice method [" + this.aspectJAdviceMethod + "]; pointcut expression [" + this.pointcut.getPointcutExpression() + "]", var4); 14 } catch (InvocationTargetException var5) { 15 throw var5.getTargetException(); 16 } 17 }
而对于 @After 注解, 对应的是 AspectJAfterAdvice 类 :
1 public class AspectJAfterAdvice extends AbstractAspectJAdvice implements MethodInterceptor, AfterAdvice { 2 public AspectJAfterAdvice(Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) { 3 super(aspectJBeforeAdviceMethod, pointcut, aif); 4 } 5 6 public Object invoke(MethodInvocation mi) throws Throwable { 7 Object var2; 8 try { 9 //第一步: 调用 被切入方法 10 var2 = mi.proceed(); 11 } finally { 12 //第二步: 调用 切入方法 13 this.invokeAdviceMethod(this.getJoinPointMatch(), (Object)null, (Throwable)null); 14 } 15 16 return var2; 17 } 18 19 public boolean isBeforeAdvice() { 20 return false; 21 } 22 23 public boolean isAfterAdvice() { 24 return true; 25 } 26 }
way so far, way so hard! 可能已经忘了, 回到 getAdvisors() 方法的第五步中, 同步实例化增强器 SyntheticInstantiationAdvisor 的作用, 该类是 ReflectiveAspectJAdvisorFactory 的一个内部类:
1 protected static class SyntheticInstantiationAdvisor extends DefaultPointcutAdvisor { 2 public SyntheticInstantiationAdvisor(final MetadataAwareAspectInstanceFactory aif) { 3 super(aif.getAspectMetadata().getPerClausePointcut(), new MethodBeforeAdvice() { 4 //第一步: 目标方法前调用 before 方法 5 public void before(Method method, Object[] args, Object target) { 6 //第二步: 初始化 aspect 7 aif.getAspectInstance(); 8 } 9 }); 10 } 11 }
在 getAdvisors() 方法中, 第六步获取 DeclareParents 注解的作用主要是处理 IntroductionAdvisor ,具体干什么的其实我也没见过 (? _ ?)
1 private Advisor getDeclareParentsAdvisor(Field introductionField) { 2 DeclareParents declareParents = (DeclareParents)introductionField.getAnnotation(DeclareParents.class); 3 if(declareParents == null) { 4 return null; 5 } else if(DeclareParents.class.equals(declareParents.defaultImpl())) { 6 throw new IllegalStateException("defaultImpl must be set on DeclareParents"); 7 } else { 8 // 封装信息 9 return new DeclareParentsAdvisor(introductionField.getType(), declareParents.value(), declareParents.defaultImpl()); 10 } 11 }
不骗你, 这么多的代码,其实只是 findEligibleAdvisors() 方法中的 findCandidateAdvisors() 方法的深入, 找到所有的增强器之后还需要找合适的增强器 findAdvisorsThatCanApply():
1 protected List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) { 2 ProxyCreationContext.setCurrentProxiedBeanName(beanName); 3 4 List var4; 5 try { 6 //第一步: 过滤已经得到的 advisors 7 var4 = AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass); 8 } finally { 9 ProxyCreationContext.setCurrentProxiedBeanName((String)null); 10 } 11 12 return var4; 13 }
1 public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) { 2 if(candidateAdvisors.isEmpty()) { 3 return candidateAdvisors; 4 } else { 5 List<Advisor> eligibleAdvisors = new LinkedList(); 6 Iterator var3 = candidateAdvisors.iterator(); 7 8 while(var3.hasNext()) { 9 Advisor candidate = (Advisor)var3.next(); 10 //第一步: 首先处理 IntroductionAdvisor 11 if(candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) { 12 eligibleAdvisors.add(candidate); 13 } 14 } 15 16 boolean hasIntroductions = !eligibleAdvisors.isEmpty(); 17 Iterator var7 = candidateAdvisors.iterator(); 18 19 while(var7.hasNext()) { 20 Advisor candidate = (Advisor)var7.next(); 21 //第二步: 略过已经处理的 IntroductionAdvisor 并处理普通的 bean 22 if(!(candidate instanceof IntroductionAdvisor) && canApply(candidate, clazz, hasIntroductions)) { 23 eligibleAdvisors.add(candidate); 24 } 25 } 26 27 return eligibleAdvisors; 28 } 29 }
1 public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) { 2 //第一步: 处理 IntroductionAdvisor 3 if(advisor instanceof IntroductionAdvisor) { 4 return ((IntroductionAdvisor)advisor).getClassFilter().matches(targetClass); 5 } else if(advisor instanceof PointcutAdvisor) { 6 //第二步: 处理 普通 bean 7 PointcutAdvisor pca = (PointcutAdvisor)advisor; 8 return canApply(pca.getPointcut(), targetClass, hasIntroductions); 9 } else { 10 return true; 11 } 12 }
1 public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) { 2 Assert.notNull(pc, "Pointcut must not be null"); 3 if(!pc.getClassFilter().matches(targetClass)) { 4 return false; 5 } else { 6 MethodMatcher methodMatcher = pc.getMethodMatcher(); 7 IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null; 8 if(methodMatcher instanceof IntroductionAwareMethodMatcher) { 9 introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher)methodMatcher; 10 } 11 12 Set<Class<?>> classes = new HashSet(ClassUtils.getAllInterfacesForClassAsSet(targetClass)); 13 classes.add(targetClass); 14 Iterator var6 = classes.iterator(); 15 16 while(var6.hasNext()) { 17 Class<?> clazz = (Class)var6.next(); 18 Method[] methods = clazz.getMethods(); 19 Method[] var9 = methods; 20 int var10 = methods.length; 21 //第一步: 遍历所有的方法并进行方法匹配 22 for(int var11 = 0; var11 < var10; ++var11) { 23 Method method = var9[var11]; 24 if(introductionAwareMethodMatcher != null && introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) || methodMatcher.matches(method, targetClass)) { 25 return true; 26 } 27 } 28 } 29 30 return false; 31 } 32 }
二, 创建代理
网上拉,知道看到 wrapIfNecessary() 方法中的第二步, 通过获取的增强器创建代理的 createProxy() 方法, 知道人生这么一天其实也就一个方法而已。。。。
1 protected Object createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) { 2 ProxyFactory proxyFactory = new ProxyFactory(); 3 //第一步: 获取当前类的相关属性 4 proxyFactory.copyFrom(this); 5 int var8; 6 int var9; 7 if(!this.shouldProxyTargetClass(beanClass, beanName)) { 8 //第二步: 添加接口 9 Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, this.proxyClassLoader); 10 Class[] var7 = targetInterfaces; 11 var8 = targetInterfaces.length; 12 13 for(var9 = 0; var9 < var8; ++var9) { 14 Class<?> targetInterface = var7[var9]; 15 proxyFactory.addInterface(targetInterface); 16 } 17 } 18 //第三步: 加入增强器 19 Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors); 20 Advisor[] var13 = advisors; 21 var8 = advisors.length; 22 23 for(var9 = 0; var9 < var8; ++var9) { 24 Advisor advisor = var13[var9]; 25 proxyFactory.addAdvisor(advisor); 26 } 27 //第四步: 设置要代理的类 28 proxyFactory.setTargetSource(targetSource); 29 //第五步: 使用自己的代理方法 30 this.customizeProxyFactory(proxyFactory); 31 //第六步: 设置代理之后是否允许修改 32 proxyFactory.setFrozen(this.freezeProxy); 33 if(this.advisorsPreFiltered()) { 34 proxyFactory.setPreFiltered(true); 35 } 36 //第七步: 创建代理对象 37 return proxyFactory.getProxy(this.proxyClassLoader); 38 }
在 createProxy() 方法的第三步中, 在加入增强器之前,需要把 拦截器封装成增强器的实现逻辑:
1 protected Advisor[] buildAdvisors(String beanName, Object[] specificInterceptors) { 2 //第一步: 解析所有注册的 interceptors 3 Advisor[] commonInterceptors = this.resolveInterceptorNames(); 4 List<Object> allInterceptors = new ArrayList(); 5 if(specificInterceptors != null) { 6 //第二步: 加入拦截器 7 allInterceptors.addAll(Arrays.asList(specificInterceptors)); 8 if(commonInterceptors != null) { 9 if(this.applyCommonInterceptorsFirst) { 10 allInterceptors.addAll(0, Arrays.asList(commonInterceptors)); 11 } else { 12 allInterceptors.addAll(Arrays.asList(commonInterceptors)); 13 } 14 } 15 } 16 int i; 17 18 Advisor[] advisors = new Advisor[allInterceptors.size()]; 19 20 for(i = 0; i < allInterceptors.size(); ++i) { 21 //第三步: 拦截器封装为 Advisor 22 advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i)); 23 } 24 25 return advisors; 26 }
1 public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException { 2 //第一步: 若本身已是 Advisor 则直接返回 3 if(adviceObject instanceof Advisor) { 4 return (Advisor)adviceObject; 5 } else if(!(adviceObject instanceof Advice)) { 6 //第二步: 不是 Advice 或 Advisor 则抛异常 7 throw new UnknownAdviceTypeException(adviceObject); 8 } else { 9 Advice advice = (Advice)adviceObject; 10 if(advice instanceof MethodInterceptor) { 11 //第三步: 处理 MethodInterceptor 的情况 12 return new DefaultPointcutAdvisor(advice); 13 } else { 14 Iterator var3 = this.adapters.iterator(); 15 //第四步: 存在 Advisor 的 adapter 同样封装 16 AdvisorAdapter adapter; 17 do { 18 if(!var3.hasNext()) { 19 throw new UnknownAdviceTypeException(advice); 20 } 21 22 adapter = (AdvisorAdapter)var3.next(); 23 } while(!adapter.supportsAdvice(advice)); 24 25 return new DefaultPointcutAdvisor(advice); 26 } 27 } 28 }
在 createProxy() 方法中, 根据获取的 Advisor 获取创建代理的 getProxy() 方法的实现逻辑:
1 public Object getProxy(ClassLoader classLoader) { 3 return this.createAopProxy().getProxy(classLoader); 5 }
首先看看 createAopProxy() 方法的实现:
1 protected final synchronized AopProxy createAopProxy() { 2 if(!this.active) { 3 this.activate(); 4 } 5 //第一步: 创建代理 6 return this.getAopProxyFactory().createAopProxy(this); 7 }
1 public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { 2 //第一步: 1, CGLIB 的优化策略 2, 代理目标类还是目标类的接口 3,是否存在代理接口 3 if(!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) { 4 //第二步: 使用 JDK 动态代理创建 5 return new JdkDynamicAopProxy(config); 6 } else { 7 Class<?> targetClass = config.getTargetClass(); 8 if(targetClass == null) { 9 throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation."); 10 } else { 11 //第三步: 接口吗 ? JDK 动态代理 : CGLIB 创建 12 return (AopProxy)(targetClass.isInterface()?new JdkDynamicAopProxy(config):new ObjenesisCglibAopProxy(config)); 13 } 14 } 15 }
嘿嘿嘿, 先看看 JDK 动态代理的创建方法, 在 JdkDynamicAopProxy 类中:
1 public Object getProxy(ClassLoader classLoader) { 2 //第一步: 获取接口 3 Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised); 4 this.findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); 5 //第二步: 创建代理 6 return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); 7 }
查看实现了 InvocationHandler 接口重写的 invoke() 方法:
1 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 2 Object oldProxy = null; 3 boolean setProxyContext = false; 4 TargetSource targetSource = this.advised.targetSource; 5 Class<?> targetClass = null; 6 Object target = null; 7 8 Object var13; 9 try { 10 //第一步: 处理 equals 方法 11 if(!this.equalsDefined && AopUtils.isEqualsMethod(method)) { 12 Boolean var18 = Boolean.valueOf(this.equals(args[0])); 13 return var18; 14 } 15 //第二步: 处理 hash 方法 16 if(!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) { 17 Integer var17 = Integer.valueOf(this.hashCode()); 18 return var17; 19 } 20 21 Object retVal; 22 if(!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) { 23 // 第三步: 调用切点方法 24 retVal = AopUtils.invokeJoinpointUsingReflection(this.advised, method, args); 25 return retVal; 26 } 27 //第四步: 之前讲述过的 expose-proxy 属性的情况的处理 28 if(this.advised.exposeProxy) { 29 oldProxy = AopContext.setCurrentProxy(proxy); 30 setProxyContext = true; 31 } 32 33 target = targetSource.getTarget(); 34 if(target != null) { 35 targetClass = target.getClass(); 36 } 37 //第五歩: 获取方法的拦截器链 38 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); 39 if(chain.isEmpty()) { 40 //第六步: 拦截器为空 调用切点方法 41 retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args); 42 } else { 43 //第七步: 拦截器不为空 封装拦截器并调用方法 44 MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); 45 retVal = invocation.proceed(); 46 } 47 //第八步: 返回结果 48 Class<?> returnType = method.getReturnType(); 49 if(retVal != null && retVal == target && returnType.isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) { 50 retVal = proxy; 51 } else if(retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) { 52 throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method); 53 } 54 55 var13 = retVal; 56 } finally { 57 if(target != null && !targetSource.isStatic()) { 58 targetSource.releaseTarget(target); 59 } 60 61 if(setProxyContext) { 62 AopContext.setCurrentProxy(oldProxy); 63 } 64 65 } 66 67 return var13; 68 }
在 JdkDynamicAopProxy 的 invoke() 方法中, 第七步调用拦截器链的 proceed() 实现逻辑, 方法在 ReflectiveMethodInvocation 类中, 从 jdk 又跑回 Spring 中了:
1 public Object proceed() throws Throwable { 2 if(this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { 3 return this.invokeJoinpoint(); 4 } else { 5 //第一步: 获取要执行的下一个拦截器 6 Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); 7 //第二步: 判断类型 8 if(interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { 9 InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice; 10 //第三步: 调用拦截器的方法 11 return dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)?dm.interceptor.invoke(this):this.proceed(); 12 } else { 13 //第四步: 若是普通的拦截器 直接调用方法 14 return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this); 15 } 16 } 17 }
大致了解了 Jdk 创建代理的方法, 下面瞄一下 CGLIB 创建代理的实现方法:
1 public Object getProxy(ClassLoader classLoader) { 2 if(logger.isDebugEnabled()) { 3 logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource()); 4 } 5 6 try { 7 Class<?> rootClass = this.advised.getTargetClass(); 8 Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy"); 9 Class<?> proxySuperClass = rootClass; 10 int x; 11 if(ClassUtils.isCglibProxyClass(rootClass)) { 12 proxySuperClass = rootClass.getSuperclass(); 13 Class<?>[] additionalInterfaces = rootClass.getInterfaces(); 14 Class[] var5 = additionalInterfaces; 15 int var6 = additionalInterfaces.length; 16 17 for(x = 0; x < var6; ++x) { 18 Class<?> additionalInterface = var5[x]; 19 this.advised.addInterface(additionalInterface); 20 } 21 } 22 23 this.validateClassIfNecessary(proxySuperClass); 24 //第一步:创建 CGLIB 必须的 Enchancer 并为其设置属性 25 Enhancer enhancer = this.createEnhancer(); 26 if(classLoader != null) { 27 enhancer.setClassLoader(classLoader); 28 if(classLoader instanceof SmartClassLoader && ((SmartClassLoader)classLoader).isClassReloadable(proxySuperClass)) { 29 enhancer.setUseCache(false); 30 } 31 } 32 33 enhancer.setSuperclass(proxySuperClass); 34 enhancer.setStrategy(new MemorySafeUndeclaredThrowableStrategy(UndeclaredThrowableException.class)); 35 enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised)); 36 //第二步: 为 enchancer 设置 拦截器 37 Callback[] callbacks = this.getCallbacks(rootClass); 38 Class<?>[] types = new Class[callbacks.length]; 39 40 for(x = 0; x < types.length; ++x) { 41 types[x] = callbacks[x].getClass(); 42 } 43 44 enhancer.setCallbackTypes(types); 45 enhancer.setCallbackFilter(new CglibAopProxy.ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset)); 46 //第三步: 生成代理及创建代理类 47 return this.createProxyClassAndInstance(enhancer, callbacks); 48 } 49 }
为 enchancer 设置拦截器的 getCallbacks() 方法的实现逻辑:
1 private Callback[] getCallbacks(Class<?> rootClass) throws Exception { 2 //第一步: 对于 expose-proxy 属性的处理 3 boolean exposeProxy = this.advised.isExposeProxy(); 4 boolean isFrozen = this.advised.isFrozen(); 5 boolean isStatic = this.advised.getTargetSource().isStatic(); 6 //第二步: 封装 DynamicAdvisedInterceptor 7 Callback aopInterceptor = new CglibAopProxy.DynamicAdvisedInterceptor(this.advised); 8 Object targetInterceptor; 9 if(exposeProxy) { 10 targetInterceptor = isStatic?new CglibAopProxy.StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()):new CglibAopProxy.DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()); 11 } else { 12 targetInterceptor = isStatic?new CglibAopProxy.StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()):new CglibAopProxy.DynamicUnadvisedInterceptor(this.advised.getTargetSource()); 13 } 14 15 Callback targetDispatcher = (Callback)(isStatic?new CglibAopProxy.StaticDispatcher(this.advised.getTargetSource().getTarget()):new CglibAopProxy.SerializableNoOp()); 16 //第三步: 加入拦截器 17 Callback[] mainCallbacks = new Callback[]{aopInterceptor, (Callback)targetInterceptor, new CglibAopProxy.SerializableNoOp(), targetDispatcher, this.advisedDispatcher, new CglibAopProxy.EqualsInterceptor(this.advised), new CglibAopProxy.HashCodeInterceptor(this.advised)}; 18 Callback[] callbacks; 19 if(isStatic && isFrozen) { 20 Method[] methods = rootClass.getMethods(); 21 Callback[] fixedCallbacks = new Callback[methods.length]; 22 this.fixedInterceptorMap = new HashMap(methods.length); 23 24 for(int x = 0; x < methods.length; ++x) { 25 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass); 26 fixedCallbacks[x] = new CglibAopProxy.FixedChainStaticTargetInterceptor(chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass()); 27 this.fixedInterceptorMap.put(methods[x].toString(), Integer.valueOf(x)); 28 } 29 30 callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length]; 31 System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length); 32 System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length); 33 this.fixedInterceptorOffset = mainCallbacks.length; 34 } else { 35 callbacks = mainCallbacks; 36 } 37 38 return callbacks; 39 }
(? _ ?) 神 TMD 的什么鬼, 看不懂啊 。。。。
在 CGLIB 中, 用 DynamicAdvisedInterceptor 封装了 增强器,查看该类中的 intercept() 方法:
1 public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { 2 Object oldProxy = null; 3 boolean setProxyContext = false; 4 Class<?> targetClass = null; 5 Object target = null; 6 7 Object var11; 8 try { 9 if(this.advised.exposeProxy) { 10 oldProxy = AopContext.setCurrentProxy(proxy); 11 setProxyContext = true; 12 } 13 14 target = this.getTarget(); 15 if(target != null) { 16 targetClass = target.getClass(); 17 } 18 19 //第一步: 获取拦截器你链 20 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); 21 Object retVal; 22 if(chain.isEmpty() && Modifier.isPublic(method.getModifiers())) { 23 //第二步: 拦截器为空则直接调用原方法 24 retVal = methodProxy.invoke(target, args); 25 } else { 26 //第三步: 拦截器不为空则调用链 27 retVal = (new CglibAopProxy.CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy)).proceed(); 28 } 29 //第四步: 改变返回值的类型并 返回结果 30 retVal = CglibAopProxy.processReturnType(proxy, target, method, retVal); 31 var11 = retVal; 32 } finally { 33 if(target != null) { 34 this.releaseTarget(target); 35 } 36 37 if(setProxyContext) { 38 AopContext.setCurrentProxy(oldProxy); 39 } 40 41 } 42 43 return var11; 44 }
看到返回结果之后,我们就大致了(bu)解(dong)了 CGLIB 的运行流程了。 (? _ ?)
本来想把 Spring AOP 中动态 AOP 和静态 AOP 的运行流程都大致回顾一遍的, 但是回顾了动态 AOP 的内容之后, 感觉还是有很多不懂的地方, 接下去不常用的静态 AOP 的内容会是瞎蒙吧, 以后深入了解后再把没做的部分完成吧。 Spring 的源码很多, 想学深不简单, 加油!![]~( ̄▽ ̄)~*
Spring源码学习笔记(7)