IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 《Spring源码深度解析 郝佳 第2版》AOP -> 正文阅读

[游戏开发]《Spring源码深度解析 郝佳 第2版》AOP

往期博客

《Spring源码深度解析 郝佳 第2版》容器的基本实现与XML文件的加载

《Spring源码深度解析 郝佳 第2版》XML标签的解析

《Spring源码深度解析 郝佳 第2版》bean的加载、循环依赖的解决

《Spring源码深度解析 郝佳 第2版》ApplicationContext

AOP面向切面编程,是一种思想,不同于OOP,他可以为不具有继承关系的对象引入一个公共行为如日志,安全监测等。具体实现分为两种

  • Spring AOP:动态代理,运行时生成代理对象。他的方便在于Spring帮助我们完成增强的自动织入,在Java中可以根据接口使用JDK动态代理和Cglib动态代理。由Spring自动为我们完成运行时织入。
  • AspectJ:静态代理,编译时直接修改字节码,AspectJ是一套独立的面向切面编程的解决方案。它基于ASM字节码编辑技术,在不使用Spring的时候也可单独使用,需要导入对应的aspect相应的jar包,然后编写静态增强逻辑之后,
    • 编译时织入:利用ajc编译器替代javac编译器,直接将源文件(java或者aspect文件)编译成class文件并将切面织入进代码。
    • 编译后织入:利用ajc编译器向javac编译期编译后的class文件或jar文件织入切面代码。
    • 加载时织入(LTW):不使用ajc编译器,利用aspectjweaver.jar工具,使用java agent代理在类加载期将切面织入进代码。这和之前的二进制编织完全一样,所不同的是织入会被延后,直到类加载器将类加载到JVM。

Spring AOP 与ApectJ 的目的一致,都是为了统一处理横切业务,但与AspectJ不同的是,Spring AOP并不尝试提供完整的AOP功能(即使它完全可以实现),Spring AOP 更注重的是与Spring IOC容器的结合,并结合该优势来解决横切业务的问题,因此在AOP的功能完善方面,相对来说AspectJ具有更大的优势,同时,Spring注意到AspectJ在AOP的实现方式上依赖于特殊编译器(ajc编译器),因此Spring很机智回避了这点,转向采用动态代理技术的实现原理来构建Spring AOP的内部机制(动态织入),这是与AspectJ(静态织入)最根本的区别。

在AspectJ1.5后,引入@Aspect形式的注解风格的开发,Spring也非常快地跟进了这种方式,因此Spring 2.0后便使用了与AspectJ一样的注解。请注意,Spring 只是使用了与 AspectJ 5 一样的注解,但仍然没有使用 AspectJ 的编译器,底层依是动态代理技术的实现,因此并不依赖于 AspectJ 的编译器,因此无论是使用spring aop还是 aspectj都需要aspectjweaver.jar spring-aop.jar这两个jar包。使用AspectJ 的 动态织入LTW 还 需要额外的jar包 spring-instrument.jar。

在Spring中使用Spring AOP本质还是动态代理:

  • 创建用于拦截的bean
  • 创建Advisor:使用@AspectJ注解定义切面,@Pointcut("execution(* *.xxx(..))")声明切点,@Before@After@Around等注解声明增强逻辑
  • 创建配置文件:在xml配置文件加上<aop:aspectj-autoproxy> 和待拦截的bean、切面bean
  • 测试

在SpringBoot中使用 Spring AOP步骤:https://cloud.tencent.com/developer/article/1690944


目录

  1. <aop:aspectj-autoproxy>标签

    • AopNamespaceHandler的init方法注册AspectJAutoProxyBeanDefinitionParser实现AOP
    • AspectJAutoProxyBeanDefinitionParser解析器的parse方法注册AnnotationAwareAspectJAutoProxyCreator解析器的BeanDefinition实现AOP,并设置target-proxy-class和expose-proxy属性值到BeanDefinition中
  2. AnnotationAwareAspectJAutoProxyCreator解析@AspectJ注解标识的Advisor

    • Spring AOP的时机
    • AbstractAutoProxyCreator核心实现AOP
      • wrapIfNessary方法
      • createProxy方法
    • JdkDynamicAopProxy分析
    • Cglib2AopProxy分析
  3. AspectJ AOP


一、<aop:aspectj-autoproxy>标签

只要是声明的自定义注解,一定在需要一个他的解析器,解析器名称一般为XxxNamespaceHandler,在AopNamespaceHandler可以看到 设置对@AspectJ注解的解析器AspectJAutoProxyBeanDefinitionParser
在这里插入图片描述

public class AopNamespaceHandler extends NamespaceHandlerSupport {
    public AopNamespaceHandler() {
    }

    public void init() {
        this.registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
        // 设置对@AspectJ注解的解析器AspectJAutoProxyBeanDefinitionParser
        this.registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
        this.registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
        this.registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
    }
}

在这里插入图片描述

1.注册AspectJAutoProxyBeanDefinitionParser

所有的解析器都是对BeanDefinitionParser接口的统一实现,入口都是parse()方法,然后调用registerAspectJAnnotationAutoProxyCreatorIfNecessary() 注册 AnnotationAwareAspectJAutoProxyCreator 解析器的beanDefinition用于实现AOP

// AspectJAutoProxyBeanDefinitionParser的parse()方法
 @Nullable
    public BeanDefinition parse(Element element, ParserContext parserContext) {
    	// 1. 注册AnnotationAwareAspectJAutoProxyCreator
        AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
        // 2. 对于注解类的子类的处理
        this.extendBeanDefinition(element, parserContext);
        return null;
    }

    private void extendBeanDefinition(Element element, ParserContext parserContext) {
        BeanDefinition beanDef = parserContext.getRegistry().getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
        if (element.hasChildNodes()) {
            this.addIncludePatterns(element, parserContext, beanDef);
        }

    }

2. 注册AnnotationAwareAspectJAutoProxyCreator实现AOP

// AopNamespaceUtils
public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(ParserContext parserContext, Element sourceElement) {
		// 1.1. 注册或者升级 AutoProxyCreator定义beanName为
		// org.Springframework.aop.configinternalAutoProxyCreator的BeanDefinition
        BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext.getRegistry(), parserContext.extractSource(sourceElement));
        // 1.2. 对proxy-target-class以及expose-proxy属性的处理
        useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
        // 1.3. 注册组件并通知,便于监听器做进一步处理
        registerComponentIfNecessary(beanDefinition, parserContext);
    }
// 2.1 注册升级AnnotationAwareAspectJAutoProxyCreator
// AopConfigUtils
@Nullable
    public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {
    	// 对beanDefinition进行注册或者升级
        return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
    }
// AopConfigUtils
 @Nullable
    private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        // 容器中已经存在自动代理创建器,需要根据优先级选择一个
        if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
            BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
            if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
                int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
                int requiredPriority = findPriorityForClass(cls);
                if (currentPriority < requiredPriority) {
                    apcDefinition.setBeanClassName(cls.getName());
                }
            }

            return null;
        } else {
        	// 容器中还不存在自动代理创建器,注册对应的beanDefinition
            RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
            beanDefinition.setSource(source);
            beanDefinition.getPropertyValues().add("order", -2147483648);
            beanDefinition.setRole(2);
            registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
            return beanDefinition;
        }
    }
// 2.2. 对proxy-target-class以及expose-proxy属性设置到BeanDefinition

在xml配置文件中对<aop:aspectj-autoproxy proxy-target-class = "true" expose-proxy = "true">或者<aop:config proxy-target-class = "true" expose-proxy = "true"> ... <aop:config> ,此处就是解析并给beanDefinition设置两个属性

  • proxy-target-class:默认Spring AOP使用JDK动态代理,给此属性设置为true表示强制使用Cglib动态代理,需要注意使用Cglib时候不能对final修饰的类代理和需要将Cglib的二进制包放在classpath下面
  • expose-proxy:主要是暴露动态代理上下文AopContext,使用AopContext.currentProxy()获得当前代理,以便解决同类内调用方法不走代理的情况(具体事例就是@Transcation注解使用时的一种情况)
// AopNamespaceUtils
 private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, @Nullable Element sourceElement) {
        if (sourceElement != null) {
            boolean proxyTargetClass = Boolean.parseBoolean(sourceElement.getAttribute("proxy-target-class"));
            if (proxyTargetClass) {
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            }

            boolean exposeProxy = Boolean.parseBoolean(sourceElement.getAttribute("expose-proxy"));
            if (exposeProxy) {
                AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
            }
        }

    }
// AopConfigUtils
public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
        if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
            BeanDefinition definition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
            definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
        }

    }

    public static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
        if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
            BeanDefinition definition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
            definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);
        }

    }

二、AnnotationAwareAspectJAutoProxyCreator解析@AspectJ

1. Spring AOP的时机

// 不存在循环依赖AOP的时机postProcessAfterInitialization()

AnnotationAwareAspectJAutoProxyCreator实现AbstractAutoProxyCreatorlei完成AOP的核心功能。
在这里插入图片描述

他实现BeanProcessor接口,因此无循环依赖的情况下对Bean的具体AOP的逻辑在父类AbstractAutoProxyCreator的postProcessAfterInitalization()方法中

// 存在循环依赖AOP时机getEarlyBeanReference()

首先需要明白解决单例bean循环依赖的关键就是在三级缓存中暴露ObjectFactory

addSingletonFactory(beanName, new ObjectFactory<Object>() {
    @Override
    public Object getObject() throws BeansException {
        return getEarlyBeanReference(beanName, mbd, bean);
    }
});

有循环依赖的情况并且A不需要AOP增强的情况,如A和B互相依赖,并且都是单例的,会使用三级缓存解决循环依赖,大致过程

  1. A在实例化完成之后会进行属性填充,此时会将ObjectFactory放到三级缓存,然后进行populateBean()、initializationBean()、postProcessAfterInitialization()等。

  2. A在populateBean()时发现A依赖B,就会转去B的getBean()…然后就是B的一系列流程…直到B需要populateBean()的时候发现需要A,会从三级缓存中的ObjectFactory实际调用AbstractAutoProxyCreator重写的getEarlyBeanReference()拿到半实例的A,假如A不需要AOP,那么完全没问题在getEarlyBeanReference()直接返回A即可,B此时就会拿到半实例不需要增强的A完成初始化,然后初始化好的B被移动到一级缓存

  3. 然后转回A的populateBean(),在一级缓存中拿到初始化好的B,然后完成后续初始化。

但是有循环依赖并且A需要AOP增强的时候,发挥关键的就是暴露在三级缓存中的getEarlyBeanReference()了。

  1. 主要逻辑在AbstractAutoProxyCreator重写的getEarlyBeanReference(),当B需要从三级缓存中拿到半实例的A时候,这个时候getEarlyBeanReference()就会被调用,会判断A是否需要增强。

  2. 当A需要增强,此时B需要填充A增强的代理对象,那么AOP的时机不能像往常一样放到postProcessAfterInitiallization()中了,而是在这里直接进行AOP返回给B的是A的增强代理实例,然后放到earlyProxyReferences, 标记这个bean已经被early处理过了,避免在postProcessAfterInitiallization()中重复处理

回顾往期博客《Spring源码深度解析 郝佳 第2版》bean的加载、循环依赖的解决,会发现如果B想要从三级缓存拿到代理的A,会调用getEarlyBeanReference()会进入SmartInstantiantionAwareBeanPostProcess的getEarlyBeanReference(),然后返回exposedObject并移动到二级缓存。就是在这里完成的提前AOP。
在这里插入图片描述
而看关键SmartInstantiationAwareBeanPostProcess的getEarlyBeanReference()核心实现

// SmartInstantiationAwareBeanPostProcess是一个接口,默认方法实现
default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
        return bean;
    }
// 查看他的实现类,发现真正的方法在AbstractAutoProxyCreator类重写实现
// AbstractAutoProxyCreator
public Object getEarlyBeanReference(Object bean, String beanName) {
        Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
        this.earlyProxyReferences.put(cacheKey, bean);
        return this.wrapIfNecessary(bean, beanName, cacheKey);
    }

于是有转到和AbstractAutoProxyCreator类

在这里插入图片描述

2. AbstractAutoProxyCreator核心类实现AOP

// 提前AOP的情况



 private final Map<Object, Object> earlyProxyReferences = new ConcurrentHashMap(16);// 主要是循环依赖下的AOP解决
 // aop相关的代理,相当于会把bean替换成一个代理类。那看下循环依赖的时候怎么处理
 // 主要逻辑在AbstractAutoProxyCreator中
// 实现了getEarlyBeanReference,会在这里直接返回一个代理类
// 然后放到earlyProxyReferences, 标记这个bean已经被early处理过了
// 
public Object getEarlyBeanReference(Object bean, String beanName) {
        Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
        this.earlyProxyReferences.put(cacheKey, bean);
        return this.wrapIfNecessary(bean, beanName, cacheKey);
    }

// 正常AOP的情况

 @Nullable
 private BeanFactory beanFactory; // 成员变量



private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap(256); // 记录那些bean需要增强

// AbstractAutoProxyCreator重写了BeanPostProcessor的postProcessAfterInitialization()等方法
 public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        if (bean != null) {
        	// 1. 根据给定的class和beanName构造一个key,格式beanClassName_beanName
            Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
            // 主要处理循环依赖情况下提前AOP和现在和AOP重复
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
            	// 2. 适合被代理,需要封装成指定bean
                return this.wrapIfNecessary(bean, beanName, cacheKey);
            }
        }

        return bean;
    }

// 2. wrapIfNecessary

如果适合被代理,需要封装成指定bean,放到adviserBeans

// AbstractAutoProxyCreator 
//  适合被代理,需要封装成指定bean
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		// 已经处理过了
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
            
        } 
        // 无需增强
        else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        } 
		// 基础设施类和指定的类跳过不增强
		// 需要增强的类
		else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
			
			// 2.1 如果存在增强方法需要创建代理,如@AspectJ注解配置的切面、通知
            Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
            
            if (specificInterceptors != DO_NOT_PROXY) {
                this.advisedBeans.put(cacheKey, Boolean.TRUE);
                // 2.2 增强方法不为空,需要创建代理执行增强方法
                Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
                
                this.proxyTypes.put(cacheKey, proxy.getClass());
                return proxy;
            } else {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return bean;
            }
        } else {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
    }
// 2.1 getAdvicesAndAdvisorsForBean

解析增强方法,如@AspectJ注解配置的切面、通知,然后找到该bean能运用的增强

  • // 找出所有的增强方法放到List
  • // 找出针对该bean的增强方法放到List
// AbstractAutoProxyCreator 
// 模板方法,由子类AbstractAdvisorAutoProxyCreator 重写
 @Nullable
    protected abstract Object[] getAdvicesAndAdvisorsForBean(Class<?> var1, String var2, @Nullable TargetSource var3) throws BeansException;

// AbstractAdvisorAutoProxyCreator 
 @Nullable
    protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
    	// 调用 findEligibleAdvisors
        List<Advisor> advisors = this.findEligibleAdvisors(beanClass, beanName);
        return advisors.isEmpty() ? DO_NOT_PROXY : advisors.toArray();
    }
// AbstractAdvisorAutoProxyCreator的findEligibleAdvisors查找所有增强方法或者增强器
 protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
 
 		// 2.1.1查找所有的增强方法,因为分析的使用注解@AspectJ配置的AOP,
 		// 因此查找方法其实是子类AnnotationAwareAspectJAutoProxyCreator类
 		
        List<Advisor> candidateAdvisors = this.findCandidateAdvisors();
        // 2.1.2针对该bean的增强方法
        List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        
        this.extendAdvisors(eligibleAdvisors);
        if (!eligibleAdvisors.isEmpty()) {
            eligibleAdvisors = this.sortAdvisors(eligibleAdvisors);
        }

        return eligibleAdvisors;
    }
// 2.1.1查找所有的增强方法,因为分析的使用注解@AspectJ配置的AOP, 因此查找方法其实是子类AnnotationAwareAspectJAutoProxyCreator类
// AbstractAdvisorAutoProxyCreator 
protected List<Advisor> findCandidateAdvisors() {
        Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
        return this.advisorRetrievalHelper.findAdvisorBeans();
    }

// AnnotationAwareAspectJAutoProxyCreator
protected List<Advisor> findCandidateAdvisors() {
		// 父类查找
        List<Advisor> advisors = super.findCandidateAdvisors();
        if (this.aspectJAdvisorsBuilder != null) {
        	// 核心实现 BeanFactoryAspectJAdvisorsBuilder
        
            advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
        }

        return advisors;
    }

// 核心实现 BeanFactoryAspectJAdvisorsBuilder.buildAspectJAdvisors()

  1. 获取所有注册在beanFactory的beanName
  2. 遍历所有beanName,找出@AspectJ标注的类,然后 就是最复杂的地方,委托给AspectJAdvisorFactory接口的实现类ReflectiveAspectJAdvisorFactory的getAdvisors方法
  3. 对于切面类增强方法提取
  4. 将提取结果加入缓存
// BeanFactoryAspectJAdvisorsBuilder
public List<Advisor> buildAspectJAdvisors() {
        List<String> aspectNames = this.aspectBeanNames;
        if (aspectNames == null) {
            synchronized(this) {
                aspectNames = this.aspectBeanNames;
                if (aspectNames == null) {
                    List<Advisor> advisors = new ArrayList();
                    List<String> aspectNames = new ArrayList();
                    String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
                    String[] var18 = beanNames;
                    int var19 = beanNames.length;

                    for(int var7 = 0; var7 < var19; ++var7) {
                        String beanName = var18[var7];
                        if (this.isEligibleBean(beanName)) {
                            Class<?> beanType = this.beanFactory.getType(beanName, false);
                            // 对标注@AspectJ的切面解析
                            if (beanType != null && this.advisorFactory.isAspect(beanType)) {
                                aspectNames.add(beanName);
                                AspectMetadata amd = new AspectMetadata(beanType, beanName);
                                if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                                    MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                                    // 最复杂的地方,委托给AspectJAdvisorFactory接口的实现类ReflectiveAspectJAdvisorFactory的getAdvisors方法
                                    List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                                    if (this.beanFactory.isSingleton(beanName)) {
                                    	// 加入缓存
                                        this.advisorsCache.put(beanName, classAdvisors);
                                    } else {
                                        this.aspectFactoryCache.put(beanName, factory);
                                    }

                                    advisors.addAll(classAdvisors);
                                } else {
                                    if (this.beanFactory.isSingleton(beanName)) {
                                        throw new IllegalArgumentException("Bean with name '" + beanName + "' is a singleton, but aspect instantiation model is not singleton");
                                    }

                                    MetadataAwareAspectInstanceFactory factory = new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
                                    this.aspectFactoryCache.put(beanName, factory);
                                    advisors.addAll(this.advisorFactory.getAdvisors(factory));
                                }
                            }
                        }
                    }

                    this.aspectBeanNames = aspectNames;
                    return advisors;
                }
            }
        }

        if (aspectNames.isEmpty()) {
            return Collections.emptyList();
        } else {
            List<Advisor> advisors = new ArrayList();
            Iterator var3 = aspectNames.iterator();

            while(var3.hasNext()) {
                String aspectName = (String)var3.next();
                List<Advisor> cachedAdvisors = (List)this.advisorsCache.get(aspectName);
                if (cachedAdvisors != null) {
                    advisors.addAll(cachedAdvisors);
                } else {
                    MetadataAwareAspectInstanceFactory factory = (MetadataAwareAspectInstanceFactory)this.aspectFactoryCache.get(aspectName);
                    advisors.addAll(this.advisorFactory.getAdvisors(factory));
                }
            }

            return advisors;
        }
    }

// 获取切面的增强方法是最复杂的地方,委托给AspectJAdvisorFactory接口的实现类ReflectiveAspectJAdvisorFactory的getAdvisors方法
在这里插入图片描述

public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
		// 标记为@AspectJ的切面类
        Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
        String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
        this.validate(aspectClass);
        
        MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
        List<Advisor> advisors = new ArrayList();
        // 1.  获取切面每个方法
        Iterator var6 = this.getAdvisorMethods(aspectClass).iterator();

        while(var6.hasNext()) {
            Method method = (Method)var6.next();
            // 2.  对每个方法解析
            Advisor advisor = this.getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
            if (advisor != null) {
                advisors.add(advisor);
            }
        }

        if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
            Advisor instantiationAdvisor = new ReflectiveAspectJAdvisorFactory.SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
            // 3.  配置了增强延迟初始化,需要在在首部加上同步增强实例化加载器
            advisors.add(0, instantiationAdvisor);
        }

        Field[] var12 = aspectClass.getDeclaredFields();
        int var13 = var12.length;

        for(int var14 = 0; var14 < var13; ++var14) {
            Field field = var12[var14];
            Advisor advisor = this.getDeclareParentsAdvisor(field);
            if (advisor != null) {
                advisors.add(advisor);
            }
        }

        return advisors;
    }
// 1. 获取切面每个方法
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
        List<Method> methods = new ArrayList();
        ReflectionUtils.doWithMethods(aspectClass, (method) -> {
            if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
                methods.add(method);
            }

        }, ReflectionUtils.USER_DECLARED_METHODS);
        if (methods.size() > 1) {
            methods.sort(METHOD_COMPARATOR);
        }

        return methods;
    }

// 2. 调用解析每个方法以及增强注解

@Nullable
    public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrderInAspect, String aspectName) {
        this.validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
        // 2.1  解析PointCut切点
        AspectJExpressionPointcut expressionPointcut = this.getPointcut(candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
        // 切点表达式封装为 InstantiationModelAwarePointcutAdvisorImpl
        return expressionPointcut == null ? null : new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
    }

// 2.1 解析PointCut切点表达式,封装到 InstantiationModelAwarePointcutAdvisorImpl
@Nullable
    private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
        AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
        if (aspectJAnnotation == null) {
            return null;
        } else {
            AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class[0]);
            ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
            if (this.beanFactory != null) {
                ajexp.setBeanFactory(this.beanFactory);
            }

            return ajexp;
        }
    }
    // 2.2. 调用解析每个方法以及增强注解
@Nullable
    public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
        Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
        this.validate(candidateAspectClass);
        // 获取方法上的注解
        AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
        if (aspectJAnnotation == null) {
            return null;
        } else if (!this.isAspect(candidateAspectClass)) {
            throw new AopConfigException("Advice must be declared inside an aspect type: Offending method '" + candidateAdviceMethod + "' in class [" + candidateAspectClass.getName() + "]");
        } else {
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Found AspectJ method: " + candidateAdviceMethod);
            }

            Object springAdvice;
            // 根据注解类型解析
            switch(aspectJAnnotation.getAnnotationType()) {
            // Pointcut切点不解析
            case AtPointcut:
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
                }

                return null;
            case AtAround:
                springAdvice = new AspectJAroundAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
                break;
            case AtBefore:
                springAdvice = new AspectJMethodBeforeAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
                break;
            case AtAfter:
                springAdvice = new AspectJAfterAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
                break;
            case AtAfterReturning:
                springAdvice = new AspectJAfterReturningAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
                AfterReturning afterReturningAnnotation = (AfterReturning)aspectJAnnotation.getAnnotation();
                if (StringUtils.hasText(afterReturningAnnotation.returning())) {
                    ((AbstractAspectJAdvice)springAdvice).setReturningName(afterReturningAnnotation.returning());
                }
                break;
            case AtAfterThrowing:
                springAdvice = new AspectJAfterThrowingAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
                AfterThrowing afterThrowingAnnotation = (AfterThrowing)aspectJAnnotation.getAnnotation();
                if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
                    ((AbstractAspectJAdvice)springAdvice).setThrowingName(afterThrowingAnnotation.throwing());
                }
                break;
            default:
                throw new UnsupportedOperationException("Unsupported advice type on method: " + candidateAdviceMethod);
            }

            ((AbstractAspectJAdvice)springAdvice).setAspectName(aspectName);
            ((AbstractAspectJAdvice)springAdvice).setDeclarationOrder(declarationOrder);
            String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
            if (argNames != null) {
                ((AbstractAspectJAdvice)springAdvice).setArgumentNamesFromStringArray(argNames);
            }

            ((AbstractAspectJAdvice)springAdvice).calculateArgumentBindings();
            return (Advice)springAdvice;
        }
    }

可以看出Spring会对不同注解的方法生成不同的增强器如AspectJAroundAdvice、AspectJAfterReturningAdvice等

在这里插入图片描述

在这里插入图片描述

以@Before注解为例
  • 在拦截链中放置MethodBeforeAdviceInterceptor ,MethodBeforeAdviceInterceptor 完成了增强逻辑
  • 在MethodBeforeAdviceInterceptor 放置AspectJMethodBeforeAdvice
  • 在调用invoke方法的时候串联调用,// 调用AspectJMethodBeforeAdvice的前置增强方法然后才是 // 方法执行
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {
    private final MethodBeforeAdvice advice;

    public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
        Assert.notNull(advice, "Advice must not be null");
        this.advice = advice;
    }
	// @Before注解增强逻辑
    public Object invoke(MethodInvocation mi) throws Throwable {
    	// 调用AspectJMethodBeforeAdvice的方法前置增强
        this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
        // 方法执行
        return mi.proceed();
    }
}



// AspectJMethodBeforeAdvice
 public void before(Method method, Object[] args, @Nullable Object target) throws Throwable {
 		// 激活增强方法
        this.invokeAdviceMethod(this.getJoinPointMatch(), (Object)null, (Throwable)null);
    }
// AbstractAspectJAdvice
protected Object invokeAdviceMethod(@Nullable JoinPointMatch jpMatch, @Nullable Object returnValue, @Nullable Throwable ex) throws Throwable {
		// 重载
        return this.invokeAdviceMethodWithGivenArgs(this.argBinding(this.getJoinPoint(), jpMatch, returnValue, ex));
    }
// AbstractAspectJAdvice

protected transient Method aspectJAdviceMethod; // 正是对前置增强的方法

protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
        Object[] actualArgs = args;
        if (this.aspectJAdviceMethod.getParameterCount() == 0) {
            actualArgs = null;
        }

        try {
            ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
            // 真正激活,调用的Method的invoke
            return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);
        } catch (IllegalArgumentException var4) {
            throw new AopInvocationException("Mismatch on arguments to advice method [" + this.aspectJAdviceMethod + "]; pointcut expression [" + this.pointcut.getPointcutExpression() + "]", var4);
        } catch (InvocationTargetException var5) {
            throw var5.getTargetException();
        }
    }
以@After注解为例

和前置不同,直接在拦截器链中使用了中间的AspectJAfterAdvice

public class AspectJAfterAdvice extends AbstractAspectJAdvice implements MethodInterceptor, AfterAdvice, Serializable {
    public AspectJAfterAdvice(Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
        super(aspectJBeforeAdviceMethod, pointcut, aif);
    }

    public Object invoke(MethodInvocation mi) throws Throwable {
        Object var2;
        try {
            var2 = mi.proceed();
        } finally {
        	// 激活增强方法
            this.invokeAdviceMethod(this.getJoinPointMatch(), (Object)null, (Throwable)null);
        }

        return var2;
    }

    public boolean isBeforeAdvice() {
        return false;
    }

    public boolean isAfterAdvice() {
        return true;
    }
}

// 2.1.2 findAdvisorsThatCanApply

之前找到所有的增强之后封装为XxxAdvice,然后就是遍历找出该bean能运用的放到List集合

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

        List var4;
        try {
        	// 委托
            var4 = AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
        } finally {
            ProxyCreationContext.setCurrentProxiedBeanName((String)null);
        }

        return var4;
    }
 
 // AopUtils
 public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
        if (candidateAdvisors.isEmpty()) {
            return candidateAdvisors;
        } else {
            List<Advisor> eligibleAdvisors = new ArrayList();
            Iterator var3 = candidateAdvisors.iterator();

            while(var3.hasNext()) {
                Advisor candidate = (Advisor)var3.next();
                // 引介增强
                if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
                    eligibleAdvisors.add(candidate);
                }
            }

            boolean hasIntroductions = !eligibleAdvisors.isEmpty();
            Iterator var7 = candidateAdvisors.iterator();

            while(var7.hasNext()) {
                Advisor candidate = (Advisor)var7.next();
                // 普通bean的增强
                if (!(candidate instanceof IntroductionAdvisor) && canApply(candidate, clazz, hasIntroductions)) {
                    eligibleAdvisors.add(candidate);
                }
            }

            return eligibleAdvisors;
        }
    }
// canApply
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
        if (advisor instanceof IntroductionAdvisor) {
            return ((IntroductionAdvisor)advisor).getClassFilter().matches(targetClass);
        } else if (advisor instanceof PointcutAdvisor) {
            PointcutAdvisor pca = (PointcutAdvisor)advisor;
            return canApply(pca.getPointcut(), targetClass, hasIntroductions);
        } else {
            return true;
        }
    }
// 2.2 createProxy创建代理

如果可以运用的增强方法不为空,需要为该bean创建代理执行增强方法,

// 2.2.1 设置beanDefinition原来的属性

// 2.2.2 实例化proxyFactory ,内部封装了getProxy等方法,需要根据下面的配置进去的属性获取代理对象

// 2.2.3 获取当前bean的属性

// 2.2.4 设置属性,根据我们配置的proxy-target-class属性,选用JDK还是Cglib动态代理时需要用到保存在ProxyFactory中的该属性

// 2.2.5 加入能用的增强器,复杂

// 2.2.6 设置被代理类

// 2.2.7 定制代理

// 2.2.8 委托ProxyFactory获取代理对象,复杂

// AbstractAutoProxyCreator 
 protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) {
 		// 2.2.1 设置beanDefinition原来的属性
        if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
        
            AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory)this.beanFactory, beanName, beanClass);
        }
		// 2.2.2 实例化proxyFactory 封装了getProxy等方法,需要根据下面的配置进去的属性获取代理对象
        ProxyFactory proxyFactory = new ProxyFactory();
        // 2.2.3 获取当前bean的属性
        proxyFactory.copyFrom(this);
        // 2.2.4 设置属性,根据我们配置的proxy-target-class属性
        if (!proxyFactory.isProxyTargetClass()) {
            if (this.shouldProxyTargetClass(beanClass, beanName)) {
            	// Cglib动态代理
                proxyFactory.setProxyTargetClass(true);
            } else {
            	// JDK动态代理
                this.evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }
		// 2.2.5 加入能用的增强器
        Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
        proxyFactory.addAdvisors(advisors);
        // 2.2.6 设置被代理类
        proxyFactory.setTargetSource(targetSource);
        // 2.2.7 定制代理
        this.customizeProxyFactory(proxyFactory);
        proxyFactory.setFrozen(this.freezeProxy);
        if (this.advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }
		// 2.2.8 委托ProxyFactory获取代理对象
        return proxyFactory.getProxy(this.getProxyClassLoader());
    }
// 2.2.5 buildAdvisors封装能用的增强器

因为Spring涉及了过多的拦截器、增强器、增强方法等方式对逻辑进行增强,所以非常有必要封装成为Advisor来进行代理的创建

简单来说:Advice 是通知,Advisor 是增强器。使用 spring aop 要定义切面,切面里面有 通知 和 切点。

在项目启动的过程中,项目中的所有切面会被 AnnotationAwareAspectJAutoProxyCreator 解析,它会找到切面中的每一个通知以及通知对应的切点,拿这二者构建一个新的对象,这个对象就是 Advisor。最后将所有解析得到的增强器注入到容器中。

protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
        Advisor[] commonInterceptors = this.resolveInterceptorNames();
        List<Object> allInterceptors = new ArrayList();
        if (specificInterceptors != null) {
            allInterceptors.addAll(Arrays.asList(specificInterceptors));
            if (commonInterceptors.length > 0) {
                if (this.applyCommonInterceptorsFirst) {
                    allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
                } else {
                    allInterceptors.addAll(Arrays.asList(commonInterceptors));
                }
            }
        }

        int i;
        if (this.logger.isTraceEnabled()) {
            int nrOfCommonInterceptors = commonInterceptors.length;
            i = specificInterceptors != null ? specificInterceptors.length : 0;
            this.logger.trace("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors + " common interceptors and " + i + " specific interceptors");
        }

        Advisor[] advisors = new Advisor[allInterceptors.size()];

        for(i = 0; i < allInterceptors.size(); ++i) {
        	// 封装
            advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
        }

        return advisors;
    }
//DefaultAdvisorAdapterRegistry

public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
        if (adviceObject instanceof Advisor) {
            return (Advisor)adviceObject;
        } else if (!(adviceObject instanceof Advice)) {
            throw new UnknownAdviceTypeException(adviceObject);
        } else {
            Advice advice = (Advice)adviceObject;
            if (advice instanceof MethodInterceptor) {
            	// MethodInterceptor 类型使用 DefaultPointcutAdvisor封装
                return new DefaultPointcutAdvisor(advice);
            } else {
                Iterator var3 = this.adapters.iterator();

                AdvisorAdapter adapter;
                // 存在 AdvisorAdapter 也需要封装 DefaultPointcutAdvisor
                do {
                    if (!var3.hasNext()) {
                        throw new UnknownAdviceTypeException(advice);
                    }

                    adapter = (AdvisorAdapter)var3.next();
                } while(!adapter.supportsAdvice(advice));

                return new DefaultPointcutAdvisor(advice);
            }
        }
    }
// 2.2.8 委托ProxyFactory获取代理对象
// ProxyFactory
public Object getProxy(@Nullable ClassLoader classLoader) {
        return this.createAopProxy().getProxy(classLoader);
    }
// ProxyCreatorSupport
 protected final synchronized AopProxy createAopProxy() {
        if (!this.active) {
            this.activate();
        }
		// 委托AopProxyFactory接口的createProxy()
        return this.getAopProxyFactory().createAopProxy(this);
    }
// DefaultAopProxyFactory 实现AopProxyFactory
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
            return new JdkDynamicAopProxy(config);
        } else {
            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.");
            } else {
            	// 选用Cglib还是JDK动态代理
                return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
            }
        }
    }

在分析JDK动态代理和Cglib动态代理之前,先看看如何使用

  1. 使用JDK动态代理:需要被代理类实现某个接口
    • 创建处理器MyInvocationHandler实现InvocationHandler接口,重写invoke、getProxy()方法(也可以放到外面直接Proxy.newProxyInstance()获得代理对象),然后构造方法传入被代理对象
    • 创建被代理对象实例,传入MyInvocationHandler实例
    • 通过MyInvocationHandler.getProxy()获得代理对象proxy
    • 测试 proxy.test()
  2. 使用Cglib动态代理:要求被代理类不能被final修饰
    • 创建处理器MyMethodInterceptor实现MethodInterceptor,重写intercepter()方法
    • 测试,创建Enhancer实例
      • 调用setSuperClass()设置被代理类Class,
      • 调用setCallback()传入MyMethodInterceptor实例,
      • 调用create()方法创建代理对象,然后调用方法test()
// JdkDynamicAopProxy处理器分析

可以看到// final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable 它也实现 InvocationHandler

关键点就是invoke、getProxy方法

  public Object getProxy() {
        return this.getProxy(ClassUtils.getDefaultClassLoader());
    }

    public Object getProxy(@Nullable ClassLoader classLoader) {
        if (logger.isTraceEnabled()) {
            logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
        }

        Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
        this.findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
        return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
    }

invoke方法主要是创建了一个拦截器链,然后使用ReflectiveMethodInvocation封装,在他的proceed()方法实现拦截器的逐一调用
在这里插入图片描述

 @Nullable
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object oldProxy = null;
        boolean setProxyContext = false;
        TargetSource targetSource = this.advised.targetSource;
        Object target = null;

        Object retVal;
        try {
            if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
                Boolean var18 = this.equals(args[0]);
                return var18;
            }

            if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
                Integer var17 = this.hashCode();
                return var17;
            }

            if (method.getDeclaringClass() == DecoratingProxy.class) {
                Class var16 = AopProxyUtils.ultimateTargetClass(this.advised);
                return var16;
            }

            if (this.advised.opaque || !method.getDeclaringClass().isInterface() || !method.getDeclaringClass().isAssignableFrom(Advised.class)) {
            // 自身类.class.isAssignableFrom(自身类或者子类.class) 返回true,其他情况返回false
                if (this.advised.exposeProxy) {
                    oldProxy = AopContext.setCurrentProxy(proxy);
                    setProxyContext = true;
                }

                target = targetSource.getTarget();
                Class<?> targetClass = target != null ? target.getClass() : null;
                // 拦截器链
                List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
                if (chain.isEmpty()) {
                	// 没有发现拦截器链,直接调用切点方法
                    Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                    retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
                } else {
                    MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
                    // 剩下的拦截器链执行
                    retVal = invocation.proceed();
                }

                Class<?> returnType = method.getReturnType();
                if (retVal != null && retVal == target && returnType != Object.class && returnType.isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
                    retVal = proxy;
                } else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
                    throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method);
                }

                Object var12 = retVal;
                return var12;
            }

            retVal = AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
        } finally {
            if (target != null && !targetSource.isStatic()) {
                targetSource.releaseTarget(target);
            }

            if (setProxyContext) {
                AopContext.setCurrentProxy(oldProxy);
            }

        }

        return retVal;
    }

// ReflectiveMethodInvocation
 @Nullable
    public Object proceed() throws Throwable {
        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
        	// 切点
            return this.invokeJoinpoint();
        } else {
        	// 拦截器链
            Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
            if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
                InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
                Class<?> targetClass = this.targetClass != null ? this.targetClass : this.method.getDeclaringClass();
                return dm.methodMatcher.matches(this.method, targetClass, this.arguments) ? dm.interceptor.invoke(this) : this.proceed();
            } else {
                return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
            }
        }
    }
// Cglib2AopProxy处理器分析

首先需要导入依赖

<dependency>
	<groupId>springframework</groupId>
	<artifactId>spring-aop</artifactId>
	<version>1.2.5</version>
</dependency>

getProxy方法

public Object getProxy() {
        return this.getProxy((ClassLoader)null);
    }

    public Object getProxy(ClassLoader classLoader) {
        if (logger.isDebugEnabled()) {
            Class targetClass = this.advised.getTargetSource().getTargetClass();
            logger.debug("Creating CGLIB2 proxy" + (targetClass != null ? " for [" + targetClass.getName() + "]" : ""));
        }

        Enhancer enhancer = new Enhancer();

        try {
            Class rootClass = this.advised.getTargetSource().getTargetClass();
            Class proxySuperClass = AopUtils.isCglibProxyClass(rootClass) ? rootClass.getSuperclass() : rootClass;
            this.validateClassIfNecessary(proxySuperClass);
            enhancer.setSuperclass(proxySuperClass);
            enhancer.setCallbackFilter(new Cglib2AopProxy.ProxyCallbackFilter(this.advised));
            enhancer.setStrategy(new UndeclaredThrowableStrategy(class$java$lang$reflect$UndeclaredThrowableException == null ? (class$java$lang$reflect$UndeclaredThrowableException = class$("java.lang.reflect.UndeclaredThrowableException")) : class$java$lang$reflect$UndeclaredThrowableException));
            enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
            Callback[] callbacks = this.getCallbacks(rootClass);
            enhancer.setCallbacks(callbacks);
            if (Cglib2AopProxy.CglibUtils.canSkipConstructorInterception()) {
                enhancer.setInterceptDuringConstruction(false);
            }

            Class[] types = new Class[callbacks.length];

            for(int x = 0; x < types.length; ++x) {
                types[x] = callbacks[x].getClass();
            }

            enhancer.setCallbackTypes(types);
            Object proxy;
            if (this.constructorArgs != null) {
                proxy = enhancer.create(this.constructorArgTypes, this.constructorArgs);
            } else {
                proxy = enhancer.create();
            }

            return proxy;
        } catch (CodeGenerationException var8) {
            throw new AspectException("Couldn't generate CGLIB subclass of class '" + this.advised.getTargetSource().getTargetClass() + "': " + "Common causes of this problem include using a final class or a non-visible class", var8);
        } catch (IllegalArgumentException var9) {
            throw new AspectException("Couldn't generate CGLIB subclass of class '" + this.advised.getTargetSource().getTargetClass() + "': " + "Common causes of this problem include using a final class or a non-visible class", var9);
        } catch (Exception var10) {
            throw new AspectException("Unexpected AOP exception", var10);
        }
    }

intercepter方法

private class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
        private DynamicAdvisedInterceptor() {
        }

        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            MethodInvocation invocation = null;
            Object oldProxy = null;
            boolean setProxyContext = false;
            Class targetClass = null;
            Object target = null;

            Object var12;
            try {
                Object retVal = null;
                if (Cglib2AopProxy.this.advised.exposeProxy) {
                    oldProxy = AopContext.setCurrentProxy(proxy);
                    setProxyContext = true;
                }

                target = this.getTarget();
                if (target != null) {
                    targetClass = target.getClass();
                }

                List chain = Cglib2AopProxy.this.advised.getAdvisorChainFactory().getInterceptorsAndDynamicInterceptionAdvice(Cglib2AopProxy.this.advised, proxy, method, targetClass);
                if (chain.isEmpty()) {
                    retVal = methodProxy.invoke(target, args);
                } else {
                    invocation = new Cglib2AopProxy.CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy);
                    retVal = invocation.proceed();
                }

                retVal = Cglib2AopProxy.massageReturnTypeIfNecessary(proxy, target, retVal);
                var12 = retVal;
            } finally {
                if (target != null) {
                    this.releaseTarget(target);
                }

                if (setProxyContext) {
                    AopContext.setCurrentProxy(oldProxy);
                }

            }

            return var12;
        }

        public int hashCode() {
            return Cglib2AopProxy.this.advised.hashCode();
        }

        protected Object getTarget() throws Exception {
            return Cglib2AopProxy.this.advised.getTargetSource().getTarget();
        }

        protected void releaseTarget(Object target) throws Exception {
            Cglib2AopProxy.this.advised.getTargetSource().releaseTarget(target);
        }
    }

三、AspectJ动态织入

AspectJ 的底层技术是 静态代理 ,主要是在虚拟机启动的时候通过改变目标对象字节码的方式来完成对目标对象的增强,它比动态代理有更高的效率,因为在动态代理调用过程中,还需要一个动态创建代理类并代理目标对象的步骤,而静态代理是在启动时完成了字节码增强,当系统调用目标类和正常的类无差别,所以效率上会相对高一些。

Aspect是实现AOP编程的一种具体实现

  • 编译时织入,利用ajc编译器替代javac编译器,直接将源文件(java或者aspect文件)编译成class文件并将切面织入进代码。
  • 编译后织入,利用ajc编译器向javac编译期编译后的class文件或jar文件织入切面代码。
  • 加载时织入(LTW),不使用ajc编译器,利用aspectjweaver.jar工具,使用java agent代理在类加载期将切面织入进代码。

前两种织入方法都依赖于ajc的编译工具,LTW却通过java agent机制在内存中操作类文件,可以不需要ajc的支持做到 动态织入

不过,这里有一个挺有意思的问题,我们知道编译期一定会编译AnnoAspect类,那么这时候通过切面语法我们就可以找到他要处理的App类,这大概就是编译阶段织入的大概流程。

但是如果在类加载期处理的话,当类加载到App类的时候,我们并不知道这个类需要被AnnoAspect处理。。。因此为了实现LTW,我们肯定要有个配置文件,来告诉类加载器,某某某切面需要优先考虑,他们很可能会影响其他的类。为了实现LTW,我们需要在资源目录下配置META-INF/aop.xml文件,来告知类加载器我们当前注册的切面。

比如说Load-Time Weaving的方式 还 需要额外的jar包 spring-instrument.jar。
当然,无论是使用spring aop还是 aspectj都需要aspectjweaver.jar spring-aop.jar这两个jar包。

?

参考:https://blog.csdn.net/whatigame/article/details/103173308

使用步骤

  • 在xml配置文件中加上<aop:aspect-autoproxy><context:load-time-weaver>开启Load-Time Weaving开关
  • 在class路径下新建META-INF文件夹,文件夹创建aop.xml文件,里面配置<aspect>、 <weaver>、<aspects>主要是告诉AspectJ哪些包进行织入,并使用哪些增强器
  • 加入启动参数,也就是应用指定的jar包
  • 测试
  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-04-01 00:25:36  更:2022-04-01 00:27:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:19:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码