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 的源码很多, 想学深不简单, 加油!![]~( ̄▽ ̄)~*
来源:https://www.cnblogs.com/forwrader/p/6685367.html