Spring AOP源码流程解析

Spring 实现AOP的几个核心工作流程如下

1、核心工具类的创建

开启@EnableAspectJAutoProxy 注解的时候,实际上是把AOP核心工具类AnnotationAwareAspectJAutoProxyCreator添加到IOC容器的过程,这个类负责切面通知类的解析,并且负责代理对象的创建逻辑。

2、加载切面和通知

加载Aspect 的切面类,解析切面类(Aspect)对应的通知方法(advice) 和 切面规则(PointCut)。

3、创建代理Bean

IOC创建Bean(target)的时候和所有切面对象的PointCut匹配,PointCut命中的话则需要创建代理对象(Proxy),并且通过getBean()返回的是代理对象(Proxy)。

4、执行代理对象的方法。

根据代用的方法(Method)找到所有匹配的通知方法(Advice),这里会把符合调用的通知方法(advice)按照顺序(前置、后置、环绕、返回、异常)组成一个调用链(List),然后通过proced()方法依次执行调用链里面的方法。

1、创建AnnotationAwareAspectJAutoProxyCreator对象

使用AOP的时候我们都会通过一个注解(@EnableAspectJAutoProxy),或者在配置文件增加配置来开启AOP功能,而这个配置其实就是是否需要注册一个名叫AnnotationAwareAspectJAutoProxyCreator到IOC容器中去,如果没有开启这个配置的话,那么IOC容器就不会创建这个对象,那么也就无法扫描到我们的Aspect相关的切面类。

首先我们需要看AnnotationAwareAspectJAutoProxyCreator 类的关系结构图,这有助于我们后面理解AnnotationAwareAspectJAutoProxyCreator 的创建时机和执行时机。

1578364553461.png

(1)从@EnableAspectJAutoProxy注解源码我们可以看到,它引入了一个AspectJAutoProxyRegistrar的类。

decoration-color: initial;">@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
 //省略代码
}

(2)然后AspectJAutoProxyRegistrar类实现了ImportBeanDefinitionRegistrar 接口。

熟悉IOC容器的话应该能理解实现了在ImportBeanDefinitionRegistrar .registerBeanDefinitions()方法中可以动态的往容器里面添加Bean的配置(BeanDefinition)信息,最终其实就是动态的往容器里面添加Bean。

ImportBeanDefinitionRegistrar .registerBeanDefinitions()源码

public void registerBeanDefinitions(
 AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
​
 //注册AnnotationAwareAspectJAutoProxyCreator到IOC容器,此Bean会在registerBeanPostProcessors时创建
 AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
 //省略代码
 }

(3)在ImportBeanDefinitionRegistrar .registerBeanDefinitions()方法里面会调用AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry) 方法注册一个bean id为“org.springframework.aop.config.internalAutoProxyCreator” 配置信息(BeanDefinition)到IOC容器。

AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

最终调用AopConfigUtils.registerOrEscalateApcAsRequired方法()

private static BeanDefinition registerOrEscalateApcAsRequired(Class cls, BeanDefinitionRegistry registry,
 @Nullable Object source) {
​
 Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
​
 if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
 BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
 if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
 int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
 int requiredPriority = findPriorityForClass(cls);
 if (currentPriority < requiredPriority) {
 apcDefinition.setBeanClassName(cls.getName());
 }
 }
 return null;
 }
​
 RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
 beanDefinition.setSource(source);
 //定义顺序
 beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
 beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
 registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
 return beanDefinition;
 }

(4)在IOC容器启动时候,会加载所有的BeanDefinition来实例化Bean, AnnotationAwareAspectJAutoProxyCreator 类实现了Ordered接口和 BeanPostProcessor接口,所以AnnotationAwareAspectJAutoProxyCreator 会优先于其他的Bean先创建,IOC容器会在容器刷新的时候就进行Bean的创建。

AbstractApplicationContext.refresh()

调用

AbstractApplicationContext.registerBeanPostProcessors()

最终调用

PostProcessorRegistrationDelegate.registerBeanPostProcessors()

因为实现了Ordered接口,所以会执行下面代码逻辑

public static void registerBeanPostProcessors(
 ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
​
 //...省略代码

 // 然后注册实现了Ordered接口的BeanPostProcessors
 List orderedPostProcessors = new ArrayList<>();
 for (String ppName : orderedPostProcessorNames) {
 //此处优先其它普通bean之前创建实现了Ordered接口的Bean对象
 BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
 orderedPostProcessors.add(pp);
 if (pp instanceof MergedBeanDefinitionPostProcessor) {
 internalPostProcessors.add(pp);
 }
 }

 //...省略代码

 }

AnnotationAwareAspectJAutoProxyCreator整个配置加载和bean创建过程

1578992420642.png

2、切面和通知加载阶段

因为在创建代理的时候需要对所有我们定义的Aspect 切面类进行匹配,匹配的Aspect 我们才会创建代理,否则的话就代表对象不需要进行代理。而进行匹配前我们势必需要把IOC容器所有的Aspect和对应的Advice都加载好解析并缓存好,那么我们在创建的代理的时候就直接拿过来进行匹配使用了。

主要逻辑:

(1)、创建代理时候会从缓存的数据里面取得所有与当前对象匹配的Advice.

(2)、当缓存里面不存在时候再扫描所有的IOC容器bean,如果为Aspect类型对象则解析保存到缓存中。

方法调用流程如下:

1579016117466.png

入口:AbstractAutoProxyCreator.postProcessBeforeInstantiation()方法

public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {
 //省略代码......
 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
 //省略代码......
 return null;
 }

调用 AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(),查找符合条件的Advisor

protected Object[] getAdvicesAndAdvisorsForBean(Class beanClass, String beanName, @Nullable TargetSource targetSource) {
 List advisors = findEligibleAdvisors(beanClass, beanName);
 if (advisors.isEmpty()) {
 return DO_NOT_PROXY;
 }
 return advisors.toArray();
 }

调用AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(),拿到所有Advisor 然后和当前对象进行匹配

findEligibleAdvisors(Class beanClass, String beanName) {
 //获取到所有切面通知方法
 List candidateAdvisors = findCandidateAdvisors();
 //匹配到符合当前对象的通知方法
 List eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
 extendAdvisors(eligibleAdvisors);
 //对通知方法集合进行排序
 if (!eligibleAdvisors.isEmpty()) {
 eligibleAdvisors = sortAdvisors(eligibleAdvisors);
 }
 return eligibleAdvisors;
 }

调用AbstractAdvisorAutoProxyCreator.findCandidateAdvisors()

 findCandidateAdvisors() {
 Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
 return this.advisorRetrievalHelper.findAdvisorBeans();
 }

调用BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans(),扫描容器的bean ,如果是Advisor 类型的都进行解析添加到缓存

public List findAdvisorBeans() {
 // Determine list of advisor bean names, if not cached already.
 String[] advisorNames = null;
 synchronized (this) {
 advisorNames = this.cachedAdvisorBeanNames;
 if (advisorNames == null) {
 // Do not initialize FactoryBeans here: We need to leave all regular beans
 // uninitialized to let the auto-proxy creator apply to them!
 advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
 this.beanFactory, Advisor.class, true, false);
 this.cachedAdvisorBeanNames = advisorNames;
 }
 }
 if (advisorNames.length == 0) {
 return new LinkedList<>();
 }
​
 List advisors = new LinkedList<>();
 for (String name : advisorNames) {
 if (isEligibleBean(name)) {
 if (this.beanFactory.isCurrentlyInCreation(name)) {
 if (logger.isDebugEnabled()) {
 logger.debug("Skipping currently created advisor '" + name + "'");
 }
 }
 else {
 try {
 advisors.add(this.beanFactory.getBean(name, Advisor.class));
 }
 catch (BeanCreationException ex) {
 Throwable rootCause = ex.getMostSpecificCause();
 if (rootCause instanceof BeanCurrentlyInCreationException) {
 BeanCreationException bce = (BeanCreationException) rootCause;
 String bceBeanName = bce.getBeanName();
 if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
 if (logger.isDebugEnabled()) {
 logger.debug("Skipping advisor '" + name +
 "' with dependency on currently created bean: " + ex.getMessage());
 }
 // Ignore: indicates a reference back to the bean we're trying to advise.
 // We want to find advisors other than the currently created bean itself.
 continue;
 }
 }
 throw ex;
 }
 }
 }
 }
 return advisors;
 }

3、代理创建阶段

当IOC容器创建每个对象(doCreateBean)的时候,会在原对象创建完(createBeanInstance)并且依赖注入完之后(populateBean)之后调用一个初始化对象的方法(initializeBean),initializeBean方法里面会执行所有实现了BeanPostProcessor 接口的postProcessAfterInitialization()方法;

而我们在上面已经创建了的AOP核心类他就实现了BeanPostProcessor接口,所以这里所有的Bean都会执行AbstractAutoProxyCreator.postProcessAfterInitialization()逻辑;在这个方法里开始为我们的原生对象生成对应的代理对象。

调用流程如下:

1579015399542.png

在AbstractAutowireCapableBeanFactory.doCreateBean()方法里调用initializeBean()进行对象的初始化。

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
 throws BeanCreationException {

 //省略代码...........

 //==创建bean实例 new Object()
 instanceWrapper = createBeanInstance(beanName, mbd, args);

 //===依赖注入
 populateBean(beanName, mbd, instanceWrapper);
​
 //===对象生成后执行BeanPostProcessor、init、Aware 相关逻辑, 返回最终暴露出去的bean对象
 exposedObject = initializeBean(beanName, exposedObject, mbd);
 }
 //省略代码...........

应用所有后置处理器

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
 //省略代码....
​
 Object wrappedBean = bean;
 if (mbd == null || !mbd.isSynthetic()) {
 //==执行bean初始化之前的业务逻辑 (此处会执行实现了PostProcessors接口的对象逻辑)
 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
 }
​
 //省略代码....
 return wrappedBean;
 }

遍历所有BeanPostProcessor调用对应的postProcessBeforeInitialization方法

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
 throws BeansException {
 Object result = existingBean;
 for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
 Object current = beanProcessor.postProcessBeforeInitialization(result, beanName);
 if (current == null) {
 return result;
 }
 result = current;
 }
 return result;
 }

调用AbstractAutoProxyCreator.postProcessAfterInitialization()方法

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
        if (bean != null) {
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            if (!this.earlyProxyReferences.contains(cacheKey)) {
                //==创建代理对象
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }

调用AbstractAutoProxyCreator.wrapIfNecessary()开始创建代理

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        //对应bean是否已经生成了代理
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        }

        //无需增强
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        }

        //如果是aop的工具类则直接返回,比如 advice pointcut advisor
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }

        //获取所有的拦截通知
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        // 有符合条件的的切面通知则则创建代理
        if (specificInterceptors != DO_NOT_PROXY) {
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
            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;
    }

调用AbstractAutoProxyCreator.createProxy()创建代理对象

protected Object createProxy(Class beanClass, @Nullable String beanName,
            @Nullable Object[] specificInterceptors, TargetSource targetSource) {
        BeanNameConstants.contansBeanName(beanName);
        if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
            AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
        }

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

        if (!proxyFactory.isProxyTargetClass()) {
            if (shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            }
            else {
                evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }

        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
        proxyFactory.addAdvisors(advisors);
        proxyFactory.setTargetSource(targetSource);
        customizeProxyFactory(proxyFactory);

        proxyFactory.setFrozen(this.freezeProxy);
        if (advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }

        return proxyFactory.getProxy(getProxyClassLoader());
    }

调用ProxyFactory.getProxy()来决定是使JDK、或者CGlib来创建代理

public Object getProxy(@Nullable ClassLoader classLoader) {
        //使用JDK、或者CGlib创建代理
        return createAopProxy().getProxy(classLoader);
    }

4、代理执行阶段

这里以JDK生成的动态代理为例,当代理对象执行对应的方法后统一都会进入JdkDynamicAopProxy.invoke()方法

这里主要是获取到当前代理对象的所有匹配的Advice,然后把所有的Advice按照顺序放到List集合里组成一个调用链,然后调用链依次调用proceed()方法执行对应通知和对象方法逻辑。

调用流程如下:

1579015360442.png

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        MethodInvocation invocation;
        Object oldProxy = null;
        boolean setProxyContext = false;

        TargetSource targetSource = this.advised.targetSource;
        Object target = null;

        try {
            if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
                // 如果是调用equals 方法则执行equals的逻辑
                return equals(args[0]);
            }
            else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
                // 如果是调用hashCode方法,则执行hashCode的逻辑
                return hashCode();
            }
            else if (method.getDeclaringClass() == DecoratingProxy.class) {
                // 如果当前方法是Spring织入的DecoratingProxy接口中的方法,则返回目标对象的Class类型
                return AopProxyUtils.ultimateTargetClass(this.advised);
            }
            else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
                    method.getDeclaringClass().isAssignableFrom(Advised.class)) {
                // 通过反射调用invoke
                return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
            }

            Object retVal;

            if (this.advised.exposeProxy) {
                // Make invocation available if necessary.
                oldProxy = AopContext.setCurrentProxy(proxy);
                setProxyContext = true;
            }

            // Get as late as possible to minimize the time we "own" the target,
            // in case it comes from a pool.
            target = targetSource.getTarget();
            Class targetClass = (target != null ? target.getClass() : null);

            // ==获得代理对象的方法执行链
            List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

            // Check whether we have any advice. If we don't, we can fallback on direct
            // reflective invocation of the target, and avoid creating a MethodInvocation.
            if (chain.isEmpty()) {
                // We can skip creating a MethodInvocation: just invoke the target directly
                // Note that the final invoker must be an InvokerInterceptor so we know it does
                // nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
                Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
            }
            else {
                // We need to create a method invocation...
                invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
                // Proceed to the joinpoint through the interceptor chain.
                retVal = invocation.proceed();
            }

            // Massage return value if necessary.
            Class returnType = method.getReturnType();
            if (retVal != null && retVal == target &&
                    returnType != Object.class && returnType.isInstance(proxy) &&
                    !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
                // Special case: it returned "this" and the return type of the method
                // is type-compatible. Note that we can't help if the target sets
                // a reference to itself in another returned object.
                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);
            }
            return retVal;
        }
        finally {
            if (target != null && !targetSource.isStatic()) {
                // Must have come from TargetSource.
                targetSource.releaseTarget(target);
            }
            if (setProxyContext) {
                // Restore old proxy.
                AopContext.setCurrentProxy(oldProxy);
            }
        }
    }







你可能感兴趣的:(Spring AOP源码流程解析)