SpringAop源码-基于@AspectJ注解的方式

565 阅读12分钟

官方aop

1.SpringAOP的基本概念

Aspect切面

就是定义切入点、通知等载体.如果使用@AspectJ注解的方式它就是一个类,如果使用Schema-based(springxml)的方式,它就是一个标签.
例如以@AspectJ注解的方式

@Aspect
public class PointCutExample {
    // 定义一个PointCut切点
    @Pointcut("execution(* com.spring.Aop..service.*.*(..))")
    public void businessService() {}
}
@Aspect
public class AdviceExample {
    //定义一个advice通知
    @Before("com.spring.Aop.aspect.PointCutExample.businessService()")
    public void before(JoinPoint joinPoint) {
        log.info("准备执行方法:{},参数列表:{}",joinPoint, Arrays.asList(joinPoint.getArgs()));
    }

也可以把通知和切点都写到一个Aspect切面里. 以Schema-based xml的方式

 <!--目标对象一个普通bean-->
 <bean id="userServiceImpl" class="com.spring.Aop.service.。在上例中目标点就是UserServiceImpl类中的"></bean>

 <!--声明一个advice-->
 <bean id="logArgsAdvice" class="com.spring.Aop.aspect.LogArgsAdvice"></bean>

<aop:config>
    <!--定义切点-->
    <aop:pointcut id="logArgsPointCut" expression="execution(* com.spring.Aop..service.*.*(..))"></aop:pointcut>
     <!--定义advice通知-->
    <aop:aspect ref="logArgsAdvice">
        <aop:before method="before" pointcut-ref="logArgsPointCut"></aop:before>
    </aop:aspect>
</aop:config>
//advice通知并没有加注解@AspectJ
public class LogArgsAdvice {

    public void before(JoinPoint joinPoint) throws Throwable {
      log.info("准备执行方法:{},参数列表:{}",joinPoint, Arrays.asList(joinPoint.getArgs()));
    }
}

JoinPoint连接点

叫目标点更好理解.就是需要进行拦截的目标方法,在Aop的理念中很多地方都可以作为连接点,进行添加横切逻辑.但springAop中连接点就单指某个方法。在上例中连接目标点就是UserServiceImpl类中的所有方法。

PointCut切点

定义查找匹配连接点的表达式,可以简单的认为PointCut就是JoinPoint的集合. 代表被表达式匹配上的所有连接点.

advice通知

横切逻辑,前置通知、后置通知等等

注意:

@AspectJ注解使用了AOP的概念.跟AspectJ是没有关系的,只是用了个名字。

2.代码实现基于@AspectJ注解方式

定义连接点JoinPoint,也就是需要代理的目标方法 UserService.java

//UserService接口
public interface UserService {
   User createUser(String name,Integer age);
   User queryUser();
}
//UserServiceImpl实现类
@Slf4j
public class UserServiceImpl implements UserService {
    private static User user = null;

    @Override
    public User createUser(String name, Integer age) {
        user = new User();
        user.setName(name);
        user.setAge(age);
        log.info("UserServiceImpl createUser 方法执行中....");
        return user;
    }

    @Override
    public User queryUser() {
        log.info("UserServiceImpl queryUser 方法执行中....");
        return user;
    }
}

定义pointCut切点,就是匹配查找JoinPoint连接点的表达式 UserPointCut.java

// 定义PointCut
@Aspect
public class UserPointCut {

    @Pointcut("execution(* com.spring.Aop..service.*.*(..))")
    public void businessService() {}
}

定义Advice通知,也就是需要增强的横切逻辑

@Slf4j
@Aspect
public class UserAdvice {

    @Before("com.spring.Aop.aspect.UserPointCut.businessService()")
    public void before(JoinPoint joinPoint) {
        log.info("准备执行方法:{},参数列表:{}",joinPoint, Arrays.asList(joinPoint.getArgs()));
    }

    @AfterReturning(pointcut = "com.spring.Aop.aspect.UserPointCut.businessService()",returning="returnValue")
    public void afterReturning(JoinPoint joinPoint,Object returnValue){
        log.info("{}方法执行返回:{}",joinPoint,returnValue);
    }

application xml配置文件 springAop-2.0aspectJ.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
    <!--普通bean-->
    <bean id="userService" class="com.spring.Aop.service.UserServiceImpl"></bean>

    <!--定义advice通知-->
    <bean id="userAdvice" class="com.spring.Aop.aspect.UserAdvice"></bean>

    <!--开启@AspectJ配置-->
    <aop:aspectj-autoproxy/>

</beans>

测试代码

ClassPathXmlApplicationContext applicationContext =  new ClassPathXmlApplicationContext("classpath:springAop-2.0aspectJ.xml");
UserService userService =  applicationContext.getBean(UserService.class);
userService.createUser("Jom",12);
userService.queryUser();

运行结果:

image.png

3.SpringAop的底层原理

代理模式是springAop的实现原理,但是具体是怎么的呢?如果让我们自己是实现springAop的功能,会怎么做?

3.1动态代理的原理

①.调用Proxy.newProxyInstance生成代理对象.
②.继承InvocationHandler接口,实现Invoke方法,可以在invoke方法添加各种通知横切逻辑,同时调用目标对象的方法.
③.JDK自动生成的代理对象会继承目标对象的接口,并实现目标对象需要代理的方法.方法里再调用②中的invoke方法,而invoke方法中又调用了目标对象的方法,这样就实现了代理的功能.

3.2自己实现aop的思路

①.首先要一个处理aop的工具类
②.找到需要代理的目标类
③.工具类里实现Invoke方法,将寻找到的advice和目标方法调用添加进去.
④.生成代理类对象.因为依赖Jdk动态代理,实现invoke方法将目标对象传入进去即可.

问题:

1.IOC容器如何区分普通类和代理类?--- 通过接口BeanPostProcessor区分的
2.因PointCut切点是匹配表达式,就有可能匹配到很多不同的service方法,会生成一个代理对象包含所有的方法代理?还是生成多个代理对象? ---对于单个被代理的目标对象来说只会生成任意一个代理对象,但在实际执行invoke里会循环执行全部匹配上的advice执行链.

4.源码实现

4.1.查找到处理aop的工具类

在这里是AnnotationAwareAspectJAutoProxyCreator,那怎么找到该类呢?
1.找到开头标签aop对应的命名空间 image.png
2.全局搜索命名空间:www.springframework.org/schema/aop 注意http后需加一个 “\”,在spring.handlers找到对应的Handler image.png 3.再根据Handler找到对应的Parser,这里是AspectJAutoProxyBeanDefinitionParser image.png 4.AspectJAutoProxyBeanDefinitionParser代码如下,parse()方法里会注册AnnotationAwareAspectJAutoProxyCreator类.

//解析方法
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
//注册类到Ioc容器
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
   extendBeanDefinition(element, parserContext);
   return null;
}

进入registerAspectJAnnotationAutoProxyCreatorIfNecessary方法

public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
      ParserContext parserContext, Element sourceElement) {
    //将一个类定义注册到IOC容器,并返回对象BeanDefinition
    //这个就是AnnotationAwareAspectJAutoProxyCreator.class
   BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
         parserContext.getRegistry(), parserContext.extractSource(sourceElement));
   //处理proxy-target-class与expose-proxy属性,将beanDefinition对应的属性设置为true/false
   useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
   //注册组件
   registerComponentIfNecessary(beanDefinition, parserContext);
}

image.png 最终注册bean的key就是这个,下面会进行debug验证.

4.2 Aop处理类Creator何时被加载

那么springIOC容器是知道加载这个类呢?在何时加载的呢?
此处涉及到IOC知识,不详细展开。spring在读取xml配置文件时,会解析xml中的配置,也包括xml文件中的声明部分. 先看下IOC的启动流程,AbstractApplicationContext的refresh()方法.

@Override
public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

      // Prepare this context for refreshing.
      prepareRefresh();

      // a.此处加载AnnotationAwareAspectJAutoProxyCreator的bean定义
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // Prepare the bean factory for use in this context.
      prepareBeanFactory(beanFactory);

      try {
         // Allows post-processing of the bean factory in context subclasses.
         postProcessBeanFactory(beanFactory);

         StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
         // Invoke factory processors registered as beans in the context.
         invokeBeanFactoryPostProcessors(beanFactory);

         // b.注册和创建AnnotationAwareAspectJAutoProxyCreator对象
         registerBeanPostProcessors(beanFactory);
         beanPostProcess.end();

         // Initialize message source for this context.
         initMessageSource();

         // Initialize event multicaster for this context.
         initApplicationEventMulticaster();

         // Initialize other special beans in specific context subclasses.
         onRefresh();

         // Check for listener beans and register them.
         registerListeners();

         // c.注册创建普通的bean对象
         finishBeanFactoryInitialization(beanFactory);

         // Last step: publish corresponding event.
         finishRefresh();
      }

先看a处的代码,进入到obtainFreshBeanFactory()方法,发现里面又调用了refreshBeanFactory()方法. refreshBeanFactory在AbstractRefreshableApplicationContext中代码如下

@Override
protected final void refreshBeanFactory() throws BeansException {
   if (hasBeanFactory()) {
      destroyBeans();
      closeBeanFactory();
   }
   try {
      DefaultListableBeanFactory beanFactory = createBeanFactory();
      beanFactory.setSerializationId(getId());
      //对IOC容器进行定制化,如设置是否允许循环引用、是否允许bean定义覆盖重写等
      customizeBeanFactory(beanFactory);
      //加载Bean定义
      loadBeanDefinitions(beanFactory);
      this.beanFactory = beanFactory;
   }
   catch (IOException ex) {
      throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
   }
}

loadBeanDefinitions方法最终会调用执行上面的AspectJAutoProxyBeanDefinitionParser的parse方法.loadBeanDefinitions执行后debug如下

image.png 可以看到BeanDefinitionMap里除了我们自己定义的bean之外,还多了一个org.springframework.aop.config.internalAutoProxyCreator。

4.2.创建Aop处理类Creator的对象

先看看Creator类的继承关系图如下 image.png 可以看到该类继承实现了BeanPostProcessor接口.这个接口大家应该很熟悉,就是spring设计的扩展功能实现.
另外关于动态代理的执行时机问题,是需要目标对象被创建初始化后,才能进行动态处理操作.不然目标对象都没有,代理谁呢?不符合逻辑.
从IOC的启动流程来说,有了Bean定义同时又实现了BeanPostProcessor接口.故在registerBeanPostProcessors(beanFactory)时会将该Creator类注册到容器里,参看4.2 b处的代码.注意这里注册就会创建Creator类对象了,创建的时机在普通的bean之前,这点尤其重要.

registerBeanPostProcessors源码如下:

public static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
      //查找实现了BeanPostProcessor的类
   String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

   int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
   beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

   // Separate between BeanPostProcessors that implement PriorityOrdered,
   // Ordered, and the rest.
   // 存放实现PriorityOrdered的PostProcessors
   List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
   // 存放实现MergedBeanDefinitionPostProcessor的PostProcessors
   List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
   // 存放实现Ordered的PostProcessors
   List<String> orderedPostProcessorNames = new ArrayList<>();
   // 存放以外情况的PostProcessors
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
   for (String ppName : postProcessorNames) {
      if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
         // 此时PostProcessors对象还没有被创建,所以存放beanName
         priorityOrderedPostProcessors.add(pp);
         if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
         }
      }
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
         orderedPostProcessorNames.add(ppName);
      }
      else {
         nonOrderedPostProcessorNames.add(ppName);
      }
   }

   // First, register the BeanPostProcessors that implement PriorityOrdered.
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

   // Next, register the BeanPostProcessors that implement Ordered.
   // 这里注册实现了Ordered的BeanPostProcessors
   List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
   for (String ppName : orderedPostProcessorNames) {
       // 重点:创建BeanPostProcessors对象 最终会调用执行doCreateBean方法.
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      orderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   sortPostProcessors(orderedPostProcessors, beanFactory);
   //将创建好的BeanPostProcessors对象 存放到beanPostProcessors列表中.
   registerBeanPostProcessors(beanFactory, orderedPostProcessors);

   // Now, register all regular BeanPostProcessors.
   List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
   for (String ppName : nonOrderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      nonOrderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

   // Finally, re-register all internal BeanPostProcessors.
   sortPostProcessors(internalPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, internalPostProcessors);

   // Re-register post-processor for detecting inner beans as ApplicationListeners,
   // moving it to the end of the processor chain (for picking up proxies etc).
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

到这里AnnotationAwareAspectJAutoProxyCreator类的对象已经创建好了,提前创建此种类型对象spring是通过其继承实现了BeanPostProcessor识别的.

4.4 创建普通Bean对象,如何变成代理对象的

创建普通Bean对象也就是需要代理的目标对象,在refresh()方法的finishBeanFactoryInitialization(beanFactory)里面,参看4.2的c处标记。 通过该方法一直点下去,最终会调用到AbstractAutowireCapableBeanFactory.doCreateBean()真正创建对象的地方.如下

//省略。。。。
if (instanceWrapper == null) {
    // 创建对象
    instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//省略。。。。
// Initialize the bean instance.
Object exposedObject = bean;
try {
    // 填充Bean,设置属性啥的
   populateBean(beanName, mbd, instanceWrapper);
   // 初始化Bean
   exposedObject = initializeBean(beanName, exposedObject, mbd);
}
//省略。。。。

进入initializeBean方法

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
   if (System.getSecurityManager() != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
         invokeAwareMethods(beanName, bean);
         return null;
      }, getAccessControlContext());
   }
   else {
      invokeAwareMethods(beanName, bean);
   }

   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;
}

applyBeanPostProcessorsAfterInitialization会循环调用IOC容器中所有的BeanPostProcessor,上面创建的Creator对象的postProcessAfterInitialization在这里会被执行,执行后目标对象就被包装成代理对象了。 至此IOC是如何加载代理对象和普通目标对象就清晰了。接下来就是SpringAop主要内容了。

4.5 创建代理对象

被调用的postProcessAfterInitialization方法在AnnotationAwareAspectJAutoProxyCreator的父接口AbstractAutoProxyCreator中,如下

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    //此处的参数bean和beanName就是目标对象,此时目标对象已经被创建出来了.
   if (bean != null) {
       //从缓存中获取bean的名字key,如果是FactoryBean类型的key前面加&标识,以外的正常返回
      Object cacheKey = getCacheKey(bean.getClass(), beanName);
      if (this.earlyProxyReferences.remove(cacheKey) != bean) {
          //执行处理,处理完如果是aop类型就返回代理后的对象,给到ioc容器
         return wrapIfNecessary(bean, beanName, cacheKey);
      }
   }
   return bean;
}

wrapIfNecessary方法的详细处理

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
   //beanName不可空 && 已经处理过的直接返回
   if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
      return bean;
   }
   //advisedBeans中包含是类型为Advice、Pointcut、Advisor、AopInfrastructureBean都跳过直接返回.
   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;
   }
   // 4.5.1 寻找匹配该目标Bean的横切逻辑方法(advice和advisor之类的)
   // 在我们上面的例子就是UserAdvice里的before和afterReturning方法
   Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
   if (specificInterceptors != DO_NOT_PROXY) {
      this.advisedBeans.put(cacheKey, Boolean.TRUE);
      //4.5.2生成真正的代理对象proxy,即利用JDK动态代理或cglib生成的$proxy0@xxx对象
      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;
}

这步处理结束后、就返回想要的代理对象了.

4.5.1 寻找匹配目标Bean的通知方法(advice和advisor)

getAdvicesAndAdvisorsForBean是抽象方法,具体的实现有2个子类分别是AbstractAdvisorAutoProxyCreator和BeanNameAutoProxyCreator。 而AbstractAdvisorAutoProxyCreator是上面注册的AnnotationAwareAspectJAutoProxyCreator的父类,故找AbstractAdvisorAutoProxyCreator中相应的方法.

@Nullable
protected abstract Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName,
      @Nullable TargetSource customTargetSource) throws BeansException;

image.png AbstractAdvisorAutoProxyCreator中getAdvicesAndAdvisorsForBean()

protected Object[] getAdvicesAndAdvisorsForBean(
      Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
   //查找合适的advisor(继承和注解advisor的类)
   List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
   if (advisors.isEmpty()) {
      return DO_NOT_PROXY;
   }
   return advisors.toArray();
}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
   //先找到容器中全部的advisor
   List<Advisor> candidateAdvisors = findCandidateAdvisors();
   //再匹配beanName对应的advisor
   List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
   extendAdvisors(eligibleAdvisors);
   if (!eligibleAdvisors.isEmpty()) {
      eligibleAdvisors = sortAdvisors(eligibleAdvisors);
   }
   return eligibleAdvisors;
}
4.5.1.1 查找全部的advisor

findCandidateAdvisors()方法,上面的处理是在AbstractAdvisorAutoProxyCreator中,而findCandidateAdvisors方法在其类中有实现,且在子类中也有实现,此处应该去AnnotationAwareAspectJAutoProxyCreator中的实现,优先调用自己的方法

protected List<Advisor> findCandidateAdvisors() {
   // 找到所有继承了Advisor.class的子类
   List<Advisor> advisors = super.findCandidateAdvisors();
   // Build Advisors for all AspectJ aspects in the bean factory.
   if (this.aspectJAdvisorsBuilder != null) {
       //寻找注解的advisor
      advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
   }
   return advisors;
}

经过处理后的advisors里面封装了pointCut和advice信息

4.5.1.2 匹配目标beanName对应的advisor

findAdvisorsThatCanApply()方法

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
   if (candidateAdvisors.isEmpty()) {
      return candidateAdvisors;
   }
   List<Advisor> eligibleAdvisors = new ArrayList<>();
   for (Advisor candidate : candidateAdvisors) {
      if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
         eligibleAdvisors.add(candidate);
      }
   }
   boolean hasIntroductions = !eligibleAdvisors.isEmpty();
   for (Advisor candidate : candidateAdvisors) {
      if (candidate instanceof IntroductionAdvisor) {
         // already processed
         continue;
      }
      if (canApply(candidate, clazz, hasIntroductions)) {
         eligibleAdvisors.add(candidate);
      }
   }
   return eligibleAdvisors;
}

4.5.2 生成具体的代理对象

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
      @Nullable Object[] specificInterceptors, TargetSource targetSource) {

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

   ProxyFactory proxyFactory = new ProxyFactory();
   proxyFactory.copyFrom(this);
   // 判断proxy-target-class="true"
   if (proxyFactory.isProxyTargetClass()) {
      if (Proxy.isProxyClass(beanClass)) {
         for (Class<?> ifc : beanClass.getInterfaces()) {
            proxyFactory.addInterface(ifc);
         }
      }
   }
   else {
      // No proxyTargetClass flag enforced, let's apply our default checks...
      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);
   }

   // Use original ClassLoader if bean class not locally loaded in overriding class loader
   ClassLoader classLoader = getProxyClassLoader();
   if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
      classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
   }
   return proxyFactory.getProxy(classLoader);
}

可以看到proxyFactory对象封装了advisors和目标对象的信息. proxyFactory.getProxy()

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

根据配置先创建AopProxy对象,再根据AopProxy创建具体的proxy对象.是用JDK动态代理还是Cglib方式. DefaultAopProxyFactory类createAopProxy()

@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
   //此处的config参数就是proxyFactory对象
   if (!NativeDetector.inNativeImage() &&
         (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
      Class<?> targetClass = config.getTargetClass();
       ... 
      if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
         return new JdkDynamicAopProxy(config);
      }
      return new ObjenesisCglibAopProxy(config);
   }
   else {
      return new JdkDynamicAopProxy(config);
   }
}

我们只看JdkDynamicAopProxy方法在JdkDynamicAopProxy类中

public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
   //如果不存在Advisor或者目标对象为空的话 抛出异常
   if (config.getAdvisorCount() == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
      throw new AopConfigException("No advisors and no TargetSource specified");
   }
   this.advised = config;
   //获取advised里代理对象所继承的所有接口
   this.proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
   //判断标记继承的接口是否有实现equals和hashCode方法
   findDefinedEqualsAndHashCodeMethods(this.proxiedInterfaces);
}

创建具体的代理对象

@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
   if (logger.isTraceEnabled()) {
      logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
   }
   return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
}

至此代理对象就创建完成了.

4.6 执行调用Aop对象

此处只看JdkDynamicAopProxy JDK动态代理的方式 JDK动态代理的原理,生成的代理对象的方法内部会委托给InvocationHandler.invoke()方法。而invoke方法就会包含各个增强方法(通知),再调用原对象的方法。 看一下JdkDynamicAopProxy的源码实现了InvocationHandler接口

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {

重点invoke()

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

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

   try {
      if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
         // The target does not implement the equals(Object) method itself.
         return equals(args[0]);
      }
      else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
         // The target does not implement the hashCode() method itself.
         return hashCode();
      }
      //method.getDeclaringClass获取Method对应的目标类,method.getClass获得是Method类
      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;
      }
      //获取目标对象的类
      target = targetSource.getTarget();
      Class<?> targetClass = (target != null ? target.getClass() : null);

      // 获取目标方法的拦截器链.程序上我们可以定义多个Aop切面,而某个目标方法就有可能被多个Aop匹配上,故需要循环执行每个匹配的aop通知.
      List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
      //拦截器链为空的,则直接调用目标对象方法
      if (chain.isEmpty()) { 
         Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
         retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
      }
      else {
         // 创建MethodInvocation
         MethodInvocation invocation =
               new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
         // Proceed to the joinpoint through the interceptor chain.
         retVal = invocation.proceed();
      }

      //最终方法执行的返回结果
      Class<?> returnType = method.getReturnType();
      if (retVal != null && retVal == target &&
            returnType != Object.class && returnType.isInstance(proxy) &&
            !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
         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);
      }
   }
}

ReflectiveMethodInvocation的proceed()

public Object proceed() throws Throwable {
   // 如果执行Interceptor完了,则执行joinPoint.注意currentInterceptorIndex初始值为-1
   if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
      return invokeJoinpoint();
   }
   // 执行Interceptor,根据currentInterceptorIndex逐个获取Interceptor
   Object interceptorOrInterceptionAdvice =
         this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
   //是否需要动态匹配     
   if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
      // Evaluate dynamic method matcher here: static part will already have
      // been evaluated and found to match.
      InterceptorAndDynamicMethodMatcher dm =
            (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
      Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
      if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
         return dm.interceptor.invoke(this);
      }
      else {
         // Dynamic matching failed.
         // Skip this interceptor and invoke the next in the chain.
         return proceed();
      }
   }
   else {
      // It's an interceptor, so we just invoke it: The pointcut will have
      // been evaluated statically before this object was constructed.
      //执行当前IntercetporAdvice的invoke方法
      return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
   }
}

为什么@Before、@After的Advice的invoke可以实现前置、后置的通知效果? MethodBeforeAdviceInterceptor的invoke()

public Object invoke(MethodInvocation mi) throws Throwable {
   //先执行before方法,执行完后再回调ReflectiveMethodInvocation.proceed()
   this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
   return mi.proceed();
}

AfterReturningAdviceInterceptor的invoke()

public Object invoke(MethodInvocation mi) throws Throwable {
    //先回调ReflectiveMethodInvocation.proceed(),因为调用joinPoint在这里
   Object retVal = mi.proceed();
   //再执行afterReturning
   this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
   return retVal;
}

结束。

5.总结

Aop首先需要理解基础的概念,有哪些具体是什么用处,怎么使用的。
其次理解动态代理的原理,这是理解aop的基础。
最后具体的aop实现步骤,先创建代理对象 -> 创建目标对象时 -> 判断是否有匹配上的代理对象 ->找到所有的advice和pointCut -> 再找到和目标对象匹配的advice和pointCut -> 生成实际的代理对象 -> 程序调用 -> 代理对象里会调用invoke方法 -> 执行具体的横切逻辑通知 -> 执行调用目标对象.

另仅个人学习记录,有理解不到位的情况...