Spring源码解析-AOP

AOP是面向切面编程,能对一些方法进行相同的处理。首先来看一下怎么用。
①创建一个需要被拦截的bean

public class AopTest {
    public void test(){
        System.out.println("test");
    }
}

②创建一个Advisor

package advisor;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

/**
 * Created by Administrator on 2017/8/20 0020.
 */
@Aspect
public class AspectJTest {
    @Pointcut("execution(* *.test(..))")
    public void test(){

    }
    @Before("test()")
    public void beforeTest(){
        System.out.println("start test");
    }
    @After("test()")
    public void afterTst(){
        System.out.println("end test");
    }
    @Around("test()")
    public Object aroundTest(ProceedingJoinPoint point){
        System.out.println("开始环绕");
        Object o = null;
        try {
            o = point.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println("结束环绕");
        return o;
    }
}

③配置xml文件

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:task="http://www.springframework.org/schema/task"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/task
        http://www.springframework.org/schema/task/spring-task.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">

        <aop:aspectj-autoproxy/>
        <bean id="test" class="bean.AopTest"/>
        <bean class="advisor.AspectJTest"/>

</beans>

④测试

@Test
    public void testSimpleLoad(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beanFactoryTest.xml");
        AopTest aopTest = (AopTest) context.getBean("test");
        aopTest.test();
    }
    结果:
    开始环绕
start test
test
结束环绕
end test

现在来分析这个aop
还记得这之前的自定义标签解析了,在碰到自定义标签时,会通过命名空间找到命名空间处理器,然后调用init方法,注册这个解析器,最后进行标签解析,我们找到映射

http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler

进入这个命名空间处理器

public void init() {
        this.registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
        this.registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
        this.registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
        this.registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
    }

看到了他的init方法,正是注册了一个AspectJAutoProxyBeanDefinitionParser解析器,找到parse方法

public BeanDefinition parse(Element element, ParserContext parserContext) {
       //注册AspectJAnnotationAutoProxyCreator AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
       //对注解子类进行处理
        this.extendBeanDefinition(element, parserContext);
        return null;
    }

我们进入registerAspectJAnnotationAutoProxyCreatorIfNecessary这个方法查看

public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(ParserContext parserContext, Element sourceElement) {
        //注册或升级AnnotationAutoProxyCreator这个自动代理创建器
        BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext.getRegistry(), parserContext.extractSource(sourceElement));

进入这个方法

public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
        return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
    }
    //继续进入该方法
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, 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) {
        //改变这个beandefinition的属性                    apcDefinition.setBeanClassName(cls.getName());
                }
            }

            return null;
        } else {
            RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
            beanDefinition.setSource(source);
            beanDefinition.getPropertyValues().add("order", Integer.valueOf(-2147483648));
            beanDefinition.setRole(2);
            //注册这个beanDefinition            registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
            //返回
            return beanDefinition;
        }
    }

回到之前的代码段

//对proxy-target-classexpose-proxy属性进行处理        useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);

进入该方法

private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Element sourceElement) {
        if(sourceElement != null) {
            //获取proxy-target-class属性值
            boolean proxyTargetClass = Boolean.valueOf(sourceElement.getAttribute("proxy-target-class")).booleanValue();
            if(proxyTargetClass) {
            //处理该属性                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            }
            //获取expose-proxy属性值
            boolean exposeProxy = Boolean.valueOf(sourceElement.getAttribute("expose-proxy")).booleanValue();
            if(exposeProxy) {
        //处理该属性                AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
            }
        }

    }

接下来来看一下proxy-target-class属性的处理,就是在BeanDefinition的属性中加入这个值为真,接着我们来了解一下这个属性,一般情况下在创建代理时会检查该类是否实现了接口,如果实现了接口,则采用jdk动态代理,如果没有,则采用cglib动态代理,如果把proxy-target-class设置成true,就会强制采用cglib动态代理,但是一般都是建议采用jdk的动态代理。那么来说一下jdk动态代理和cglib动态代理的区别。其实jdk动态代理我有在博客中写过,jdk动态代理采用接口的实现类来完成目标对象的代理。cglib代理是生成对象的子类来实现动态代理,性能比jdk强,但是无法对final方法进行代理。

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);
        }

    }

对exposeProxy属性的设置跟什么那个属性设置基本是一样的,就不多说了。来说一下exposeProxy这个属性,如果我们采用方法调用,那么这个方法就不回被增强,如果想要被增强的话,那么需要把exposeProxy设为true,然后在调用方法时需要AopContexy.currentProxy(),当这个获得的对象转化为接口再调用方法。
回到原来的方法

        //注册组件并通知
        registerComponentIfNecessary(beanDefinition, parserContext);
    }

AnnotationAutoProxyCreatorIfNecessary类实现了BeanPostProcessor的接口,所以会在容器refresh时进行实例化,并添加到容器中,那么这是怎么进行AOP代理的呢。还记不记得在创建bean方法createBean中有这么一个方法,resolveBeforeInstantiation,这个就是来获得一个代理类的,也就是进行创建AOP代理

protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
        if(this.logger.isDebugEnabled()) {
            this.logger.debug("Creating instance of bean '" + beanName + "'");
        }

        this.resolveBeanClass(mbd, beanName, new Class[0]);

        try {
            mbd.prepareMethodOverrides();
        } catch (BeanDefinitionValidationException var5) {
            throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "Validation of method overrides failed", var5);
        }

        Object beanInstance;
        try {
            beanInstance = this.resolveBeforeInstantiation(beanName, mbd);
            if(beanInstance != null) {
                return beanInstance;
            }
        } catch (Throwable var6) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var6);
        }

        beanInstance = this.doCreateBean(beanName, mbd, args);
        if(this.logger.isDebugEnabled()) {
            this.logger.debug("Finished creating instance of bean '" + beanName + "'");
        }

        return beanInstance;
    }

我们进入这个resolveBeforeInstantiation方法。

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        if(!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            if(mbd.hasBeanClass() && !mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
                bean = this.applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName);
                if(bean != null) {
                    bean = this.applyBeanPostProcessorsAfterInitialization(bean, beanName);
                }
            }

            mbd.beforeInstantiationResolved = Boolean.valueOf(bean != null);
        }

        return bean;
    }

首先来看这个applyBeanPostProcessorsBeforeInstantiation方法,我们可以看出,如果BeanPostProcessor属于InstantiationAwareBeanPostProcessor,那么执行这个beanpost处理器的postProcessBeforeInstantiation方法,
AnnotationAutoProxyCreatorIfNecessary就是
InstantiationAwareBeanPostProcessor的子类,所以执行这个方法。

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        Iterator var3 = this.getBeanPostProcessors().iterator();

        while(var3.hasNext()) {
            BeanPostProcessor bp = (BeanPostProcessor)var3.next();
            if(bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
                Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
                if(result != null) {
                    return result;
                }
            }
        }

        return null;
    }

我们进入这个自动代理创建器,找到初始化前置方法,这个方法的实现是在父类AbstractAutoProxyCreator里面,

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        //根据class和beanName构建出key,结构为beanclassName_beanName
        Object cacheKey = this.getCacheKey(beanClass, beanName);
        //beanName为空或者没有处理过
        if(beanName == null || !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;
            }
        }

        if(beanName != null) {
            //获得目标实例,也就是说这个需要被代理的实例对象
            TargetSource targetSource = this.getCustomTargetSource(beanClass, beanName);
            if(targetSource != null) {
                //添加记录
                this.targetSourcedBeans.add(beanName);
                //获取针对这个bean的增强
                Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
                //创建代理
                Object proxy = this.createProxy(beanClass, beanName, specificInterceptors, targetSource);
                this.proxyTypes.put(cacheKey, proxy.getClass());
                return proxy;
            }
        }

        return null;
    }

但是走到这里时,我们会发现TargetSource targetSource = this.getCustomTargetSource(beanClass, beanName);一般没有在xml文件中配置targetsource,这个值为空。所以会返回null,那么。就需要继续创建bean,在bean实例化后,填充完属性后,又会进入initmethod方法,在这里也会对初始化的前后置处理器进行调用。然后我们来看自动代理创建类的这两个方法。
前置处理没有做任何处理

public Object postProcessBeforeInitialization(Object bean, String beanName) {
        return bean;
    }

后置处理,我们

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if(bean != null) {
            Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
            if(!this.earlyProxyReferences.contains(cacheKey)) {
            //如果适合代理,就需要封装指定bean
                return this.wrapIfNecessary(bean, beanName, cacheKey);
            }
        }

        return bean;
    }

进入wrapIfNecessary方法,其实这个跟这个那个实例前置处理还是很像的

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        //如果已经处理过
        if(beanName != null && 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)) {
            //获取所有切点和通知
            Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);

进入这个方法查看,这是个子类实现的方法

 protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
        List<Advisor> advisors = this.findEligibleAdvisors(beanClass, beanName);
        return advisors.isEmpty()?DO_NOT_PROXY:advisors.toArray();
    }

进入findEligibleAdvisors方法

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
        //获得增强器
        List<Advisor> candidateAdvisors = this.findCandidateAdvisors();

由于我们分析的是使用注解的AOP,所以这个方法是在AnnotationAwareAspectJAutoProxyCreator中完成。

protected List<Advisor> findCandidateAdvisors() {
        //在使用注解方式配置AOP的时候并不是丢弃了对XML配置的支持
        //在这里调用父类的方法加载配置文件的AOP声明
        List<Advisor> advisors = super.findCandidateAdvisors();
        //添加获取bean注解增强的功能        advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
        return advisors;
    }

我们进入这个buildAspectJAdvisors方法

public List<Advisor> buildAspectJAdvisors() {
        List<String> aspectNames = null;
        synchronized(this) {
            aspectNames = this.aspectBeanNames;
            if(aspectNames == null) {
                List<Advisor> advisors = new LinkedList();
                List<String> aspectNames = new LinkedList();
                //找到所有的beanName
                String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
                String[] var18 = beanNames;
                int var19 = beanNames.length;
                //遍历所有的注册的bean,找出含有AspectJ的类
                for(int var7 = 0; var7 < var19; ++var7) {
                    String beanName = var18[var7];
                    if(this.isEligibleBean(beanName)) {
                        Class<?> beanType = this.beanFactory.getType(beanName);
                        //如果存在AspectJ注解
                        if(beanType != null && this.advisorFactory.isAspect(beanType)) {
                            //添加到aspect集合名中
                            aspectNames.add(beanName);
                            AspectMetadata amd = new AspectMetadata(beanType, beanName);
                            if(amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                                MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                                //获取该类中所有的增强方法
                                List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);

我们进入这个方法查看,这个方法需要自己找,这个方法为了获取所有的增强方法

public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory maaif) {
        //获取apectj类的class对象
        Class<?> aspectClass = maaif.getAspectMetadata().getAspectClass();
        //获取标记为aspectj的name
        String aspectName = maaif.getAspectMetadata().getAspectName();
        //验证
        this.validate(aspectClass);
        MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = new LazySingletonAspectInstanceFactoryDecorator(maaif);
        List<Advisor> advisors = new LinkedList();
        //得到所有的增强方法
        Iterator var6 = this.getAdvisorMethods(aspectClass).iterator();
        //遍历
        while(var6.hasNext()) {
            Method method = (Method)var6.next();
                //获取Advisor,在这个方法内会把增强方法,跟切点装配到一块,忽略piontcut
            Advisor advisor = this.getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);

我们看一下getAdvisor这个方法,看一下怎么获取的增强器

public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aif, int declarationOrderInAspect, String aspectName) {
        this.validate(aif.getAspectMetadata().getAspectClass());
        //获取切点
        AspectJExpressionPointcut ajexp = this.getPointcut(candidateAdviceMethod, aif.getAspectMetadata().getAspectClass());

看一下如何获取的切点

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());
            return ajexp;
        }
    }

返回之前的方法

        //根据切点信息生成增强器
        return ajexp == null?null:new InstantiationModelAwarePointcutAdvisorImpl(this, ajexp, aif, candidateAdviceMethod, declarationOrderInAspect, aspectName);
    }

进入InstantiationModelAwarePointcutAdvisorImpl构造方法

public InstantiationModelAwarePointcutAdvisorImpl(AspectJAdvisorFactory af, AspectJExpressionPointcut ajexp, MetadataAwareAspectInstanceFactory aif, Method method, int declarationOrderInAspect, String aspectName) {
        //对下面属性进行封装
        this.declaredPointcut = ajexp;
        this.method = method;
        this.atAspectJAdvisorFactory = af;
        this.aspectInstanceFactory = aif;
        this.declarationOrder = declarationOrderInAspect;
        this.aspectName = aspectName;
        //如果不是懒加载
        if(aif.getAspectMetadata().isLazilyInstantiated()) {
            Pointcut preInstantiationPointcut = Pointcuts.union(aif.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
            this.pointcut = new InstantiationModelAwarePointcutAdvisorImpl.PerTargetInstantiationModelPointcut(this.declaredPointcut, preInstantiationPointcut, aif, (InstantiationModelAwarePointcutAdvisorImpl.SyntheticClass_1)null);
            this.lazy = true;
        } else {
            //生成不同的增强器
            this.instantiatedAdvice = this.instantiateAdvice(this.declaredPointcut);
            this.pointcut = this.declaredPointcut;
            this.lazy = false;
        }

    }

进入instantiateAdvice方法

private Advice instantiateAdvice(AspectJExpressionPointcut pcut) {
        return this.atAspectJAdvisorFactory.getAdvice(this.method, pcut, this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
    }

找到这个getAdvice代码

public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut ajexp, MetadataAwareAspectInstanceFactory aif, int declarationOrderInAspect, String aspectName) {
        Class<?> candidateAspectClass = aif.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(ReflectiveAspectJAdvisorFactory.SyntheticClass_1.$SwitchMap$org$springframework$aop$aspectj$annotation$AbstractAspectJAdvisorFactory$AspectJAnnotationType[aspectJAnnotation.getAnnotationType().ordinal()]) {
            case 1:
                springAdvice = new AspectJMethodBeforeAdvice(candidateAdviceMethod, ajexp, aif);
                break;
            case 2:
                springAdvice = new AspectJAfterAdvice(candidateAdviceMethod, ajexp, aif);
                break;
            case 3:
                springAdvice = new AspectJAfterReturningAdvice(candidateAdviceMethod, ajexp, aif);
                AfterReturning afterReturningAnnotation = (AfterReturning)aspectJAnnotation.getAnnotation();
                if(StringUtils.hasText(afterReturningAnnotation.returning())) {
                    ((AbstractAspectJAdvice)springAdvice).setReturningName(afterReturningAnnotation.returning());
                }
                break;
            case 4:
                springAdvice = new AspectJAfterThrowingAdvice(candidateAdviceMethod, ajexp, aif);
                AfterThrowing afterThrowingAnnotation = (AfterThrowing)aspectJAnnotation.getAnnotation();
                if(StringUtils.hasText(afterThrowingAnnotation.throwing())) {
                    ((AbstractAspectJAdvice)springAdvice).setThrowingName(afterThrowingAnnotation.throwing());
                }
                break;
            case 5:
                springAdvice = new AspectJAroundAdvice(candidateAdviceMethod, ajexp, aif);
                break;
            case 6:
                if(this.logger.isDebugEnabled()) {
                    this.logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
                }

                return null;
            default:
                throw new UnsupportedOperationException("Unsupported advice type on method " + candidateAdviceMethod);
            }

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

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

返回原来代码

            if(advisor != null) {
                //添加到集合中
                advisors.add(advisor);
            }
        }

        if(!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
            //如果寻找的增强器不为空,又配置了增强延迟初始化那么需要在收尾加入同步实例化增强器
            Advisor instantiationAdvisor = new ReflectiveAspectJAdvisorFactory.SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
            advisors.add(0, instantiationAdvisor);
        }

        Field[] var12 = aspectClass.getDeclaredFields();
        int var13 = var12.length;
        //获取DeclareParents注解
        for(int var14 = 0; var14 < var13; ++var14) {
            Field field = var12[var14];
            Advisor advisor = this.getDeclareParentsAdvisor(field);
            if(advisor != null) {
                advisors.add(advisor);
            }
        }
        //返回所有的增强
        return advisors;
    }

返回之前的方法,这时候已经获取了增强方法。

                                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 LinkedList();
            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;
        }
    }

得到所有的增强后,则需要找到匹配的增强器

        //寻找配置的增强器
        List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        this.extendAdvisors(eligibleAdvisors);
        if(!eligibleAdvisors.isEmpty()) {
            eligibleAdvisors = this.sortAdvisors(eligibleAdvisors);
        }

        return eligibleAdvisors;
    }

我们来查看这个这个findAdvisorsThatCanApply方法

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;
    }

进入findAdvisorsThatCanApply方法

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

            while(var3.hasNext()) {
                Advisor candidate = (Advisor)var3.next();
                //首先处理引介增强,在这里就在进行匹配了,先会获取piontcut的execution表达式,然后和该类中的所有方法进行匹配,留下适合的增强器。
                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;
        }
    }

获取增强器后,那么就要进行代理的创建了。

            if(specificInterceptors != DO_NOT_PROXY) {
                this.advisedBeans.put(cacheKey, Boolean.TRUE);
                //创建代理
                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;
        }
    }

我们来看一下如何创建代理

protected Object createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
        //获取代理工厂
        ProxyFactory proxyFactory = new ProxyFactory();
        //获取当前类相关属性
        proxyFactory.copyFrom(this);
        if(!proxyFactory.isProxyTargetClass()) {
            //决定对于给定的bean是否应该使用targetClass而不是他的接口代理,检查proxtTargetClass设置以及preserveTargetClass属性,也就是说,在这里已经开始选择了代理是采用jdk还是cglib
            if(this.shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            } else {
                //添加代理接口
                this.evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }
        //将拦截器封装为增强器
        Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);

我们来看看这个方法

protected Advisor[] buildAdvisors(String beanName, Object[] specificInterceptors) {
        Advisor[] commonInterceptors = this.resolveInterceptorNames();
        List<Object> allInterceptors = new ArrayList();
        if(specificInterceptors != null) {
    //加入拦截器            allInterceptors.addAll(Arrays.asList(specificInterceptors));
            if(commonInterceptors != null) {
                if(this.applyCommonInterceptorsFirst) {
                    allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
                } else {
                    allInterceptors.addAll(Arrays.asList(commonInterceptors));
                }
            }
        }

        int i;
        if(this.logger.isDebugEnabled()) {
            int nrOfCommonInterceptors = commonInterceptors != null?commonInterceptors.length:0;
            i = specificInterceptors != null?specificInterceptors.length:0;
            this.logger.debug("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;
    }

来看一下wrap这个方法

public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
        if(adviceObject instanceof Advisor) {
            //如果是Advisor类就直接返回
            return (Advisor)adviceObject;
        } else if(!(adviceObject instanceof Advice)) {
            throw new UnknownAdviceTypeException(adviceObject);
        } else {
            Advice advice = (Advice)adviceObject;            
            if(advice instanceof MethodInterceptor) {
                //如果是方法拦截器就生成默认的Advisor
                return new DefaultPointcutAdvisor(advice);
            } else {
                Iterator var3 = this.adapters.iterator();
                //如果存在适配器就进行封装
                AdvisorAdapter adapter;
                do {
                    if(!var3.hasNext()) {
                        throw new UnknownAdviceTypeException(advice);
                    }

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

                return new DefaultPointcutAdvisor(advice);
            }
        }
    }
        Advisor[] var7 = advisors;
        int var8 = advisors.length;
        //往代理工厂里加入所有增强器
        for(int var9 = 0; var9 < var8; ++var9) {
            Advisor advisor = var7[var9];
            proxyFactory.addAdvisor(advisor);
        }
        //设置需要代理的类
        proxyFactory.setTargetSource(targetSource);
        //定制代理
        this.customizeProxyFactory(proxyFactory);
        //用来控制代理工厂被配置之后,是否允许修改通知
        //缺省值为false(即在代理被配置后不允许修改代理)
        proxyFactory.setFrozen(this.freezeProxy);
        if(this.advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }
        //得到代理
        return proxyFactory.getProxy(this.proxyClassLoader);
    }

我们来看一下getProxy方法

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

protected final synchronized AopProxy createAopProxy() {
        if(!this.active) {
            this.activate();
        }
        //创建代理
        return this.getAopProxyFactory().createAopProxy(this);
    }
//在这里会选择用cglib做动态代理还是jdk
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 {
                return (AopProxy)(targetClass.isInterface()?new JdkDynamicAopProxy(config):new ObjenesisCglibAopProxy(config));
            }
        }
    }

我们来看一下jdk动态代理怎么完成的aop,在之前的博客中已经讲过了简单的jdk动态代理,通过接口生成一个代理类,代理类调用InvocatioHandler的inovke方法,来完成代理。我们来看一下JdkDynamicAopProxy这个类。
看一个获取代理方法

public Object getProxy(ClassLoader classLoader) {
        if(logger.isDebugEnabled()) {
            logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
        }

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

可见跟jdk的动态代理十分相似,主要还是在于这个类的inovke方法。

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

        Object retVal;
        try {
            //equals方法的处理
            if(!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
                Boolean var18 = Boolean.valueOf(this.equals(args[0]));
                return var18;
            }
            //hash方法的处理
            if(!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
                Integer var17 = Integer.valueOf(this.hashCode());
                return var17;
            }

            if(this.advised.opaque || !method.getDeclaringClass().isInterface() || !method.getDeclaringClass().isAssignableFrom(Advised.class)) {
                if(this.advised.exposeProxy) {
                    oldProxy = AopContext.setCurrentProxy(proxy);
                    setProxyContext = true;
                }

                target = targetSource.getTarget();
                if(target != null) {
                    targetClass = target.getClass();
                }
                //获取对应方法的拦截器链
                List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
                //如果拦截器是空的,直接执行该方法
                if(chain.isEmpty()) {
                    retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
                } else {
                    //将方法和拦截器封装在ReflectiveMethodInvocation中
                    MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
                    //执行拦截器
                    retVal = invocation.proceed();
                }

                Class<?> returnType = method.getReturnType();
                if(retVal != null && retVal == target && 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 var13 = retVal;
                return var13;
            }

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

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

        }

        return retVal;
    }

我们来看一下这个proceed的执行过程

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;

                return dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)?dm.interceptor.invoke(this):this.proceed();
            } else {
                //如果是普通拦截器就是调用inoke方法
                return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
            }
        }
    }

了解过设计模式的应该知道这叫责任链模式。
所以前置增强的执行过程是先调用增强方法,在调用这个process,相当于责任的传递,而后置增强是先调用这个process,然后return,最后用finally执行后置方法。
除了AOP动态代理,还有静态代理,静态代理是在生成class时,虚拟机直接生成了代理后的class。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值