SpringAOP——源码

一、找到代理对象初始化的地方

上一篇的例子

 1 @Configuration
 2 @EnableAspectJAutoProxy
 3 public class Main {
 4 
 5     public static void main(String[] args){
 6         AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
 7         context.scan("com.app.aop");
 8         context.refresh();
 9         Xxable a = (Xxable)context.getBean("a");
10         B b = (B) context.getBean("b");
11         a.xx();
12         b.xx();
13         System.out.println(a.getClass().getName());
14         System.out.println(b.getClass().getName());
15     }
16 }

在第9行断点发现,IOC容器初始化后,IOC容器中存放的已经是代理对象proxy obejct

 根据动态代理分析:JDK动态代理是先创建targetobject然后将targetobject组合到proxyObject中,所以创建proxy object必是在target object初始化之后

通过前面bean初始化知道在DI之后才bean基本初始化完成,也就是proxy object的产生是在DI之后,

最后在bean初始化完成后,调用BeanPostProcessor时找到了proxy object产生的地方

/* org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean */

    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
        throws BeanCreationException {
        ...
        //这里实现DI
        populateBean(beanName, mbd, instanceWrapper);
        //DI完成后执行BeanPostProcessor
        exposedObject = initializeBean(beanName, exposedObject, mbd);
        ...
    }

/* org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition) */

    protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
      ...
        //调用所有BeanPostProcessor前置方法BeanPostProcessor.postProcessBeforeInitialization
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        ...
        //调用所有BeanPostProcessor前置方法BeanPostProcessor.postProcessAfterInitialization
        //AOP代理对象就是这里初始化的
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        ...
    }

具体的实现AnnotationAwareAspectJAutoProxyCreator.postProcessAfterInitialization

二、AnnotationAwareAspectJAutoProxyCreator

AnnoatiowareAspectJAutoProxyCreator.postprocessAfterInitialzation

/* org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization */
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        if (bean != null) {
            //feactoryBean beanName = &beanName
            //Bean beanName = beanName
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                //创建proxy object
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }

    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        //跳过自定义代理的Bean例如有个Bean使用AspectJ实现AOP,不需要使用SpringAOP再来代理了
(设置BeanPostProcessor.targetSourcedBeans.add)
//避免自定义代理后,又默认代理一遍 if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } //skip不能被代理的Bean(设置BeanPostProcessor.before里面advisedBeans.put) //例如PointCut.class的实例Bean if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } //再次验证上一步 if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // Create proxy if we have advice. //如果有advisor获取所有的advisors,然后筛选出class对应joinpoint的advisors Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); //advisors不为空初始化proxy object if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); //创建代理对象proxy object Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);获取所有的advisors
/* org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean */
    protected Object[] getAdvicesAndAdvisorsForBean(
            Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
        //统计advice
        List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
        if (advisors.isEmpty()) {
            return DO_NOT_PROXY;
        }
        return advisors.toArray();
    }

    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
        //查找所有Advisor,用Bean创建的Advisor+aspectBean中的advisor方法
        List<Advisor> candidateAdvisors = findCandidateAdvisors();
        //根据class中方法匹配对应的Advisor,过滤当前bean TargetClass与Advisor对应的pointCut相匹配的Advisor
        List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        //加入一个默认的ExposeInvocationInterceptor.ADVISOR
        //后面责任链模式执行代理方法,这个advisor就位于责任链首位了,第一个需要被执行的advisor
        //作用就是记录target object的方法(ThreadLocal实现),便于调整五种advice的执行循序的实现
        extendAdvisors(eligibleAdvisors);
        if (!eligibleAdvisors.isEmpty()) {
            //一开始我以为是倒序后来发现错了,默认先比较order值
        //默认advisor。order < 0 放首位
            //然后调整afterThrowAdvice>afterRuturningAdvice>afterAdivce>RoundAdvice>BeforeAdvice
            eligibleAdvisors = sortAdvisors(eligibleAdvisors);
        }
        return eligibleAdvisors;
    }
List<Advisor> candidateAdvisors = findCandidateAdvisors();:获取所有的advisors Bean创建的advisor+扫描aspect中的advisor方法
/* org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors */
    protected List<Advisor> findCandidateAdvisors() {
        // Add all the Spring advisors found according to superclass rules.
        //用Bean创建的Advice
        List<Advisor> advisors = super.findCandidateAdvisors();
        // Build Advisors for all AspectJ aspects in the bean factory.
        if (this.aspectJAdvisorsBuilder != null) {
            //加上aspect的Bean中的Advice方法
            advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
        }
        return advisors;
    }
this.aspectJAdvisorsBuilder.buildAspectJAdvisors():获取aspect中声明的advisors
/* org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors */
    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<>();
                    aspectNames = new ArrayList<>();
                    //获取beanfactory中所有的beanName,遍历allBeanNamesByType获得
                    String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                            this.beanFactory, Object.class, true, false);
                    for (String beanName : beanNames) {
                        if (!isEligibleBean(beanName)) {
                            continue;
                        }
                        // We must be careful not to instantiate beans eagerly as in this case they
                        // would be cached by the Spring container but would not have been weaved.
                        //根据beanName过去bean的类型Type
                        Class<?> beanType = this.beanFactory.getType(beanName);
                        if (beanType == null) {
                            continue;
                        }
                        // 根据beanType筛选出切面aspect:
                        // class被@Aspect注解,且不是AspectJ编译器生成的类(通过魔数判断)
                        if (this.advisorFactory.isAspect(beanType)) {
                            //缓存aspectBean的beanName
                            aspectNames.add(beanName);
                            AspectMetadata amd = new AspectMetadata(beanType, beanName);
                            if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                                MetadataAwareAspectInstanceFactory factory =
                                        new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                                //从aspect中定义的advisor
                                List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                                if (this.beanFactory.isSingleton(beanName)) {
                                    //单例缓存advisor
                                    this.advisorsCache.put(beanName, classAdvisors);
                                }
                                else {
                                    //原型缓存factory
                                    this.aspectFactoryCache.put(beanName, factory);
                                }
                                advisors.addAll(classAdvisors);
                            }
                            else {
                                // Per target or per this.
                                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();
        }
        //有缓存直接去缓存取
        List<Advisor> advisors = new ArrayList<>();
        for (String aspectName : aspectNames) {
            List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
            if (cachedAdvisors != null) {
                advisors.addAll(cachedAdvisors);
            }
            else {
                MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
                advisors.addAll(this.advisorFactory.getAdvisors(factory));
            }
        }
        return advisors;
    }
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);获取aspecj的advisor并排序
/* org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisors */
    public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
        //获取aspectClass & AspectName并在此校验
        Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
        String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
        validate(aspectClass);

        // We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
        // so that it will only instantiate once.
        MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
                new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

        List<Advisor> advisors = new ArrayList<>();
        //getAdvisorMethods获取aspect中advice方法并且排序,
        for (Method method : getAdvisorMethods(aspectClass)) {
            //注意advisors.size()这个参数,这里生成advisor实例类型是InstantiationModelAwarePointcutAdvisorImpl这个类实现了Ordered接口,
//advisors.size()就是优先级,后面会根据这个变量排序一次
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName); if (advisor != null) { advisors.add(advisor); } } // If it's a per target aspect, emit the dummy instantiating aspect. if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory); advisors.add(0, instantiationAdvisor); } // Find introduction fields. //introduction:获取被@DeclareParents注解变量 for (Field field : aspectClass.getDeclaredFields()) { Advisor advisor = getDeclareParentsAdvisor(field); if (advisor != null) { advisors.add(advisor); } } return advisors; } private List<Method> getAdvisorMethods(Class<?> aspectClass) { final List<Method> methods = new ArrayList<>(); ReflectionUtils.doWithMethods(aspectClass, method -> { // Exclude pointcuts if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) { //获取aspect中的advice方法,没有被@Pointcut注解的方法,下面比较器中 //如果未被advice相关注解的方法,会设置为null,即排序的时候再筛选了一次 methods.add(method); } }, ReflectionUtils.USER_DECLARED_METHODS); // methods.sort(METHOD_COMPARATOR); return methods; }
METHOD_COMPARATOR:排序比较器
/* org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory */
    static {
        Comparator<Method> adviceKindComparator = new ConvertingComparator<>(
                //advice排序:around>before>after>afterReturning>afterThrowing
//后面还会调整:afterThrowing>afterReturning>after>around>before
//运行无异常时:around before>before>around after>after>after returning> //有异常时:around before>before>after>afterThrowing new InstanceComparator<>( Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class), (Converter<Method, Annotation>) method -> { AspectJAnnotation<?> annotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method); return (annotation != null ? annotation.getAnnotation() : null); }); Comparator<Method> methodNameComparator = new ConvertingComparator<>(Method::getName); METHOD_COMPARATOR = adviceKindComparator.thenComparing(methodNameComparator); }
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));创建代理对象proxy object
/* org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy */
    protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
            @Nullable Object[] specificInterceptors, TargetSource targetSource) {

        if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
            //修改beandefinition.setAttribute(org.springframework.aop.framework.autoproxy.AutoProxyUtils.originalTargetClass,targetClass)
            AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
        }

        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.copyFrom(this);

        //传说中的ProxyTargetClass属性
        //false 默认JDK动态代理、无接口类使用CgLib代理
        //true 强制全部使用CgLib代理
        if (!proxyFactory.isProxyTargetClass()) {
            if (shouldProxyTargetClass(beanClass, beanName)) {
                //beandefinition.getAttribute(org.springframework.aop.framework.autoproxy.AutoProxyUtils.preserveTargetClass)
                //=true,则使用Cglib代理
                proxyFactory.setProxyTargetClass(true);
            }
            else {
                //检测beanClass如果实现了接口,记录所有的接口到proxyFactory.interfaces容器中
                //检测beanClass如果没有实现接口 proxyFactory.setProxyTargetClass(true);
                evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }
     //将Advisor中实例转化为DefaultPointcutAdvisor实例
        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
        //设置advisors到proxyFactory
        proxyFactory.addAdvisors(advisors);
        //设置targetSource到proxyFactory
        proxyFactory.setTargetSource(targetSource);
        //空方法
        customizeProxyFactory(proxyFactory);

        proxyFactory.setFrozen(this.freezeProxy);
        if (advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }
        //getProxyClassLoader  上下文线程类加载器,服务提供接口SPI了解一下
        return proxyFactory.getProxy(getProxyClassLoader());
    }
return proxyFactory.getProxy(getProxyClassLoader());创建Proxy object ==>createAopProxy().getProxy(classLoader);
//众所众知的默认代理设置
/*org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy */
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
            //optimize = true
            //proxyTargetCass = true
            //proxyFactory.interfaces.length = 0
            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.");
            }
            if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                //目标类型是接口类型 || targetClass是Proxy的实现类
                //返回JDK动态代理
                return new JdkDynamicAopProxy(config);
            }
            //保底CgLib代理
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            //默认JDK动态代理
            return new JdkDynamicAopProxy(config);
        }
    }

/* org.springframework.aop.framework.JdkDynamicAopProxy#getProxy(java.lang.ClassLoader) */
    public Object getProxy(@Nullable ClassLoader classLoader) {
        if (logger.isTraceEnabled()) {
            logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
        }
        //proxy object需要实现的接口
        Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
        findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
        //动态代理InvocationHandler的那个类this=JdkDynamicAopProxy实例
        return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
    }

proxy.method == JdkDynamicAopProxy.invoke(method) == CglibAopProxy.DynamicAdvisedInterceptor.intercept(method):

具体实现逻辑很相似,仅仅是代理对象创建方式不同,方法调用的逻辑基本一致。

/* org.springframework.aop.framework.JdkDynamicAopProxy#invoke */
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       ...
        // 生成一个advisor链,这里责任链模式Get the interception chain for this method
        // 验证当前方法是join point:pointAdvisor.getPointcut().getMethodMatcher().matchs(method)
        List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
        ...
        MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
        // Proceed to the joinpoint through the interceptor chain.
        //通过责任链顺序执行方法
        retVal = invocation.proceed();
     ...
    }

两种代理方法责任链模式实现是同一个方法。

/* org.springframework.aop.framework.ReflectiveMethodInvocation#proceed */
public Object proceed() throws Throwable {
        // We start with an index of -1 and increment early.
        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
            return invokeJoinpoint();
        }

        Object interceptorOrInterceptionAdvice =
                this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
        if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
            // Evaluate dynamic method matcher here: static part will already have
            // been evaluated and found to match.
            InterceptorAndDynamicMethodMatcher dm =
                    (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
            Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
            if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
                return dm.interceptor.invoke(this);
            }
            else {
                // Dynamic matching failed.
                // Skip this interceptor and invoke the next in the chain.
                return proceed();
            }
        }
        else {
            // It's an interceptor, so we just invoke it: The pointcut will have
            // been evaluated statically before this object was constructed.
            return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
        }
    }

 具体流程

1、ExposeInvocationInterceptor----默认Advisor
    public Object invoke(MethodInvocation mi) throws Throwable {
        MethodInvocation oldInvocation = invocation.get();
        invocation.set(mi);
        try {
            return mi.proceed();
        }
        finally {
            invocation.set(oldInvocation);
        }
    }
    -----------
    mi.proceed();
2、AspectJAfterThrowingAdvice----AfterThrowingAdvice
    public Object invoke(MethodInvocation mi) throws Throwable {
        try {
            return mi.proceed();
        }
        catch (Throwable ex) {
            if (shouldInvokeOnThrowing(ex)) {
                invokeAdviceMethod(getJoinPointMatch(), null, ex);
            }
            throw ex;
        }
    }
    -----------
    try{
        mi.proceed();
    }catch(Throwable ex){
        AfterThrowingAdvice
    }
3、AfterReturningAdviceInterceptor----AfterReturningAdvice
    public Object invoke(MethodInvocation mi) throws Throwable {
        Object retVal = mi.proceed();
        this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
        return retVal;
    }
    -------------
    try{
        mi.proceed();
        AfterReturningAdvice
    }catch(Throwable ex){
        AfterThrowingAdvice
    }
4、AspectJAfterAdvice----AfterAdvice
    public Object invoke(MethodInvocation mi) throws Throwable {
        try {
            return mi.proceed();
        }
        finally {
            invokeAdviceMethod(getJoinPointMatch(), null, null);
        }
    }
    ----------------
    try{
        mi.proceed();
        AfterReturningAdvice
    }catch(Throwable ex){
        AfterThrowingAdvice
    }finally{
        AfterAdvice
    }
5、AspectJAroundAdvice----AroundAdvice
    public Object invoke(MethodInvocation mi) throws Throwable {
        if (!(mi instanceof ProxyMethodInvocation)) {
            throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
        }
        ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
        ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
        JoinPointMatch jpm = getJoinPointMatch(pmi);
        return invokeAdviceMethod(pjp, jpm, null, null);
    }
    ----------------
    try{
        around before advice
        mi.proceed();
        around after advice
        AfterReturningAdvice
    }catch(Throwable ex){
        AfterThrowingAdvice
    }finally{
        AfterAdvice
    }
6、MethodBeforeAdviceInterceptor----BeforeAdvice
    public Object invoke(MethodInvocation mi) throws Throwable {
        this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
        return mi.proceed();
    }
    -----------------
    try{
        around after advice
        BeforeAdvice
        mi.proceed();//method.invoke(target,methodName);
        around after advice
        AfterReturningAdvice
    }catch(Throwable ex){
        AfterThrowingAdvice
    }finally{
        AfterAdvice
    }

..

posted on 2020-03-02 15:27  FFStayF  阅读(238)  评论(0编辑  收藏  举报