Spring AOP 源码学习

基本概念

概念

      1.Aspect(切面): Aspect 声明类似于 Java 中的类声明,在 Aspect 中会包含着一些 Pointcut 以及相应的 Advice。

添加注解的类:
@Aspect
@Component
public class AopDemoServices

2.Joint point(连接点):(要拦截哪个个方法的表达式)表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它 joint point。
如:"execution(* com.ddd.spring.source.spring.aop.source.aop.CalcServiceImpl.before(..))"

3.Pointcut(切点):表示一组 joint point,这些 joint point 或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方。
如:@Pointcut("execution(* com.ddd.spring.source.spring.aop.source.aop.CalcServiceImpl.before(..))")

4.Advice(增强):(也可以称为通知)Advice 定义了在 Pointcut 里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执行的代码。
如:@Before(value = "pointCut()")
public void before(JoinPoint joinPoint)

5.Target(目标对象):织入 Advice 的目标对象.。

6.Weaving(织入):将 Aspect 和其他对象连接起来, 并创建 Adviced object 的过程(就是界面中的通知和目标对象的连接和执行称为织入)

 

通知(Advice)类型:

(1)前置通知(Before advice):在某连接点(join point)之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常)。

(2)返回后通知(After returning advice):在某连接点(join point)正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。

(3)抛出异常后通知(After throwing advice):在方法抛出异常退出时执行的通知。

(4)后通知(After (finally) advice):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。

(5)环绕通知(Around Advice):包围一个连接点(join point)的通知,如方法调用。这是最强大的一种通知类型。 环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结束执行。 环绕通知是最常用的一种通知类型。


概要图

类图

Spring AOP 原理 

Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。

Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理。JDK动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。JDK动态代理的核心是InvocationHandler接口和Proxy类。

如果目标类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成某个类的子类,注意,CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。

选择代理策略

Cglib和JDK代理

如果指定了@EnableAspectJAutoProxy(proxyTargetClass = true) 则使用Cglib代理,否则如果目标类实现了接口,则使用JDK动态代理技术,否则使用Cglib来生成代理。

@EnableAspectJAutoProxy

1.通过@EnableAspectJAutoProxy注解的Import注解向IOC容器注册了AnnotationAwareAspectJAutoProxyCreator

@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
//导入了AspectJAutoProxyRegistrar
AspectJAutoProxyRegistrar:向IOC容器注册了AnnotationAwareAspectJAutoProxyCreator 
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
通过ImportBeanDefinitionRegistrar注册

//添加bean  AnnotationAwareAspectJAutoProxyCreator
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);

2.在Bean的后置处理器里面通过AspectJAwareAdvisorAutoProxyCreator的父类创建代理对象

在Spring Bean处理器的AspectJAwareAdvisorAutoProxyCreator创建的代理对象

 

3.后置处理器BeanPostProcessor调用AbstractAutoProxyCreator创建代理对象

 

调用代理类图

分析调用逻辑之前先上类图,看看Spring 中主要的AOP 组件:

代理对象生成源码

getBean——>AbstractBeanFactory:doGetBean->
AbstractAutowireCapableBeanFactory:createBean->doCreateBean->
initializeBean:applyBeanPostProcessorsAfterInitialization->AbstractAutoProxyCreator :postProcessAfterInitialization
wrapIfNecessary:createProxy->ProxyCreatorSupport:createAopProxy  
 
 protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
        BeanWrapper instanceWrapper = null;
       // 删除无关代码
        Object exposedObject = bean;

        try {
            this.populateBean(beanName, mbd, instanceWrapper);
            // 创建代理入口,后置处理器 创建代理对象
            exposedObject = this.initializeBean(beanName, exposedObject, mbd);
        } catch (Throwable var18) {
            if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
                throw (BeanCreationException)var18;
            }
 
    }

 AbstractAutoProxyCreator

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

        return bean;
    }
 

 protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        } else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        } else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
             //这里来查找通知 用于确定是否需要创建代理对象 (根据切面的切入点判断当前类是否有通知)
            Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
             //
            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;
        }
    }
AbstractAutoProxyCreator

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

        Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
        proxyFactory.addAdvisors(advisors);
        proxyFactory.setTargetSource(targetSource);
        this.customizeProxyFactory(proxyFactory);
        proxyFactory.setFrozen(this.freezeProxy);
        if (this.advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }

       //从工厂里面获取proxyFactory
        return proxyFactory.getProxy(this.getProxyClassLoader());
    }

//ProxyFactory
  public Object getProxy(@Nullable ClassLoader classLoader) {
        return this.createAopProxy().getProxy(classLoader);
    }
//ProxyCreatorSupport
  protected final synchronized AopProxy createAopProxy() {
        if (!this.active) {
            this.activate();
        }

        return this.getAopProxyFactory().createAopProxy(this);
    }
//DefaultAopProxyFactory
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
   //判断我们是否前置指定使用 cglib代理的 ProxyTargetClass
   if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
      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.");
      }
      //所有targetCalss是接口 使用jdk
      if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
         return new JdkDynamicAopProxy(config);
      }
      //动态代理
      return new ObjenesisCglibAopProxy(config);
   }
   else {
      return new JdkDynamicAopProxy(config);
   }
}
//JdkDynamicAopProxy 使用JDK自带的创建代理对象
public Object getProxy(@Nullable ClassLoader classLoader) { 
 Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
 this.findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
          //调用实际调用创建代理对象
        return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
    }
//CglibAopProxy 
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
      try {
      Class<?> rootClass = this.advised.getTargetClass();
      
      // Configure CGLIB Enhancer...
      Enhancer enhancer = 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 ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));

      Callback[] callbacks = getCallbacks(rootClass);
      Class<?>[] types = new Class<?>[callbacks.length];
      for (int x = 0; x < types.length; x++) {
         types[x] = callbacks[x].getClass();
      }
      // fixedInterceptorMap only populated at this point, after getCallbacks call above
      enhancer.setCallbackFilter(new ProxyCallbackFilter(
            this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
      enhancer.setCallbackTypes(types);

      // Generate the proxy class and create a proxy instance.
      return createProxyClassAndInstance(enhancer, callbacks);
   }
//ObjenesisCglibAopProxy
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;
}
代理对象生成源码

切面是如何织入的?

InvocationHandler 是JDK 动态代理的核心,生成的代理对象的方法调用都会委托到InvocationHandler.invoke()方法。而从JdkDynamicAopProxy 的源码我们可以看到这个类其实也实现了InvocationHandler,Spring AOP 是如何织入切面的,直接上源码看invoke()方法: 

@Override
    @Nullable
    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 {
            //eqauls()方法,具目标对象未实现此方法
            if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
                // The target does not implement the equals(Object) method itself.
                return equals(args[0]);
            }
            //hashCode()方法,具目标对象未实现此方法
            else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
                // The target does not implement the hashCode() method itself.
                return hashCode();
            }
            else if (method.getDeclaringClass() == DecoratingProxy.class) {
                // There is only getDecoratedClass() declared -> dispatch to proxy config.
                return AopProxyUtils.ultimateTargetClass(this.advised);
            }
            //Advised接口或者其父接口中定义的方法,直接反射调用,不应用通知
            else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
                    method.getDeclaringClass().isAssignableFrom(Advised.class)) {
                // Service invocations on ProxyConfig with the proxy config...
                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);

            // Get the interception chain for this method.
            //获取可以应用到此方法上的Interceptor列表
            List<Object> 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.
            //如果没有可以应用到此方法的通知(Interceptor),此直接反射调用 method.invoke(target, args)
            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...
                //创建MethodInvocation
                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);
            }
        }
    }
JdkDynamicAopProxy.invoke()

主要实现思路可以简述为:首先获取应用到此方法上的通知链(Interceptor Chain)。如果有通知,则应用通知,并执行JoinPoint;如果没有通知,则直接反射执行JoinPoint。这里的关键是通知链是如何获取的以及它又是如何执行的呢?首先,从上面的代码可以看到,通知链是通过Advised.getInterceptorsAndDynamicInterceptionAdvice()这个方法来获取的,我们来看下这个方法的实现逻辑: 

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method Method, @Nullable Class<?> targetClass)
{
MethodCacheKey cacheKey = new MethodCacheKey(Method);
List<Object> cached = this.MethodCache.get(cacheKey);
if (cached == null) {
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, Method, targetClass);
this.MethodCache.put(cacheKey, cached);
}
return cached;
}
getInterceptorsAndDynamicInterceptionAdvice

通过上面的源码我们可以看到, 实际获取通知的实现逻辑其实是由AdvisorChainFactory的getInterceptorsAndDynamicInterceptionAdvice()方法来完成的,且获取到的结果会被缓存。下面来分析getInterceptorsAndDynamicInterceptionAdvice()方法的实现

* 从提供的配置实例config中获取advisor列表,遍历处理这些advisor.如果是IntroductionAdvisor,
     * 则判断此Advisor能否应用到目标类targetClass上.如果是PointcutAdvisor,则判断
     * 此Advisor能否应用到目标方法method上.将满足条件的Advisor通过AdvisorAdaptor转化成Interceptor列表返回.
     
*/
    @Override
    public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
            Advised config, Method method, @Nullable Class<?> targetClass) {

        // This is somewhat tricky... We have to process introductions first,
        // but we need to preserve order in the ultimate list.
        List<Object> interceptorList = new ArrayList<>(config.getAdvisors().length);
        Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
        //查看是否包含IntroductionAdvisor
        boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
        //这里实际上注册一系列AdvisorAdapter,用于将Advisor转化成MethodInterceptor
        AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();

        for (Advisor advisor : config.getAdvisors()) {
            if (advisor instanceof PointcutAdvisor) {
                // Add it conditionally.
                PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
                if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
                
                    //将Advisor转化成Interceptor
                    MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
                    //检查当前advisor的pointcut是否可以匹配当前方法
                    MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
                    if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
                        if (mm.isRuntime()) {
                            // Creating a new object instance in the getInterceptors() method
                            // isn't a problem as we normally cache created chains.
                            for (MethodInterceptor interceptor : interceptors) {
                                interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
                            }
                        }
                        else {
                            interceptorList.addAll(Arrays.asList(interceptors));
                        }
                    }
                }
            }
            else if (advisor instanceof IntroductionAdvisor) {
                IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
                if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
                    Interceptor[] interceptors = registry.getInterceptors(advisor);
                    interceptorList.addAll(Arrays.asList(interceptors));
                }
            }
            else {
                Interceptor[] interceptors = registry.getInterceptors(advisor);
                interceptorList.addAll(Arrays.asList(interceptors));
            }
        }

        return
 interceptorList;
    }
getInterceptorsAndDynamicInterceptionAdvice

这个方法执行完成后,Advised 中配置能够应用到连接点(JoinPoint)或者目标类(Target Object)的Advisor 全部被转化成了MethodInterceptor,接下来我们再看下得到的拦截器链是怎么起作用的。

//如果没有可以应用到此方法的通知(Interceptor),此直接反射调用 method.invoke(target, args)
            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...
                //创建MethodInvocation
                invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
                // Proceed to the joinpoint through the interceptor chain.
                retVal = invocation.proceed();
            }
invoke

从这段代码可以看出, 如果得到的拦截器链为空, 则直接反射调用目标方法, 否则创建MethodInvocation,调用其proceed()方法,触发拦截器链的执行,来看下具体代码:

    @Override
    @Nullable
    public Object proceed() throws Throwable {
        //    We start with an index of -1 and increment early.
        //如果Interceptor执行完了,则执行joinPoint
        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
            return invokeJoinpoint();
        }

        Object interceptorOrInterceptionAdvice =
                this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
        //如果要动态匹配joinPoint
        if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
            // Evaluate dynamic method matcher here: static part will already have
            // been evaluated and found to match.
            InterceptorAndDynamicMethodMatcher dm =
                    (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
            //动态匹配:运行时参数是否满足匹配条件
            if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
                return dm.interceptor.invoke(this);
            }
            else {
                // Dynamic matching failed.
                // Skip this interceptor and invoke the next in the chain.
                //动态匹配失败时,略过当前Intercetpor,调用下一个Interceptor
                return proceed();
            }
        }
        else {
            // It's an interceptor, so we just invoke it: The pointcut will have
            // been evaluated statically before this object was constructed.
            //执行当前Intercetpor
            return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
        }
    }
ReflectiveMethodInvocation.proceed()

至此,通知链就完美地形成了。我们再往下来看invokeJoinpointUsingReflection()方法,其实就是反射调用:

//    
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
            return invokeJoinpoint();
        }

@Nullable
    public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args)
            throws Throwable {

        // Use reflection to invoke the method.
        try {
            ReflectionUtils.makeAccessible(method);
                         //反射调用
            return method.invoke(target, args);
        }
         
    }    
invokeJoinpointUsingReflection,反射调用

 

 

如何触发通知?

在为AopProxy 代理对象配置拦截器的实现中,有一个取得拦截器的配置过程,这个过程是由DefaultAdvisorChainFactory 实现的,这个工厂类负责生成拦截器链,在它getInterceptorsAndDynamicInterceptionAdvice 方法中,有一个适配器和注册过程,通过配置Spring 预先设计好的拦截器,Spring 加入了它对AOP 实现的处理。GlobalAdvisorAdapterRegistry 负责拦截器的适配和注册过程。

//JdkDynamicAopProxy.invoke
//    List<Object> chain = //this.advised.getInterceptorsAndDynamicInterceptionAdvice(met//hod, targetClass);

//getInterceptorsAndDynamicInterceptionAdvice
//    AdvisorAdapterRegistry registry = //GlobalAdvisorAdapterRegistry.getInstance();
public abstract class GlobalAdvisorAdapterRegistry {

    /**
     * Keep track of a single instance so we can return it to classes that request it.
     */
    private static AdvisorAdapterRegistry instance = new DefaultAdvisorAdapterRegistry();

    /**
     * Return the singleton {@link DefaultAdvisorAdapterRegistry} instance.
     */
    public static AdvisorAdapterRegistry getInstance() {
        return instance;
    }

    /**
     * Reset the singleton {@link DefaultAdvisorAdapterRegistry}, removing any
     * {@link AdvisorAdapterRegistry#registerAdvisorAdapter(AdvisorAdapter) registered}
     * adapters.
     */
    static void reset() {
        instance = new DefaultAdvisorAdapterRegistry();
    }
GlobalAdvisorAdapterRegistry

而GlobalAdvisorAdapterRegistry 起到了适配器和单例模式的作用,提供了一个DefaultAdvisorAdapterRegistry,它用来完成各种通知的适配和注册过程。

public DefaultAdvisorAdapterRegistry() {
        registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
        registerAdvisorAdapter(new AfterReturningAdviceAdapter());
        registerAdvisorAdapter(new ThrowsAdviceAdapter());
    }
DefaultAdvisorAdapterRegistry

DefaultAdvisorAdapterRegistry 设置了一系列的是配置,正是这些适配器的实现,为Spring AOP 提供了编织能力Spring AOP 为了实现advice 的织入,设计了特定的拦截器对这些功能进行了封装。看MethodBeforeAdviceInterceptor 如何完成封装的?如:MethodBeforeAdviceAdapter

    @Override
    public MethodInterceptor getInterceptor(Advisor advisor) {
        MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
        return new MethodBeforeAdviceInterceptor(advice);
    }
MethodInterceptor

可以看到,invoke 方法中,首先触发了advice 的before 回调,然后才是proceed。

目标对象的增强是通过拦截器实现的

 

通知类

通知实现类

  1. ExposeInvocationInterceptor

  2. AspectJAfterThrowingAdvice

  3. AfterReturningAdviceInterceptor

  4. AspectJAfterAdvice  

  5. MethodBeforeAdviceInterceptor before

  6. MethodInterceptor 重写invoke 方法实现  环绕通知,around

通知实现类源码

AspectJAfterThrowingAdvice

 public Object invoke(MethodInvocation mi) throws Throwable {
        try {
        //进入循环的下一个 条件 AfterReturningAdviceInterceptor
            return mi.proceed();
        } catch (Throwable var3) {
            if (this.shouldInvokeOnThrowing(var3)) {
                this.invokeAdviceMethod(this.getJoinPointMatch(), (Object)null, var3);
            }

            throw var3;
        }
    }
AspectJAfterThrowingAdvice

AfterReturningAdviceInterceptor

  public Object invoke(MethodInvocation mi) throws Throwable {
        //指向下个 切面方法,又回到1 开始执行下一个 AspectJAfterAdvice
        Object retVal = mi.proceed();
        this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
        return retVal;
    }
AfterReturningAdviceInterceptor

AspectJAfterAdvice

  public Object invoke(MethodInvocation mi) throws Throwable {
        Object var2;
        try {
        //指向下个 切面方法,又回到1 开始执行下一个 MethodBeforeAdviceInterceptor
            var2 = mi.proceed();
        } finally {
            this.invokeAdviceMethod(this.getJoinPointMatch(), (Object)null, (Throwable)null);
        }

        return var2;
    }
AspectJAfterAdvice

MethodBeforeAdviceInterceptor

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

AspectJMethodBeforeAdvice

    @Override
    public void before(Method method, Object[] args, @Nullable Object target) throws Throwable {
        invokeAdviceMethod(getJoinPointMatch(), null, null);
    }
AspectJMethodBeforeAdvice

 

posted @ 2021-02-05 16:33  暖暖-木木  阅读(94)  评论(0编辑  收藏  举报