Spring AOP 源码解析

以前写过 IOC 的源码分析,那篇文章真的有点长,看完须要点耐心。不少读者但愿能写一写 Spring AOP 的源码分析文章,这样读者看完 IOC + AOP 也就对 Spring 会有比较深的理解了。今天终于成文了,可能不少读者早就再也不等待了,不过主要为了后来者吧。html

本文不会像 IOC 源码分析那篇文章同样,很具体地分析每一行 Spring AOP 的源码,目标读者是已经知道 Spring IOC 源码是怎么回事的读者,由于 Spring AOP 终归是依赖于 IOC 容器来管理的。java

Spring AOP 的源码并不简单,由于它多,因此阅读源码最好就是找到一个分支,追踪下去。本文定位为蜻蜓点水,看个大概,不具体到每个细节。spring

前言

这一节,咱们先来"猜猜" Spring 是怎么实现 AOP 的。数组

在 Spring 的容器中,咱们面向的对象是一个个的 bean 实例,bean 是什么?咱们能够简单理解为是 BeanDefinition 的实例,Spring 会根据 BeanDefinition 中的信息为咱们生产合适的 bean 实例出来。bash

当咱们须要使用 bean 的时候,经过 IOC 容器的 getBean(…) 方法从容器中获取 bean 实例,只不过大部分的场景下,咱们都用了依赖注入,因此不多手动调用 getBean(...) 方法。app

Spring AOP 的原理很简单,就是动态代理,它和 AspectJ 不同,AspectJ 是直接修改掉你的字节码。maven

代理模式很简单,接口 + 真实实现类 + 代理类,其中 真实实现类 和 代理类 都要实现接口,实例化的时候要使用代理类。因此,Spring AOP 须要作的是生成这么一个代理类,而后替换掉真实实现类来对外提供服务。ide

替换的过程怎么理解呢?在 Spring IOC 容器中很是容易实现,就是在 getBean(…) 的时候返回的其实是代理类的实例,而这个代理类咱们本身没写代码,它是 Spring 采用 JDK Proxy 或 CGLIB 动态生成的。oop

getBean(…) 方法用于查找或实例化容器中的 bean,这也是为何 Spring AOP 只能做用于 Spring 容器中的 bean 的缘由,对于不是使用 IOC 容器管理的对象,Spring AOP 是无能为力的。源码分析

本文使用的调试代码

阅读源码很好用的一个方法就是跑代码来调试,由于本身一行一行地看的话,比较枯燥,并且不免会漏掉一些东西。

下面,咱们先准备一些简单的调试用的代码。

首先先定义两个 Service 接口:

// OrderService.java
public interface OrderService {

    Order createOrder(String username, String product);

    Order queryOrder(String username);
}
// UserService.java
public interface UserService {

    User createUser(String firstName, String lastName, int age);

    User queryUser();
}
复制代码

而后,分别来一个接口实现类:

// OrderServiceImpl.java
public class OrderServiceImpl implements OrderService {

    @Override
    public Order createOrder(String username, String product) {
        Order order = new Order();
        order.setUsername(username);
        order.setProduct(product);
        return order;
    }

    @Override
    public Order queryOrder(String username) {
        Order order = new Order();
        order.setUsername("test");
        order.setProduct("test");
        return order;
    }
}

// UserServiceImpl.java
public class UserServiceImpl implements UserService {

    @Override
    public User createUser(String firstName, String lastName, int age) {
        User user = new User();
        user.setFirstName(firstName);
        user.setLastName(lastName);
        user.setAge(age);
        return user;
    }

    @Override
    public User queryUser() {
        User user = new User();
        user.setFirstName("test");
        user.setLastName("test");
        user.setAge(20);
        return user;
    }
}
复制代码

写两个 Advice:

public class LogArgsAdvice implements MethodBeforeAdvice {

    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("准备执行方法: " + method.getName() + ", 参数列表:" + Arrays.toString(args));
    }
}
复制代码
public class LogResultAdvice implements AfterReturningAdvice {

    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target)
            throws Throwable {
        System.out.println(method.getName() + "方法返回:" + returnValue);
    }
}
复制代码

配置一下:

咱们这边使用了前面文章介绍的配置 Advisor 的方式,咱们回顾一下。

每一个 advisor 内部持有 advice 实例,advisor 负责匹配,内部的 advice 负责实现拦截处理。配置了各个 advisor 后,配置 DefaultAdvisorAutoProxyCreator 使得全部的 advisor 配置自动生效。

启动:

public class SpringAopSourceApplication {

   public static void main(String[] args) {

      // 启动 Spring 的 IOC 容器
      ApplicationContext context = new ClassPathXmlApplicationContext("classpath:DefaultAdvisorAutoProxy.xml");

      UserService userService = context.getBean(UserService.class);
      OrderService orderService = context.getBean(OrderService.class);

      userService.createUser("Tom", "Cruise", 55);
      userService.queryUser();

      orderService.createOrder("Leo", "随便买点什么");
      orderService.queryOrder("Leo");
   }
}
复制代码

输出:

准备执行方法: createUser, 参数列表:[Tom, Cruise, 55]
queryUser方法返回:User{firstName='test', lastName='test', age=20, address='null'}
准备执行方法: createOrder, 参数列表:[Leo, 随便买点什么]
queryOrder方法返回:Order{username='test', product='test'}
复制代码

从输出结果,咱们能够看到:

LogArgsAdvice 做用于 UserService#createUser(…) 和 OrderService#createOrder(…) 两个方法;

LogResultAdvice 做用于 UserService#queryUser() 和 OrderService#queryOrder(…) 两个方法;

下面的代码分析中,咱们将基于这个简单的例子来介绍。

IOC 容器管理 AOP 实例

本节介绍 Spring AOP 是怎么做用于 IOC 容器中的 bean 的。

Spring AOP 的使用介绍 那篇文章已经介绍过 DefaultAdvisorAutoProxyCreator 类了,它能实现自动将全部的 advisor 生效。

咱们来追踪下 DefaultAdvisorAutoProxyCreator 类,看看它是怎么一步步实现的动态代理。而后在这个基础上,咱们再简单追踪下 @AspectJ 配置方式下的源码实现。

首先,先看下 DefaultAdvisorAutoProxyCreator 的继承结构:

咱们能够发现,DefaultAdvisorAutoProxyCreator 最后竟然是一个 BeanPostProcessor,在 Spring IOC 源码分析的时候说过,BeanPostProcessor 的两个方法,分别在 init-method 的先后获得执行。

public interface BeanPostProcessor {
    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
复制代码

这里再贴一下 IOC 的源码,咱们回顾一下:

// AbstractAutowireCapableBeanFactory

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

    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        // 1. 建立实例
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    ...

    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
        // 2. 装载属性
        populateBean(beanName, mbd, instanceWrapper);
        if (exposedObject != null) {
            // 3. 初始化
            exposedObject = initializeBean(beanName, exposedObject, mbd);
        }
    }
    ...
}
复制代码

在上面第 3 步 initializeBean(...) 方法中会调用 BeanPostProcessor 中的方法,以下:

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
   ...
   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
      // 1. 执行每个 BeanPostProcessor 的 postProcessBeforeInitialization 方法
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }

   try {
      // 调用 bean 配置中的 init-method="xxx"
      invokeInitMethods(beanName, wrappedBean, mbd);
   }
   ...
   if (mbd == null || !mbd.isSynthetic()) {
      // 咱们关注的重点是这里!!!
      // 2. 执行每个 BeanPostProcessor 的 postProcessAfterInitialization 方法
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }
   return wrappedBean;
}
复制代码

也就是说,Spring AOP 会在 IOC 容器建立 bean 实例的最后对 bean 进行处理。其实就是在这一步进行代理加强。

咱们回过头来,DefaultAdvisorAutoProxyCreator 的继承结构中,postProcessAfterInitialization() 方法在其父类 AbstractAutoProxyCreator 这一层被覆写了:

// AbstractAutoProxyCreator

@Override
public Object postProcessAfterInitialization(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;
}
复制代码

继续往里看 wrapIfNecessary(...) 方法,这个方法将返回代理类(若是须要的话):

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
   if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
      return 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;
   }

   // 返回匹配当前 bean 的全部的 advisor、advice、interceptor
   // 对于本文的例子,"userServiceImpl""OrderServiceImpl" 这两个 bean 建立过程当中,
   //   到这边的时候都会返回两个 advisor
   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;
}
复制代码

这里有两个点提一下:

getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null),这个方法将获得全部的可用于拦截当前 bean 的advisor、advice、interceptor。

另外一个就是 TargetSource 这个概念,它用于封装真实实现类的信息,上面用了 SingletonTargetSource 这个实现类,其实咱们这里也不太须要关心这个,知道有这么回事就能够了。

咱们继续往下看 createProxy(…) 方法:

// 注意看这个方法的几个参数,
//   第三个参数携带了全部的 advisors
//   第四个参数 targetSource 携带了真实实现的信息
protected Object createProxy(
      Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {

   if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
      AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
   }

   // 建立 ProxyFactory 实例
   ProxyFactory proxyFactory = new ProxyFactory();
   proxyFactory.copyFrom(this);

   // 在 schema-based 的配置方式中,咱们介绍过,若是但愿使用 CGLIB 来代理接口,能够配置
   // proxy-target-class="true",这样无论有没有接口,都使用 CGLIB 来生成代理:
   //   <aop:config proxy-target-class="true">......</aop:config>
   if (!proxyFactory.isProxyTargetClass()) {
      if (shouldProxyTargetClass(beanClass, beanName)) {
         proxyFactory.setProxyTargetClass(true);
      }
      else {
         // 点进去稍微看一下代码就知道了,主要就两句:
         // 1. 有接口的,调用一次或屡次:proxyFactory.addInterface(ifc);
         // 2. 没有接口的,调用:proxyFactory.setProxyTargetClass(true);
         evaluateProxyInterfaces(beanClass, proxyFactory);
      }
   }

   // 这个方法会返回匹配了当前 bean 的 advisors 数组
   // 对于本文的例子,"userServiceImpl""OrderServiceImpl" 到这边的时候都会返回两个 advisor
   // 注意:若是 specificInterceptors 中有 advice 和 interceptor,它们也会被包装成 advisor,进去看下源码就清楚了
   Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
   for (Advisor advisor : advisors) {
      proxyFactory.addAdvisor(advisor);
   }

   proxyFactory.setTargetSource(targetSource);
   customizeProxyFactory(proxyFactory);

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

   return proxyFactory.getProxy(getProxyClassLoader());
}
复制代码

咱们看到,这个方法主要是在内部建立了一个 ProxyFactory 的实例,而后 set 了一大堆内容,剩下的工做就都是这个 ProxyFactory 实例的了,经过这个实例来建立代理: getProxy(classLoader)

ProxyFactory 详解

根据上面的源码,咱们走到了 ProxyFactory 这个类了,咱们到这个类来一看究竟。

顺着上面的路子,咱们首先到 ProxyFactory#getProxy(classLoader) 方法:

public Object getProxy(ClassLoader classLoader) {
   return createAopProxy().getProxy(classLoader);
}
复制代码

该方法首先经过 createAopProxy() 建立一个 AopProxy 的实例:

protected final synchronized AopProxy createAopProxy() {
   if (!this.active) {
      activate();
   }
   return getAopProxyFactory().createAopProxy(this);
}
复制代码

建立 AopProxy 以前,咱们须要一个 AopProxyFactory 实例,而后看 ProxyCreatorSupport 的构造方法:

public ProxyCreatorSupport() {
   this.aopProxyFactory = new DefaultAopProxyFactory();
}
复制代码

这样就将咱们导到 DefaultAopProxyFactory 这个类了,咱们看它的 createAopProxy(…) 方法:

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

   @Override
   public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
      // (我也没用过这个optimize,默认false) || (proxy-target-class=true) || (没有接口)
      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.");
         }
         // 若是要代理的类自己就是接口,也会用 JDK 动态代理
         // 我也没用过这个。。。
         if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
            return new JdkDynamicAopProxy(config);
         }
         return new ObjenesisCglibAopProxy(config);
      }
      else {
         // 若是有接口,会跑到这个分支
         return new JdkDynamicAopProxy(config);
      }
   }
   // 判断是否有实现自定义的接口
   private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
      Class<?>[] ifcs = config.getProxiedInterfaces();
      return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
   }

}
复制代码

到这里,咱们知道 createAopProxy 方法有可能返回 JdkDynamicAopProxy 实例,也有可能返回 ObjenesisCglibAopProxy 实例,这里总结一下:

若是被代理的目标类实现了一个或多个自定义的接口,那么就会使用 JDK 动态代理,若是没有实现任何接口,会使用 CGLIB 实现代理,若是设置了 proxy-target-class="true",那么都会使用 CGLIB。

JDK 动态代理基于接口,因此只有接口中的方法会被加强,而 CGLIB 基于类继承,须要注意就是若是方法使用了 final 修饰,或者是 private 方法,是不能被加强的。

有了 AopProxy 实例之后,咱们就回到这个方法了:

public Object getProxy(ClassLoader classLoader) {
   return createAopProxy().getProxy(classLoader);
}
复制代码

咱们分别来看下两个 AopProxy 实现类的 getProxy(classLoader) 实现。

JdkDynamicAopProxy 类的源码比较简单,总共两百多行,

@Override
public Object getProxy(ClassLoader classLoader) {
   if (logger.isDebugEnabled()) {
      logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
   }
   Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
   findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
   return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
复制代码

java.lang.reflect.Proxy.newProxyInstance(…) 方法须要三个参数,第一个是 ClassLoader,第二个参数表明须要实现哪些接口,第三个参数最重要,是 InvocationHandler 实例,咱们看到这里传了 this,由于 JdkDynamicAopProxy 自己实现了 InvocationHandler 接口。

InvocationHandler 只有一个方法,当生成的代理类对外提供服务的时候,都会导到这个方法中:

public interface InvocationHandler {
    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable;
}
复制代码

下面来看看 JdkDynamicAopProxy 对其的实现:

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

   TargetSource targetSource = this.advised.targetSource;
   Class<?> targetClass = null;
   Object target = null;

   try {
      if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
         // The target does not implement the equals(Object) method itself.
         // 代理的 equals 方法
         return equals(args[0]);
      }
      else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
         // The target does not implement the hashCode() method itself.
         // 代理的 hashCode 方法
         return hashCode();
      }
      else if (method.getDeclaringClass() == DecoratingProxy.class) {
         // There is only getDecoratedClass() declared -> dispatch to proxy config.
         // 
         return AopProxyUtils.ultimateTargetClass(this.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;

      // 若是设置了 exposeProxy,那么将 proxy 放到 ThreadLocal 中
      if (this.advised.exposeProxy) {
         // Make invocation available if necessary.
         oldProxy = AopContext.setCurrentProxy(proxy);
         setProxyContext = true;
      }

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

      // Get the interception chain for this method.
      // 建立一个 chain,包含全部要执行的 advice
      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. 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. // chain 是空的,说明不须要被加强,这种状况很简单 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);
      }
   }
}
复制代码

上面就三言两语说了一下,感兴趣的读者本身去深刻探索下,不是很难。简单地说,就是在执行每一个方法的时候,判断下该方法是否须要被一次或屡次加强(执行一个或多个 advice)。

说完了 JDK 动态代理 JdkDynamicAopProxy#getProxy(classLoader),咱们再来瞄一眼 CGLIB 的代理实现 ObjenesisCglibAopProxy#getProxy(classLoader)。

ObjenesisCglibAopProxy 继承了 CglibAopProxy,而 CglibAopProxy 继承了 AopProxy。

ObjenesisCglibAopProxy 使用了 Objenesis 这个库,和 cglib 同样,咱们不须要在 maven 中进行依赖,由于 spring-core.jar 直接把它的源代码也搞过来了。

经过 CGLIB 生成代理的代码量有点大,咱们就不进行深刻分析了,咱们看下大致的骨架。它的 getProxy(classLoader) 方法在父类 CglibAopProxy 类中:

// CglibAopProxy#getProxy(classLoader)

@Override
public Object getProxy(ClassLoader classLoader) {
      ...
      // 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);
   }
   catch (CodeGenerationException ex) {
      ...
   }
   catch (IllegalArgumentException ex) {
      ...
   }
   catch (Throwable ex) {
      ...
   }
}
复制代码

CGLIB 生成代理的核心类是 Enhancer 类,这里就不展开说了。

基于注解的 Spring AOP 源码分析

上面咱们蜻蜓点水地介绍了使用 DefaultAdvisorAutoProxyCreator 来实现 Spring AOP 的源码,这里,咱们也一样蜻蜓点水地来看下 @AspectJ 的实现原理。

咱们以前说过,开启 @AspectJ 的两种方式,一个是 <aop:aspectj-autoproxy/>,一个是 @EnableAspectJAutoProxy,它们的原理是同样的,都是经过注册一个 bean 来实现的。

解析 <aop:aspectj-autoproxy/> 须要用到 AopNamespaceHandler:

而后到类 AspectJAutoProxyBeanDefinitionParser:

class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser {

   @Override
   @Nullable
   public BeanDefinition parse(Element element, ParserContext parserContext) {
      AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
      extendBeanDefinition(element, parserContext);
      return null;
   }
   ...
}
复制代码

进去 registerAspectJAnnotationAutoProxyCreatorIfNecessary(...) 方法:

public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
      ParserContext parserContext, Element sourceElement) {

   BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
         parserContext.getRegistry(), parserContext.extractSource(sourceElement));
   useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
   registerComponentIfNecessary(beanDefinition, parserContext);
}
复制代码

再进去 AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary(...):

public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry,
      @Nullable Object source) {

   return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
复制代码

最终咱们看到,Spring 注册了一个 AnnotationAwareAspectJAutoProxyCreator 的 bean,beanName 为:"org.springframework.aop.config.internalAutoProxyCreator"。

咱们看下 AnnotationAwareAspectJAutoProxyCreator 的继承结构:

和前面介绍的 DefaultAdvisorAutoProxyCreator 同样,它也是一个 BeanPostProcessor,剩下的咱们就不说了,它和它的父类 AspectJAwareAdvisorAutoProxyCreator 都不复杂。

闲聊 InstantiationAwareBeanPostProcessor

为何要说这个呢?由于我发现,不少人都觉得 Spring AOP 是经过这个接口来做用于 bean 生成代理的。

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

   Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException;

   boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException;

   PropertyValues postProcessPropertyValues(
         PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException;

}
复制代码

它和 BeanPostProcessor 的方法很是类似,并且它还继承了 BeanPostProcessor。

不仔细看还真的很差区分,下面是 BeanPostProcessor 中的两个方法:

Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
复制代码

发现没有,InstantiationAwareBeanPostProcessor 是 Instantiation,BeanPostProcessor 是 Initialization,它表明的是 bean 在实例化完成而且属性注入完成,在执行 init-method 的先后进行做用的。

而 InstantiationAwareBeanPostProcessor 的执行时机要前面一些,你们须要翻下 IOC 的源码:

// AbstractAutowireCapableBeanFactory 447行
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
   ...
   try {
      // 让 InstantiationAwareBeanPostProcessor 在这一步有机会返回代理
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
      if (bean != null) {
         return bean; 
      }
   }
   // BeanPostProcessor 是在这里面实例化后才能获得执行
   Object beanInstance = doCreateBean(beanName, mbdToUse, args);
   ...
   return beanInstance;
}
复制代码

点进去看 resolveBeforeInstantiation(beanName, mbdToUse) 方法,而后就会导到 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation 方法,对于咱们分析的 AOP 来讲,该方法的实如今 AbstractAutoProxyCreator 类中:

@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
    ...
    if (beanName != null) {
      TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
      if (targetSource != null) {
         this.targetSourcedBeans.add(beanName);
         Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
         Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
         this.proxyTypes.put(cacheKey, proxy.getClass());
         return proxy;
      }
   }

   return null;
}
复制代码

咱们能够看到,这里也有建立代理的逻辑,以致于不少人会搞错。确实,这里是有可能建立代理的,但前提是对于相应的 bean 咱们有自定义的 TargetSource 实现,进到 getCustomTargetSource(...) 方法就清楚了,咱们须要配置一个 customTargetSourceCreators,它是一个 TargetSourceCreator 数组。

这里就再也不展开说 TargetSource 了,请参考 Spring Reference 中的 Using TargetSources

小结

本文真的是蜻蜓点水,和我以前写的文章有很大的不一样,但愿读者不会嫌弃。

本文说细节说得比较少,若是你在看源码的时候碰到不懂的,欢迎在评论区留言与你们进行交流。

(全文完)