Spring源码解析系列(7)之AOP的底层原理

Spring AOP的底层原理

前置知识:spring 使用aspectJ实现了aop,听起来好像spring的aop完全是依赖于aspectJ,其实spring对于aop的实现是通过动态代理(jdk的动态代理或者cglib的动态代理),它只是使用了aspectJ的Annotation,并没有使用它的编译器和织入器,进行注解的解析工作是Spring内部实现的,所以Spring AOP只是借助了AspectJ的注解而已。

spring AOP提供两种编程风格

@AspectJ support ------------>利用aspectj的注解

Schema-based AOP support ----------->xml aop:config 命名空间

开始源码剖析:

首先,要开启aop需要使用@EnableAspectJAutoProxy注解

@EnableAspectJAutoProxy

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
// 使用@import将想要注册的类注册到容器中,没有标注@Component的普通类也能被注入进来
// 导入注册器,实际上是通过调用该注册器的方法,注册beanDefinition
@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
    boolean proxyTargetClass() default false;
​
    boolean exposeProxy() default false;
}

AspectJAutoProxyRegistrar

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
    AspectJAutoProxyRegistrar() {
    }
​
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
 // 注册AnnotationAwareAspectJAutoProxyCreator的beanDefinition ,主要方法     
        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
        //2.获取原注解也就是EnableAspectJAutoProxy上面设置的属性值
        AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
        if (enableAspectJAutoProxy != null) {
            //3.设置proxyTargetClass属性
            if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            }
    //4.设置exposeProxy属性
            if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
                AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
            }
        }
​
    }
}

第1步注册一个AnnotationAwareAspectJAutoProxyCreator的BeanDefinition,此步骤很关键,具体看代码块3中的registerAspectJAnnotationAutoProxyCreatorIfNecessary的源码,第2、3、4步就是向AnnotationAwareAspectJAutoProxyCreator的BeanDefinition设置属性的步骤,看一下第3步和第四步设置proxyTargetClass属性和设置exposeProxy属性

registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry)

@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
    return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, (Object)null);
}

registerAspectJAnnotationAutoProxyCreatorIfNecessary()

@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {
    return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}

registerOrEscalateApcAsRequired()

@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    // 判断beanDefinitionMap中是否已经包含了名称为"org.springframework.aop.config.internalAutoProxyCreator"的beanDefinition
    if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
        // 如果包含了就从容器中获取
        BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
        //5.如果名称不一样,则获取优先级,在这里我们知道cls传过来的是AnnotationAwareAspectJAutoProxyCreator这个类,
            //而这个AnnotationAwareAspectJAutoProxyCreator的优先级是最高的,如果名称不一样,则BeanClassName则会被替换成
            //AnnotationAwareAspectJAutoProxyCreator.class的名称
        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 {
        // beanDefinitionMap中没有包含名称为"org.springframework.aop.config.internalAutoProxyCreator"的beanDefinition就进行创建
        RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
        beanDefinition.setSource(source);
        beanDefinition.getPropertyValues().add("order", -2147483648);
        beanDefinition.setRole(2);
      // 向容器中注入该beanDefinition
        registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
        // 返回创建好的beanDefinition
        return beanDefinition;
    }
}

forceAutoProxyCreatorToUseClassProxying(registry)

forceAutoProxyCreatorToExposeProxy(registry)

public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
    
    //1.如果容器中包含AUTO_PROXY_CREATOR_BEAN_NAME的BeanDefinition,则设置proxyTargetClass属性为true,
    //该属性在创建动态代理的时候,会影响使用JDK还是CGLIB来实现动态代理
    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类的继承关系图

到此就完成了向Spring容器中注入了一个封装了AnnotationAwareAspectJAutoProxyCreator的BeanDefinition对象,我们可以看到AnnotationAwareAspectJAutoProxyCreator间接的实现了InstantiationAwareBeanPostProcessor接口和BeanPostProcessor接口,也就是说在bean的生命周期中AnnotationAwareAspectJAutoProxyCreator也会参与进来,依据前面分析过的,InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法作为第一个被执行的后置处理器方法,postProcessAfterInstantiation()是第五个被执行的后置处理器方法;BeanPostProcessor接口postProcessBeforeInitialization方法和postProcessAfterInitialization方法是第七、八个被执行的后置处理器方法,AnnotationAwareAspectJAutoProxyCreator中只有上述postProcessBeforeInstantiation和postProcessAfterInitialization方法的具体实现。


在bean被实例化之前,调用InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法(实际上是调用父类AbstractAutoProxyCreator的重写方法)。我们来看:

AnnotationAwareAspectJAutoProxyCreator#postProcessBeforeInstantiation

判断要不要在此处直接生成代理对象,并返回,不进行bean的整个创建过程,直接将返回的对象,放入单例池。一般情况下,如果我们没有自己配置TargetSourceCreator,则一定会返回null。不会进入,就不详细分析了。

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
    Object cacheKey = this.getCacheKey(beanClass, beanName);
    if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
        if (this.advisedBeans.containsKey(cacheKey)) {
            return null;
        }
​
        if (this.isInfrastructureClass(beanClass) || this.shouldSkip(beanClass, beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return null;
        }
    }
​
    TargetSource targetSource = this.getCustomTargetSource(beanClass, beanName);
    if (targetSource != null) {
        if (StringUtils.hasLength(beanName)) {
            this.targetSourcedBeans.add(beanName);
        }
​
        Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
        Object proxy = this.createProxy(beanClass, beanName, specificInterceptors, targetSource);
        this.proxyTypes.put(cacheKey, proxy.getClass());
        return proxy;
    } else {
        return null;
    }
}

真正代理方法的执行是在initializeBean方法中进行的,当bean经历了实例化,属性填充之后,就会来到初始化的步骤,在这里面,会调用BeanPostProcessor后置处理器的postProcessBeforeInitializationpostProcessAfterInitialization方法,代理方法的执行也是在postProcessAfterInitialization进行的。

    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
        //1.已存在bean,这个bean是没有代理之前的bean
        Object result = existingBean;
​
        Object current;
        //2.拿到所有的bena的后置处理器,依次进行遍历
        for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) {
            //3.执行其postProcessAfterInitialization方法
            BeanPostProcessor processor = (BeanPostProcessor)var4.next();
            current = processor.postProcessBeforeInitialization(result, beanName);
            //4.如果有其中一个返回空,则就直接返回了,不再进行遍历
            if (current == null) {
                return result;
            }
        }
​
        return result;
    }

第3步执行后置处理器的postProcessAfterInitialization方法,并将返回的current 对象赋值给result,也就是会替换原来的bean对象。而对于bean后置处理器的postProcessAfterInitialization方法,如果不做处理的话,都是直接将传递过来的bean给直接返回,而不进行任何处理。 AnnotationAwareAspectJAutoProxyCreator也是一个bean后置处理器,而AnnotationAwareAspectJAutoProxyCreator间接的继承AbstractAutoProxyCreator类,在AbstractAutoProxyCreator类中实现了postProcessAfterInitialization方法

AbstractAutoProxyCreator#postProcessAfterInitialization方法

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    if (bean != null) {
        //1.获取缓存键,如果beanName没有长度,则直接返回bean的class,如果不为空,
        //会判断当前bean是否为FactoryBean的子类,如果是,则在其bean名称前面添加&, 如果不是则直接返回bean的名称,
        Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
        // 从earlyProxyReferences中移出缓存key,我们看一下哪里用到了缓存key↓,==判断是否已经代理过了==,代理过了就直接返回原来的bean,如果代理过了,会在再次调用getSingleton()时,从二级缓存中获得
        if (this.earlyProxyReferences.remove(cacheKey) != bean) {
            return this.wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
​
    return bean;
}
​
    protected Object getCacheKey(Class<?> beanClass, @Nullable String beanName) {
        // 判断beanName是不是空字符串,有长度,如果有就判断是不是工厂bean,如果是工厂bean,就返回&beanName,否则返回原来的beanName
        if (StringUtils.hasLength(beanName)) {
            return FactoryBean.class.isAssignableFrom(beanClass) ? "&" + beanName : beanName;
        } else {
            return beanClass;
        }
    }
private final Map<Object, Object> earlyProxyReferences = new ConcurrentHashMap(16);
// 此方法前面分析过,会在出现循环依赖时,从三级缓存中获取暴露对象的时候调用,也就是说earlyProxyReferences里面保存的是以beanName为key,对应的bean为value的“被代理对象”,我们可以看出它的主要作用就是保存“被代理对象的”,因为前面我们在分析工厂bean的时候也分析到了,也会对工厂bean中getObject()返回的对象进行代理,那么在earlyProxyReferences里工厂bean是以&beanName,bean存在的,而他所包裹的对象是以beanName,bean的形式存在的
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);
}

wrapIfNecessary()看一下具体进行代理增强的代码

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)) {
        // 1.获取能够使用的排序后的通知数组
        Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
        // 2.如果数组不为null,表明需要进行代理,进入if判断
        if (specificInterceptors != DO_NOT_PROXY) {
       // 3.向已经完成通知的bean的map中添加缓存键和是否需要进行增强的标志,标志为true,表明需要进行增强,(此时还未进行增强,即将要增强了...)
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
        // 4.创建代理对象
            Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        } else {
            // 6.在这可以看到即使不需要增强,只要经过了是否需要增强的判断,就会被添加到Map集合中,只不过标志为false
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
    } else {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }
}
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
    // 1.1查找所有符合条件的并且经过排序的通知列表
    List<Advisor> advisors = this.findEligibleAdvisors(beanClass, beanName);
    // 1.2如果不为空,就将通知列表转为数组后返回,如果为空不进行代理返回null
    return advisors.isEmpty() ? DO_NOT_PROXY : advisors.toArray();
}
​
    // 寻找符合条件的通知对象列表
    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
          // 1.先看下面:有下面的分析可知,此处就是生成全部Advisor的地方了,在这就能拿到不论是注解定义还是实现Advisor接口的全部封装好的Advisor增强器,其内部主要封装了pointcut(要被增强的方法)以及advise(实际去增强的内容)
        List<Advisor> candidateAdvisors = this.findCandidateAdvisors();
        // 2.选择该bean能够使用的增强器列表,也就是切点所在的类是当前bean对应的类的,[此处事务的Advisor中的pointcut回去进行匹配判断,会利用AnnotationTransactionAttributeSource去检查类上是否有@Transactional注解,检查方法上是否有@Transactional注解,有就将其添加到可用的Advisor列表中]
        List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        this.extendAdvisors(eligibleAdvisors);
        if (!eligibleAdvisors.isEmpty()) {
            // 如果可用的通知不为空就对其进行排序,排序会按照下面的规则进行排序
            /**
            -1 ExposeInvocationInterceptor#invoke
            0 事务advisor
            1.环绕增强前(around advice before)
            2.前置增强(before advice)
            3.-- 方法执行
            4.环绕增强后(around advice after)
            5.后置finally增强(after advice)
            6.后置增强/抛出增强            
            **/
            eligibleAdvisors = this.sortAdvisors(eligibleAdvisors);
        }
    // 返回排序后的可用的通知列表
        return eligibleAdvisors;
    }

看一下候选通知列表:

看一下筛选前后的:

看一下排序之后的:

看一下advisedBeans里面的内容:

findCandidateAdvisors()

protected List<Advisor> findCandidateAdvisors() {
    // 此步为止如果没有自定义实现Advisor接口的类,并且没有开启事务,如果开启了事务,会自动注册一个事务相关的advisor,只是通过注解进行了配置@Aspect,那就会advisors返回null
    List<Advisor> advisors = super.findCandidateAdvisors();
    if (this.aspectJAdvisorsBuilder != null) {
        // 此步是主要的去构建Advisor的步骤
        // 将搜索到的全部的带有Aspect注解的类中的带有@Before。@After等注解的方法,以及其切入点(要增强的方法)都封装成了Advisor,与之前搜索到了通过实现Advisor接口的形式定义的Advisor整合,获取到全部的Advisor增强器。====================重点=============================
        advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
    }
​
    return advisors;
​
}

buildAspectJAdvisors()

public List<Advisor> buildAspectJAdvisors() {
    // 此处获取advisor类型的beanName
    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();
                // 此处就是去获取全部被注册的beanName
                String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
                String[] var18 = beanNames;
                int var19 = beanNames.length;
            // 遍历每一个beanName
                for(int var7 = 0; var7 < var19; ++var7) {
                    String beanName = var18[var7];
                    // 默认返回true
                    if (this.isEligibleBean(beanName)) {
                        Class<?> beanType = this.beanFactory.getType(beanName, false);
                    // 判断当前类型是不是Aspect类型,就是判断是否存在Aspect注解,不存在就继续遍历下一个
                        /**
                            public boolean isAspect(Class<?> clazz) {
              return this.hasAspectAnnotation(clazz) && !this.compiledByAjc(clazz);
                             }
                        **/
                        if (beanType != null && this.advisorFactory.isAspect(beanType)) {
                            // 找到了,就添加带有Aspect注解的beanName到aspectNames中
                            aspectNames.add(beanName);
                            // 将其封装为aspectMetadata
                            AspectMetadata amd = new AspectMetadata(beanType, beanName);
                            if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                                MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                           // 解析beanName对应的类中的方法,将通知(标有注解的before、after....)和相对应的切点都封装成Advisor返回,如下图,看一下结构
                                List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                                if (this.beanFactory.isSingleton(beanName)) {
                               // 是单例bean将其,以及它对应的Advisor放入缓存中
                                    this.advisorsCache.put(beanName, classAdvisors);
                                } else {
                                    this.aspectFactoryCache.put(beanName, factory);
                                }
                        // 将其全部添加到Aspect列表中并返回
                                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;
    }
​
}

beanNamesForTypeIncludingAncestors

public static String[] beanNamesForTypeIncludingAncestors(ListableBeanFactory lbf, Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
    Assert.notNull(lbf, "ListableBeanFactory must not be null");
    // 可以看到此处传入的type是Object.class,所以result此时拿到的是全部被注册了的beanName
    String[] result = lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
    // 我们的创建的bean工厂是HierarchicalBeanFactory类型的
    if (lbf instanceof HierarchicalBeanFactory) {
        HierarchicalBeanFactory hbf = (HierarchicalBeanFactory)lbf;
        // 我们没有在自己的beanFactory中添加ParentBeanFactory,所以默认为null
        if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
            String[] parentResult = beanNamesForTypeIncludingAncestors((ListableBeanFactory)hbf.getParentBeanFactory(), type, includeNonSingletons, allowEagerInit);
            result = mergeNamesWithParent(result, parentResult, hbf);
        }
    }
    // 返回全部的beanName数组
    return result;
}

AspectMetadata结构

classAdvisors的结构

至此已经获取了全部的Advisor增强器,接下来就是筛选、排序、创建代理了......

createProxy()创建代理对象

protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) {
    if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
        AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory)this.beanFactory, beanName, beanClass);
    }
    // 创建代理工厂
    ProxyFactory proxyFactory = new ProxyFactory();
    // 获取使用@EnableAspectJAutoProxy开启代理时,设置的属性,比如proxyTargetClass(是否使用目标类进行代理--cglib,默认是false,也就是说默认采用的时jdk的动态代理),exposeProxy等
    proxyFactory.copyFrom(this);
    // 判断是否使用目标类进行动态代理
    if (proxyFactory.isProxyTargetClass()) {
        if (Proxy.isProxyClass(beanClass)) {
            Class[] var6 = beanClass.getInterfaces();
            int var7 = var6.length;
​
            for(int var8 = 0; var8 < var7; ++var8) {
                Class<?> ifc = var6[var8];
                proxyFactory.addInterface(ifc);
            }
        }
        // 判断是否应该使用动态代理,这里面是在判断beanDefinition的attributes中是否已经标志过要使用目标类进行动态代理了(一般不存在,需要手动设置)
    } else if (this.shouldProxyTargetClass(beanClass, beanName)) {
        // 如果被标记过了,就设置使用目标类进行代理
        proxyFactory.setProxyTargetClass(true);
    } else {
        // 评估代理接口:
        /**
        首先获取全部的该bean的实现接口,遍历这些接口,这些接口中只要有一个通过(!this.isConfigurationCallbackInterface(ifc) && !this.isInternalLanguageInterface(ifc) && ifc.getMethods().length > 0)判断,就表明存在合理的接口,将这些接口添加到代理工厂中,否则就将其设置为使用目标类代理
        
        **/
        this.evaluateProxyInterfaces(beanClass, proxyFactory);
    }
    // 将前面经过选择和排序的拦截器数组,以及后面解析到的拦截器等构建成统一的Advisor类型,来对对象进行增强
    Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
    proxyFactory.addAdvisors(advisors);
    // 设置需要进行代理的类
    proxyFactory.setTargetSource(targetSource);
    // 空方法
    this.customizeProxyFactory(proxyFactory);
    // 用来控制代理工厂被配置之后,是否还允许修改通知
    // 默认值为false(即在代理被配置之后,不允许修改代理的配置)
    proxyFactory.setFrozen(this.freezeProxy);
    if (this.advisorsPreFiltered()) {
        proxyFactory.setPreFiltered(true);
    }
​
    ClassLoader classLoader = this.getProxyClassLoader();
    if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
        classLoader = ((SmartClassLoader)classLoader).getOriginalClassLoader();
    }
    // 创建代理对象
    return proxyFactory.getProxy(classLoader);
}

我们看一下attribute的内部结构

buildAdvisors()构建通知

protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
    // 解析全部的拦截器
    Advisor[] commonInterceptors = this.resolveInterceptorNames();
    List<Object> allInterceptors = new ArrayList();
    if (specificInterceptors != null) {
        // 添加可用的拦截器
        if (specificInterceptors.length > 0) {
            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) {
        // 将上面获取到的全部拦截器都包装成Advisor类型
        advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
    }
​
    return advisors;
}
getProxy()获取代理对象

public Object getProxy(@Nullable ClassLoader classLoader) {
    // 调用返回的AopProxy的getProxy()方法获取代理对象
    return this.createAopProxy().getProxy(classLoader);
}
// 创建代理对象
protected final synchronized AopProxy createAopProxy() {
        if (!this.active) {
            this.activate();
        }
        // 使用默认的aop代理工厂去创建代理对象(传入我们自己配制的proxyFactory,才能获取到我们的配置),
        return this.getAopProxyFactory().createAopProxy(this);
    }
​
    public AopProxyFactory getAopProxyFactory() {
        return this.aopProxyFactory;
    }
​
    private AopProxyFactory aopProxyFactory;
​
    public ProxyCreatorSupport() {
        // 在我们创建ProxyFactory时,会创建默认的aop代理工厂对象
        this.aopProxyFactory = new DefaultAopProxyFactory();
    }

createAopProxy()创建aop代理

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    // 通过判断选择创建JDKAOP代理还是CglibAop代理
    /**
    选择的原则如下:
      optimize:用来控制通过CGLIB创建的代理是否使用激进的优化策略。除非完全了解AOP代理是如何优化,否则不推荐用户使用这个设置,目前这个属性仅用于CGLIB代理,对于JDK动态代理(缺省代理)无效。
     proxyTargetClass:这个属性为true时,目标类本身被代理而不是目标类的接口。如果这个属性值被设为true,CGLIB代理将被创建
    hasNoUserSuppliedProxyInterfaces 是否存在代理接口
    
    **/
    if (NativeDetector.inNativeImage() || !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 {
            // 最后或返回AopProxy类型的对象,AopProxy是一个接口,跟据选择动态代理的方式不同,会创建不同的代理对象
            return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
        }
    }
}

总结:JDK与Cglib动态代理的选择

proxyTargetClass true 目标对象实现了接口 – 使用CGLIB代理机制 目标对象没有接口(只有实现类) – 使用CGLIB代理机制 false 目标对象实现了接口 – 使用JDK动态代理机制(代理所有实现了的接口) 目标对象没有接口(只有实现类) – 使用CGLIB代理机制

看一下AopProxy的继承关系图

CglibAopProxy#getProxy

private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
    // 获取代理工厂中设置的一些属性信息
    boolean exposeProxy = this.advised.isExposeProxy();
    boolean isFrozen = this.advised.isFrozen();
    boolean isStatic = this.advised.getTargetSource().isStatic();
    // 将我们自己创建的代理工厂封装成DynamicAdvisedInterceptor类型,因为DynamicAdvisedInterceptor实现了了MethodInterceptor接口,跟据Cglib动态代理的使用原理,调用cglib中的方法时会调用MethodInterceptor接口的intercept方法
    Callback aopInterceptor = new CglibAopProxy.DynamicAdvisedInterceptor(this.advised);
    Object targetInterceptor;
    if (exposeProxy) {
        targetInterceptor = isStatic ? new CglibAopProxy.StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) : new CglibAopProxy.DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());
    } else {
        targetInterceptor = isStatic ? new CglibAopProxy.StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) : new CglibAopProxy.DynamicUnadvisedInterceptor(this.advised.getTargetSource());
    }
​
    Callback targetDispatcher = isStatic ? new CglibAopProxy.StaticDispatcher(this.advised.getTargetSource().getTarget()) : new CglibAopProxy.SerializableNoOp();
    Callback[] mainCallbacks = new Callback[]{aopInterceptor, (Callback)targetInterceptor, new CglibAopProxy.SerializableNoOp(), (Callback)targetDispatcher, this.advisedDispatcher, new CglibAopProxy.EqualsInterceptor(this.advised), new CglibAopProxy.HashCodeInterceptor(this.advised)};
    Callback[] callbacks;
    if (isStatic && isFrozen) {
        Method[] methods = rootClass.getMethods();
        Callback[] fixedCallbacks = new Callback[methods.length];
        this.fixedInterceptorMap = CollectionUtils.newHashMap(methods.length);
​
        for(int x = 0; x < methods.length; ++x) {
            Method method = methods[x];
            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
            fixedCallbacks[x] = new CglibAopProxy.FixedChainStaticTargetInterceptor(chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
            this.fixedInterceptorMap.put(method, x);
        }
​
        callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
        System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
        System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
        this.fixedInterceptorOffset = mainCallbacks.length;
    } else {
        callbacks = mainCallbacks;
    }
​
    return callbacks;
}

CglibAopProxy#getCallbacks方法

private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
    // 获取代理工厂中设置的一些属性信息
    boolean exposeProxy = this.advised.isExposeProxy();
    boolean isFrozen = this.advised.isFrozen();
    boolean isStatic = this.advised.getTargetSource().isStatic();
    // 将我们自己创建的代理工厂封装成DynamicAdvisedInterceptor类型,因为DynamicAdvisedInterceptor实现了了MethodInterceptor接口,跟据Cglib动态代理的使用原理,调用cglib中的方法时会调用MethodInterceptor接口的intercept方法
    Callback aopInterceptor = new CglibAopProxy.DynamicAdvisedInterceptor(this.advised);
    Object targetInterceptor;
    if (exposeProxy) {
        targetInterceptor = isStatic ? new CglibAopProxy.StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) : new CglibAopProxy.DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());
    } else {
        targetInterceptor = isStatic ? new CglibAopProxy.StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) : new CglibAopProxy.DynamicUnadvisedInterceptor(this.advised.getTargetSource());
    }
​
    Callback targetDispatcher = isStatic ? new CglibAopProxy.StaticDispatcher(this.advised.getTargetSource().getTarget()) : new CglibAopProxy.SerializableNoOp();
    Callback[] mainCallbacks = new Callback[]{aopInterceptor, (Callback)targetInterceptor, new CglibAopProxy.SerializableNoOp(), (Callback)targetDispatcher, this.advisedDispatcher, new CglibAopProxy.EqualsInterceptor(this.advised), new CglibAopProxy.HashCodeInterceptor(this.advised)};
    Callback[] callbacks;
    if (isStatic && isFrozen) {
        Method[] methods = rootClass.getMethods();
        Callback[] fixedCallbacks = new Callback[methods.length];
        this.fixedInterceptorMap = CollectionUtils.newHashMap(methods.length);
​
        for(int x = 0; x < methods.length; ++x) {
            Method method = methods[x];
            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
            fixedCallbacks[x] = new CglibAopProxy.FixedChainStaticTargetInterceptor(chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
            this.fixedInterceptorMap.put(method, x);
        }
​
        callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
        System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
        System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
        this.fixedInterceptorOffset = mainCallbacks.length;
    } else {
        callbacks = mainCallbacks;
    }
​
    return callbacks;
}

在getCallbacks中spring考虑了很多情况,但是对于我们来说,只需要理解最常用的就可以了,比如将advised属性封装在DynamicAdvisedInterceptor并加入在callbacks中,这么做的目的是什么,为什么会这么做?在前面的示例中,我们了解到CGLIB中对于方法的拦截是通过将自定义的拦截器(实现MethodInterceptor接口)加入Callback中并在调用代理的时候直接激活拦截器中的intercept方法来实现的,那么在getCallback中正是实现了这样的一个目的,DynamicAdvisedInterceptor继承自MethodInterceptor加入CallBack中后,再次调用代理时会直接调用DynamicAdvisedInterceptor中的intercept方法,所以,由此推断,对于CGLIB方式实现的代理,其核心逻辑在DynamicAdvisedInterceptor中的intercept方法,DynamicAdvisedInterceptor作为CglibAopProxy内部封装私有类,其在org.springframework.aop.framework.CglibAopProxy类中:

那我们调用代理对象的方法时,方法会被拦截,依次执行前面设置的callBack[]中的,方法拦截器的intercept(),首先会执行我们创建的封装了自定义的ProxyFactory的DynamicAdvisedInterceptor的intercept()方法,在此方法中完成我们自定义的增强逻辑。

我们看一下通知(具体的增强逻辑)的继承关系:

@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    Object oldProxy = null;
    boolean setProxyContext = false;
    Object target = null;
    TargetSource targetSource = this.advised.getTargetSource();
    try {
        if (this.advised.exposeProxy) {
            // Make invocation available if necessary.
            oldProxy = AopContext.setCurrentProxy(proxy);
            setProxyContext = true;
        }
        // 获取代理对象
        target = targetSource.getTarget();
        Class<?> targetClass = (target != null ? target.getClass() : null);
        // 获取拦截链,我们知道我们之前给每个需要被代理对象都创建了代理工厂,代理工厂中保存了每个被代理对象能够适配(应用的)Advisor[],但是针对于特定方法,就需要从Advisor[]中选择出能够用在此方法上的Advisor增强器,并从增强器中获取具体的增强逻辑(Advice),Interceptor拦截器就是Advice的子接口,这里面获取到的就是该method能够使用的拦截器列表。
        List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
        Object retVal;
        if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
           
            Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
            // 如果拦截链为空则直接激活原方法
            retVal = methodProxy.invoke(target, argsToUse);
        }
        else {
            // We need to create a method invocation...
            // 调用所有拦截器的invoke()方法,以及被代理的方法,完成增强(这里面是一个递归调用proceed()方法,proceed()方法中会获取每一个拦截器链中的拦截器调用它们的invoke()方法,在invoke()方法中会调用proceed()方法)
            /**
                     现在可以看出对advisor进行排序的意义了
            1.事务拦截器会最先执行,invoke方法中又会调用invokeWithinTransaction方法(重要,后续分析)
            2.依次调用around before  原method after afterturn的invoke方法
            **/
            retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
        }
        retVal = processReturnType(proxy, target, method, retVal);
        return retVal;
    }
    finally {
        if (target != null && !targetSource.isStatic()) {
            targetSource.releaseTarget(target);
        }
        if (setProxyContext) {
            // Restore old proxy.
            AopContext.setCurrentProxy(oldProxy);
        }
    }
}

看一下该方法拦截器列表中的内容:

上述的实现与JDK方式实现代理中的invoke方法基本相同,都是首先构造链,然后封装此链进行串联调用,区别就是在JDK代理中直接构造ReflectiveMethodInvocation类,而在CGLIB代理中使用CglibMethodInvocation,CglibMethodInvocation继承自ReflectiveMethodInvocation,但是process方法没有重写。 JdkDynamicAopProxy#getProxy方法

@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
    if (logger.isDebugEnabled()) {
        logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
    }
    //1.为给定的AOP配置确定要代理的完整接口集
    Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
    findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
    //2.创建一个动态代理对象
    return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
​
}

JDKProxy的使用关键是创建自定义的InvocationHandler,而InvocationHandler中包含了需要覆盖的函数getProxy,并且JdkDynamicAopProxy还实现了InvocationHandler接口,所以,AOP的代理会调用它的invoke方法。当调用AOP 动态代理对象的方法时,就会调用它的invoke方法。

总结:

1.首先调用通过Import注册的后置处理器的..after..方法,

判断是否被代理过了,代理过了直接返回原bean

没代理过,进行代理

2.获取可用的增强器,并进行排序,排序原则如下:

/** ​ 1.环绕增强前(around advice before) ​ 2.前置增强(before advice) ​ 3.-- 方法执行 ​ 4.环绕增强后(around advice after) ​ 5.后置finally增强(after advice) ​ 6.后置增强/抛出增强 ​ **/

3.创建代理工厂,设置代理工厂的属性,比如目标代理对象,是否使用cglib动态代理

4.进行判断,选择创建AopProxy还是JDKProxy

5.调用代理的getProxy()方法:

设置拦截器,添加回调,创建代理对象

如有问题欢迎指正讨论.....

参考博文:参考了一篇文章,但是忘记链接是什么了.....sorry下次一定记得/(ㄒoㄒ)/~~

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值