Spring源码探究——Spring的AOP是如何实现的

前言&准备工作

之前的源码分析文章中,我们介绍了IoC的执行流程,在本篇文章中,我们来解析一些Spring的另一大功能——AOP。

准备工作

1.准备被切入的方法方法

@Component
public class HelloService {
public void sayHello(){
    System.out.println("HELLO WORLD");
}
}

2.准备切面

@Aspect
@Component
public class LogAspect {

    @Before("execution(* com.core.aop.HelloService.sayHello(..))")
    public void beforeHello(){
        System.out.println("before aop is working");
    }
    @After("execution(* com.core.aop.HelloService.sayHello(..))")
    public void afterHello(){
        System.out.println("after aop is working");
    }
    @AfterReturning("execution(* com.core.aop.HelloService.sayHello(..))")
    public void AfterReturning(){
        System.out.println("return aop is working");
    }
}

3.准备配置类

@EnableAspectJAutoProxy
@Configuration
@ComponentScan(value = "com.core.aop")
public class AopConfig {
}

4.准备测试类

public class TestAop {
    @Test
    public void testaspect(){
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AopConfig.class);
        HelloService helloService = applicationContext.getBean("helloService", HelloService.class);
        helloService.sayHello();
    }
}

我们大致把AOP分为三大步 1.解析&获得切面2.将通知织入目标方法3.执行目标方法

解析&获得切面

在之前的文章我们已经知道了在通过配置类创建容器时会在invokeBeanFactoryPostProcessors()这一步中解析配置类,解析到@EnableAspectJAutoProxy注解时,会在容器中引入AspectJAutoProxyRegistrar.class,而该类又会在容器中注入一个AnnotationAwareAspectJAutoProxyCreator的bean定义信息。
在这里插入图片描述
通过类图我们可以看到该组件是一个BeanPostprocessor,它会在创建bean的各个阶段对bean进行操作,通过它的名字我们也不难猜出它与AOP息息相关。当然,再牛逼的组件也需要实例化之后才能使用,来到this.registerBeanPostProcessors(beanFactory),在这个步骤中会进行所有beanprocessor的实例化。
待初始化的beanProcessor
初始化方法,初始化了内部的一些属性,我们以后还要经常见到。

   protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        this.advisorRetrievalHelper = new AbstractAdvisorAutoProxyCreator.BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
    }
 protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        super.initBeanFactory(beanFactory);
        if (this.aspectJAdvisorFactory == null) {
            this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
        }

        this.aspectJAdvisorsBuilder = new AnnotationAwareAspectJAutoProxyCreator.BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
    }

此时这个负责AOP的组件就实例化完成了,接下来来分析它是如何解析切面与通知的。

  • 作用时间点 1 创建bean之前的resolveBeforeInstantiation()方法(在该方法中,若有bean后置处理器能生成对应的实例,就会直接返回生成的实例)。
    在这时,无论正在实例化的组件是不是切面,都会为其生成对应的增强的Advisors 。
/**
resolveBeforeInstantiation()初始化过程中的层层调用
*/
createBean()
|
resolveBeforeInstantiation()
|
applyBeanPostProcessorsBeforeInstantiation()
|
postProcessBeforeInstantiation()
|
shouldSkip()
|
this.findCandidateAdvisors();//为当前的Bean寻找对应的Advisor(增强器)
|
 protected List<Advisor> findCandidateAdvisors() {
        List<Advisor> advisors = super.findCandidateAdvisors();
        if (this.aspectJAdvisorsBuilder != null) {
        	//利用bulder为其创建增强器
            advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
        }

        return advisors;
    }

重要BeanFactoryAspectJAdvisorsBuilder.class 创建增强器的逻辑

public List<Advisor> buildAspectJAdvisors() {
        List<String> aspectNames = this.aspectBeanNames;
        //双重检查锁机制
        if (aspectNames == null) {
            synchronized(this) {
                aspectNames = this.aspectBeanNames;
                if (aspectNames == null) {
                    List<Advisor> advisors = new LinkedList();
                    List<String> aspectNames = new LinkedList();
                    //获取到当前容器中所有的bean名字,所以当实例化第一个组件时
                    //就已经完成了对所有bean的解析。
                    String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
                    String[] var18 = beanNames;
                    int var19 = beanNames.length;
					//挨个遍历对应类名
                    for(int var7 = 0; var7 < var19; ++var7) {
                        String beanName = var18[var7];
                        if (this.isEligibleBean(beanName)) {
                            //获取bean类型
                            Class<?> beanType = this.beanFactory.getType(beanName);
                            //解析判断是否被Aspect注解或以ajc$开头
                            if (beanType != null && this.advisorFactory.isAspect(beanType)) {
                            //若是则将其加入这个集合中
                                aspectNames.add(beanName);
                                //获取切面类的元数据信息
                                AspectMetadata amd = new AspectMetadata(beanType, beanName);	
              					//如果是切面是单例,则通过以下逻辑                  
                                if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                                    //将当前的工厂和bean名封装成MetadataAwareAspectInstanceFactory
                                    MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                                    //真正的构造增强器的方法
                                    List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                                    //若是单例对象,则放到增强器缓存中
                                    if (this.beanFactory.isSingleton(beanName)) {
                                        this.advisorsCache.put(beanName, classAdvisors);
                                    } else {
                                    	//否则放到另一个缓存中
                                        this.aspectFactoryCache.put(beanName, factory);
                                    }
									
                                    advisors.addAll(classAdvisors);
                                } else {
                                //切面非单例但工厂为单例的情况 抛出异常
                                    if (this.beanFactory.isSingleton(beanName)) {
                                        throw new IllegalArgumentException("Bean with name '" + beanName + "' is a singleton, but aspect instantiation model is not singleton");
                                    }
									//同上
                                    MetadataAwareAspectInstanceFactory factory = new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
                                    this.aspectFactoryCache.put(beanName, factory);
									advisors.addAll(this.advisorFactory.getAdvisors(factory));
                                }
                            }
                        }
                    }

                    this.aspectBeanNames = aspectNames;
                    return advisors;
                }
            }
        }
		//下次再执行时,直接进入以下逻辑,因为所有的类都在第一次执行后置处理时被解析过了。
        if (aspectNames.isEmpty()) {
            return Collections.emptyList();
        } else {
            List<Advisor> advisors = new 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;
        }
    }


//真正创建增强器的方法
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
	//先获取类信息
        Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
        //再获取类名
        String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
        //验证,主要判断该类是否被Aspect注解修饰,是否使用PERCFLOWBELOW或PERCFLOW方式进行AOP
        this.validate(aspectClass);
        //包装一下,包装成与懒加载切面工厂(因为此时我们真正被切入的类还没创建,所以使用懒加载的策略)
        MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
        List<Advisor> advisors = new LinkedList();
        //获取增强方法的迭代器
      	//这里实际上获取的是当前对象的所有方法,包括Object类的方法
      	//并对这些方法进行排序
        Iterator var6 = this.getAdvisorMethods(aspectClass).iterator();
		//遍历所有方法,获得其对应的增强器。
        while(var6.hasNext()) {
            Method method = (Method)var6.next();
            Advisor advisor = this.getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
            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;
		//为需要被增强的字段(被@DeclareParent修饰)创建增强器
        for(int var14 = 0; var14 < var13; ++var14) {
            Field field = var12[var14];
            Advisor advisor = this.getDeclareParentsAdvisor(field);
            if (advisor != null) {
                advisors.add(advisor);
            }
        }
		//返回
        return advisors;
    }
//获取增强器的方法
 @Nullable
    public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrderInAspect, String aspectName) {
    	//检查,内部逻辑同上
        this.validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
        //获得切点
        AspectJExpressionPointcut expressionPointcut = this.getPointcut(candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
        //若返回的AspectJExpressionPointcut 不为空,则实例化InstantiationModelAwarePointcutAdvisorImpl对象
        return expressionPointcut == null ? null : new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
    }
    


   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]);
            //将表达式放入AspectJExpressionPointcut对象中
            ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
            if (this.beanFactory != null) {
                ajexp.setBeanFactory(this.beanFactory);
            }
			//返回
            return ajexp;
        }
    }
//获取注解的方法,解析当前方法的注解,遍历classesToLookFor,看是否符合其中的一个,若符合则直接返回
@Nullable
    protected static AbstractAspectJAdvisorFactory.AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
        Class<?>[] classesToLookFor = new Class[]{Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
        Class[] var2 = classesToLookFor;
        int var3 = classesToLookFor.length;

        for(int var4 = 0; var4 < var3; ++var4) {
            Class<?> c = var2[var4];
            AbstractAspectJAdvisorFactory.AspectJAnnotation<?> foundAnnotation = findAnnotation(method, c);
            if (foundAnnotation != null) {
                return foundAnnotation;
            }
        }

        return null;
    }
//初始化方法,重点在最后一步
 public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut, Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
        this.declaredPointcut = declaredPointcut;
        this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
        this.methodName = aspectJAdviceMethod.getName();
        this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
        this.aspectJAdviceMethod = aspectJAdviceMethod;
        this.aspectJAdvisorFactory = aspectJAdvisorFactory;
        this.aspectInstanceFactory = aspectInstanceFactory;
        this.declarationOrder = declarationOrder;
        this.aspectName = aspectName;
        if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
            Pointcut preInstantiationPointcut = Pointcuts.union(aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
            this.pointcut = new InstantiationModelAwarePointcutAdvisorImpl.PerTargetInstantiationModelPointcut(this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
            this.lazy = true;
        } else {
            this.pointcut = this.declaredPointcut;
            this.lazy = false;
            //实例化增强器
            this.instantiatedAdvice = this.instantiateAdvice(this.declaredPointcut);
        }
    }
//真正的创建增强器的方法
 @Nullable
    public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
    	//获得切面类
        Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
        //验证
        this.validate(candidateAspectClass);
        //获取通知方法的注解信息
        AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
        if (aspectJAnnotation == null) {
            return null;
        } else if (!this.isAspect(candidateAspectClass)) {
            throw new AopConfigException("Advice must be declared inside an aspect type: Offending method '" + candidateAdviceMethod + "' in class [" + candidateAspectClass.getName() + "]");
        } else {
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Found AspectJ method: " + candidateAdviceMethod);
            }
				//switch判断,这里以@Before通知为例
            Object springAdvice;
            switch(aspectJAnnotation.getAnnotationType()) {
            case AtBefore:
            	//将所有的信息封装成AspectJMethodBeforeAdvice对象
                springAdvice = new AspectJMethodBeforeAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
                break;
            case AtAfter:
                springAdvice = new AspectJAfterAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
                break;
            case AtAfterReturning:
                springAdvice = new AspectJAfterReturningAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
                AfterReturning afterReturningAnnotation = (AfterReturning)aspectJAnnotation.getAnnotation();
                if (StringUtils.hasText(afterReturningAnnotation.returning())) {
                    ((AbstractAspectJAdvice)springAdvice).setReturningName(afterReturningAnnotation.returning());
                }
                break;
            case AtAfterThrowing:
                springAdvice = new AspectJAfterThrowingAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
                AfterThrowing afterThrowingAnnotation = (AfterThrowing)aspectJAnnotation.getAnnotation();
                if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
                    ((AbstractAspectJAdvice)springAdvice).setThrowingName(afterThrowingAnnotation.throwing());
                }
                break;
            case AtAround:
                springAdvice = new AspectJAroundAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
                break;
            case AtPointcut:
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
                }

                return null;
            default:
                throw new UnsupportedOperationException("Unsupported advice type on method: " + candidateAdviceMethod);
            }
			//再向生成的springAdvice添加一些信息
            ((AbstractAspectJAdvice)springAdvice).setAspectName(aspectName);
            ((AbstractAspectJAdvice)springAdvice).setDeclarationOrder(declarationOrder);
            String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
            if (argNames != null) {
                ((AbstractAspectJAdvice)springAdvice).setArgumentNamesFromStringArray(argNames);
            }

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


至此,我们已经完成了第一大步,解析&获得切面 ,我们在切面类中标注的每一个方法都被封装成为了一个个Advisor。在这里插入图片描述

将通知织入目标方法

1.Aop相关的后置处理器第一次起作用是在创建bean之前的resolveBeforeInstantiation阶段,此时并没有对bean做出什么实质操作,最终返回的是null。进而进入下一个阶段。
2.第二次对bean进行操作是在bean完成实例创建与依赖注入之后的initializeBean()阶段

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
       //省略部分代码
		//aop在这里起作用
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
        Object result = existingBean;
		//依次遍历所有的后置处理器对bean进行处理,这里我们只探究Aop相关的处理器
        Object current;
        for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) {
            BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
            current = beanProcessor.postProcessAfterInitialization(result, beanName);
            if (current == null) {
                return result;
            }
        }

        return result;
    }

public Object postProcessAfterInitialization(@Nullable 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;
    }
    //对bean进行包装的方法
    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        //判断是否为targetSourcedBean对象
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        	//判断是否是不需要增强的类
        } else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
            	//是否是基础设施类(被advice,pointcut等修饰的类 )或是需要跳过的类
        } else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
        	//为bean获取增强器,这里叫拦截器
            Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
            //增强器是否为空
            if (specificInterceptors != DO_NOT_PROXY) {
                //不为空,则说明需要增强,首先存入缓存,key是方法名
                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 {
            //否则直接返回原bean
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return bean;
            }
        } else {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
    }
//寻找对应的增强器
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
        List<Advisor> candidateAdvisors = this.findCandidateAdvisors();
        //寻找能够应用的增强器
        List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        //扩展增强器,会在增强器的list中加入org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR,并放到list的第一个位置
        this.extendAdvisors(eligibleAdvisors);
        if (!eligibleAdvisors.isEmpty()) {
        	//进行排序
            eligibleAdvisors = this.sortAdvisors(eligibleAdvisors);
        }
		//返回
        return eligibleAdvisors;
    }

	//简单看一看Spring是如何判断是否能进行增强的方法
    public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
        Assert.notNull(pc, "Pointcut must not be null");
        if (!pc.getClassFilter().matches(targetClass)) {
            return false;
        } else {
        	//拿到方法匹配器,里面保存了切面类信息与切点表达式信息等
            MethodMatcher methodMatcher = pc.getMethodMatcher();
            if (methodMatcher == MethodMatcher.TRUE) {
                return true;
            } else {
                IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
                if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
                    //强转
                    introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher)methodMatcher;
                }
				//获取类的所有接口
                Set<Class<?>> classes = new LinkedHashSet(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
                classes.add(targetClass);
                Iterator var6 = classes.iterator();
                //遍历获取到的所有类信息
                while(var6.hasNext()) {
                    Class<?> clazz = (Class)var6.next();
                    //获取类中的所有方法,包括Object类中的方法
                    Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
                    Method[] var9 = methods;
                    int var10 = methods.length;
					//遍历所有方法,判断是否能匹配对应的增强器
                    for(int var11 = 0; var11 < var10; ++var11) {
                        Method method = var9[var11];
                        if (introductionAwareMethodMatcher != null && introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) || methodMatcher.matches(method, targetClass)) {
                        //如果能增强,返回true,findAdvisorsThatCanApply会将对应的advisor放入集合中返回。
                            return true;
                        }
                    }
                }

                return false;
            }
        }
    }

在这里插入图片描述

到了这一步,spring已经为对应方法找到了与其匹配的增强方法,并封装进了specificInterceptors 中,接下来来看一看创建代理对象的方法。

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();
        //拷贝
        proxyFactory.copyFrom(this);
        //不是目标代理类。
        if (!proxyFactory.isProxyTargetClass()) {
            if (this.shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            } else {
                this.evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }
		//把传入的specificInterceptors构造为Advisor
        Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
        //将advisor放入工厂中
        proxyFactory.addAdvisors(advisors);
        //设置对象
        proxyFactory.setTargetSource(targetSource);
        //模板方法,我们可以继承重写该方法对增强工厂进行进一步的操作
        this.customizeProxyFactory(proxyFactory);
        proxyFactory.setFrozen(this.freezeProxy);
        //当前的adviser是否被过滤
        if (this.advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }
		//做完了前置准备,进入生成代理对象的方法
        return proxyFactory.getProxy(this.getProxyClassLoader());
    }
public Object getProxy(@Nullable ClassLoader classLoader) {
        if (logger.isDebugEnabled()) {
            logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
        }

        try {
            Class<?> rootClass = this.advised.getTargetClass();
            Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
            Class<?> proxySuperClass = rootClass;
            int x;
            //判断是否是cglib类(包含$$)
            if (ClassUtils.isCglibProxyClass(rootClass)) {
                proxySuperClass = rootClass.getSuperclass();
                Class<?>[] additionalInterfaces = rootClass.getInterfaces();
                Class[] var5 = additionalInterfaces;
                int var6 = additionalInterfaces.length;

                for(x = 0; x < var6; ++x) {
                    Class<?> additionalInterface = var5[x];
                    this.advised.addInterface(additionalInterface);
                }
            }
			//验证检查是否有final修饰的方法等
            this.validateClassIfNecessary(proxySuperClass, classLoader);
            //cglib的创建代理类的逻辑
            Enhancer enhancer = this.createEnhancer();
            if (classLoader != null) {
                enhancer.setClassLoader(classLoader);
                if (classLoader instanceof SmartClassLoader && ((SmartClassLoader)classLoader).isClassReloadable(proxySuperClass)) {
                    enhancer.setUseCache(false);
                }
            }

            enhancer.setSuperclass(proxySuperClass);
            enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
            enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
            enhancer.setStrategy(new CglibAopProxy.ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
            Callback[] callbacks = this.getCallbacks(rootClass);
            Class<?>[] types = new Class[callbacks.length];

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

            enhancer.setCallbackFilter(new CglibAopProxy.ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
            enhancer.setCallbackTypes(types);
            //至此初始化完成enhancer,进入创建代理对象的逻辑
            return this.createProxyClassAndInstance(enhancer, callbacks);
        } catch (IllegalArgumentException | CodeGenerationException var9) {
            throw new AopConfigException("Could not generate CGLIB subclass of class [" + this.advised.getTargetClass() + "]: Common causes of this problem include using a final class or a non-visible class", var9);
        } catch (Throwable var10) {
            throw new AopConfigException("Unexpected AOP exception", var10);
        }
    }

 protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
        Class<?> proxyClass = enhancer.createClass();
        Object proxyInstance = null;
        if (objenesis.isWorthTrying()) {
            try {
            //在此处创建代理类
                proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
            } catch (Throwable var7) {
                logger.debug("Unable to instantiate proxy using Objenesis, falling back to regular proxy construction", var7);
            }
        }

        if (proxyInstance == null) {
            try {
                Constructor<?> ctor = this.constructorArgs != null ? proxyClass.getDeclaredConstructor(this.constructorArgTypes) : proxyClass.getDeclaredConstructor();
                ReflectionUtils.makeAccessible(ctor);
                proxyInstance = this.constructorArgs != null ? ctor.newInstance(this.constructorArgs) : ctor.newInstance();
            } catch (Throwable var6) {
                throw new AopConfigException("Unable to instantiate proxy using Objenesis, and regular proxy instantiation via default constructor fails as well", var6);
            }
        }

        ((Factory)proxyInstance).setCallbacks(callbacks);
        return proxyInstance;
    }

经过cglib增强之后,我们原来的helloService已经被“狸猫换太子”,变成了代理后的hello
Service对象。
在这里插入图片描述
至此,第二步也就完成了。

执行目标方法

我们来看一下当执行

helloService.sayHello();

的逻辑

在这里插入图片描述
此时我们原生的HelloService对象被封装成了上图的代理类,它包含了原来的对象以及生成的advisor。

 		/**
 		*cglilb的代理执行方法
 		*/
 		@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();

            Object var16;
            try {
            	//将proxy放入threadlocal中
                if (this.advised.exposeProxy) {
                    oldProxy = AopContext.setCurrentProxy(proxy);
                    setProxyContext = true;
                }
	
                target = targetSource.getTarget();
                //获取原来类的类型
                Class<?> targetClass = target != null ? target.getClass() : null;
                //获取增强器链
                List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
                Object retVal;
                if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
                    Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                    retVal = methodProxy.invoke(target, argsToUse);
                } else {
                    //把用所有的信息创建一个CglibMethodInvocation对象,顾名思义,它就是用来执行目标方法的
                    //proceed()执行目标方法,返回的是方法的返回值。
                    retVal = (new CglibAopProxy.CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy)).proceed();
                }

                retVal = CglibAopProxy.processReturnType(proxy, target, method, retVal);
                var16 = retVal;
            } finally {
            	//最后释放target
                if (target != null && !targetSource.isStatic()) {
                    targetSource.releaseTarget(target);
                }

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

            }

            return var16;
        }
@Nullable
    public Object proceed() thqirows Throwable {
    //这里用了一个很巧妙的判断方法,如过当前拦截器(增强器)的索引等于当前拦截器的数量-1时就执行切		
    //点方法
        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
            return this.invokeJoinpoint();
        } else {
        	//每执行一个增强器,当前的索引就+1
        	//获取每个执行器,判断类型并执行
            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 {
            //静态匹配 在这里执行
                return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
            }
        }
    }

在这里插入图片描述
来顺序来探究一下每个增强器都是怎么执行的
首先是Spring自动给我们放入的增强器,先来看看官方的解释。
将当前的MethodInvocation(拦截器)放到ThreadLocal中,来满足我们获取整个执行链上下文的需求

Interceptor that exposes the current MethodInvocation as a thread-local object. We occasionally need to do this; for example, when a pointcut (e.g. an AspectJ expression pointcut) needs to know the full invocation context.
Don't use this interceptor unless this is really necessary. Target objects should not normally know about Spring AOP, as this creates a dependency on Spring API. Target objects should be plain POJOs as far as possible.

If used, this interceptor will normally be the first in the interceptor chain.
public Object invoke(MethodInvocation mi) throws Throwable {
        //先获取之前的mi
        MethodInvocation oldInvocation = (MethodInvocation)invocation.get();
       //将当前的mi放入TreadLocal中
        invocation.set(mi);

        Object var3;
        try {
        	//执行mi的proceed
            var3 = mi.proceed();
        } finally {
            invocation.set(oldInvocation);
        }

        return var3;
    }

看看mi的proceed()的方法,没错,就是刚刚我们遍历执行拦截器链的方法,此时它的currentInterceptorIndex已经变成了0,但仍不等于interceptorsAndDynamicMethodMatchers.size() - 1,所以继续遍历执行下一个拦截器方法。

public Object proceed() thqirows Throwable {
    //这里用了一个很巧妙的判断方法,如过当前拦截器(增强器)的索引等于当前拦截器的数量-1时就执行切		
    //点方法
        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
            return this.invokeJoinpoint();
        } else {
        	//每执行一个增强器,当前的索引就+1
        	//获取每个执行器,判断类型并执行
            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 {
            //静态匹配 在这里执行
                return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
            }
        }
    }

来到第二个增强器 @AfterReturning,它先递归调用proceed,再反射执行我们在@AfterReturning中写的代码。

 public Object invoke(MethodInvocation mi) throws Throwable {
        Object retVal = mi.proceed();
        this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
        return retVal;
    }

此时currentInterceptorIndex为1依旧要执行拦截器方法,来到下一个After方法,可以看到它也是先执行proceed方法,并在finally语句块中执行。也就是说无论我们方法执行过程中抛没抛出异常,最后都会执行@After中的逻辑

public Object invoke(MethodInvocation mi) throws Throwable {
        Object var2;
        try {
            var2 = mi.proceed();
        } finally {
            this.invokeAdviceMethod(this.getJoinPointMatch(), (Object)null, (Throwable)null);
        }

        return var2;
    }

此时currentInterceptorIndex的值为2,依旧要执行拦截器方法,来到最后一个拦截器方法@Before,可以看到,它先反射执行了我们写的before逻辑,再去递归调用

public Object invoke(MethodInvocation mi) throws Throwable {
        this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
        return mi.proceed();
    }

当这次回到methodInvocarion的proceed()方法时,currentInterceptorIndex = 3,已经与interceptorsAndDynamicMethodMatchers.size() - 1相同了,接下来就要执行我们的目标方法sayHello()了。之后在依次执行刚刚入栈的增强方法,整个AOP也就完成了。

结语

本文中,我们中AOP中切面的创建,切面的织入,切面的执行三个步骤介绍了AOP的创建执行流程和内部原理。由于本人也是初学者,文中难免有错误与无法自洽的情况,还请多多指正。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值