前言

  • 上一章节介绍了<aop:aspectj-autoproxy/>的解析过程,最终结果是得到AnnotationAwareAspectJAutoProxyCreator 这个bean,这个类用于创建AOP的代理类,那么这个类到底做了什么工作来完成AOP的功能的呢?

  • 先看一下AnnotationAwareAspectJAutoProxyCreator 的类继承关系

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
AspectJAwareAdvisorAutoProxyCreator (org.springframework.aop.aspectj.autoproxy)
AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
ProxyProcessorSupport (org.springframework.aop.framework)
ProxyConfig (org.springframework.aop.framework)
Object (java.lang)
Serializable (java.io)
Ordered (org.springframework.core)
BeanClassLoaderAware (org.springframework.beans.factory)
Aware (org.springframework.beans.factory)
AopInfrastructureBean (org.springframework.aop.framework)
SmartInstantiationAwareBeanPostProcessor (org.springframework.beans.factory.config)
InstantiationAwareBeanPostProcessor (org.springframework.beans.factory.config)
BeanPostProcessor (org.springframework.beans.factory.config)
BeanFactoryAware (org.springframework.beans.factory)
Aware (org.springframework.beans.factory)

解析

  • AnnotationAwareAspectJAutoProxyCreator的继承关系图可以注意到此类实现了 BeanPostProcessor接口,这个接口前面经常看见,实现了这个接口是可以在bean初始化之前和初始化之后添加一些逻辑,到这里,我们大概可以猜出代理类是怎样和目标对象联系在一起的,实现偷天换日

    • 先回顾下doCreateBean方法

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      // 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 中的方法,如下:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      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 {
      // 激活用户自定义的init方法 1、InitializingBean接口afterPropertiesSet方法 2、bean 定义的init-method=""方法
      invokeInitMethods(beanName, wrappedBean, mbd);
      }
      ...
      if (mbd == null || !mbd.isSynthetic()) {
      // 我们关注的重点是这里!!!
      // 2. 执行每一个 BeanPostProcessor 的 postProcessAfterInitialization 方法
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
      }
      return wrappedBean;
      }
  • 由上面的代码可以看到Spring AOP 会在 IOC 容器创建 bean 实例的最后对 bean 进行处理,其实就是在这一步进行代理增强。 我们来看一下它是怎么实现 BeanPostProcessor接口的,具体实现在父类AbstractAutoProxyCreator#postProcessAfterInitialization中,下面的代码可以看到先是判断这个bean是否需要被代理,如果要的话就是返回对应的代理类了,具体逻辑在wrapIfNecessary(bean, beanName, cacheKey);方法中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/**
* Create a proxy with the configured interceptors if the bean is
* identified as one to proxy by the subclass.
* @see #getAdvicesAndAdvisorsForBean
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
// 根据给定的bean的class和name构建出个key,格式: beanClassName_beanName
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
// 如果它适合被代理,则需要封装指定的bean
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}

/**
* Wrap the given bean if necessary, i.e. if it is eligible for being proxied.
* @param bean the raw bean instance
* @param beanName the name of the bean
* @param cacheKey the cache key for metadata access
* @return a proxy wrapping the bean, or the raw bean instance as-is
*/
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;
}
// 给定的bean类是否代表一个基础设施类,基础设施类不应代理,或者配置了指定bean不需要自动代理
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}

// Create proxy if we have advice.
// 核心方法 如果存在增强方法则创建代理
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 如果获取到了增强则需要针对增强创建代理
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理 1、获取增强方法或者增强器 2、根据获取的增强进行代理
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;
}
  • 从上面的代码可以看到代理创建的雏形,主要步骤分为两步
    • 1、获取增强方法或者增强器
    • 2、根据获取的增强进行代理

1、获取增强方法或者增强器

  • 先来看获取增强方法的实现逻辑getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Override
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
// 获取所有的增强以及寻找所有增强中适用于bean的增强并应用
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 获取所有增强器
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 从所有增强器中找出适合的增强器
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
  • 可以看到先是获取了所有的增强器,然后在所有增强器中找出适合的增强器并返回

    • 获取所有增强器

      • 当使用注解方式配置AOP的时候并不是丢弃了对XML配置的支持,在这里调用父类方法加载配置文件中的AOP声明,然后再add使用注解配置的Advisor

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        @Override
        protected List<Advisor> findCandidateAdvisors() {
        // Add all the Spring advisors found according to superclass rules.
        // 当使用注解方式配置AOP的时候并不是丢弃了对XML配置的支持
        // 在这里调用父类方法加载配置文件中的AOP声明
        List<Advisor> advisors = super.findCandidateAdvisors();
        // Build Advisors for all AspectJ aspects in the bean factory.
        // 获取注解配置的Advisor
        advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
        return advisors;
        }
      • this.aspectJAdvisorsBuilder.buildAspectJAdvisors()方法是获取注解配置的Advisor

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        56
        57
        58
        59
        60
        61
        62
        63
        64
        65
        66
        67
        68
        69
        70
        71
        72
        73
        74
        75
        76
        77
        78
        public List<Advisor> buildAspectJAdvisors() {
        List<String> aspectNames = this.aspectBeanNames;

        if (aspectNames == null) {
        synchronized (this) {
        aspectNames = this.aspectBeanNames;
        if (aspectNames == null) {
        List<Advisor> advisors = new LinkedList<Advisor>();
        aspectNames = new LinkedList<String>();
        // 获取所有的beanName
        String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
        this.beanFactory, Object.class, true, false);
        // 循环所有的beanName找出对应的增强方法
        for (String beanName : beanNames) {
        // 不合法的bean则略过
        if (!isEligibleBean(beanName)) {
        continue;
        }
        // We must be careful not to instantiate beans eagerly as in this case they
        // would be cached by the Spring conainer but would not have been weaved.
        // 获取对应的bean的类型
        Class<?> beanType = this.beanFactory.getType(beanName);
        if (beanType == null) {
        continue;
        }
        // 如果存在Aspect注解
        if (this.advisorFactory.isAspect(beanType)) {
        aspectNames.add(beanName);
        AspectMetadata amd = new AspectMetadata(beanType, beanName);
        if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
        MetadataAwareAspectInstanceFactory factory =
        new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
        // TODO 核心 解析标记AspectJ注解中的增强方法 委托 advisorFactory.getAdvisors
        List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
        if (this.beanFactory.isSingleton(beanName)) {
        this.advisorsCache.put(beanName, classAdvisors);
        }
        else {
        this.aspectFactoryCache.put(beanName, factory);
        }
        advisors.addAll(classAdvisors);
        }
        else {
        // Per target or per this.
        if (this.beanFactory.isSingleton(beanName)) {
        throw new IllegalArgumentException("Bean with name '" + beanName +
        "' is a singleton, but aspect instantiation model is not singleton");
        }
        MetadataAwareAspectInstanceFactory factory =
        new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
        this.aspectFactoryCache.put(beanName, factory);
        advisors.addAll(this.advisorFactory.getAdvisors(factory));
        }
        }
        }
        this.aspectBeanNames = aspectNames;
        return advisors;
        }
        }
        }

        if (aspectNames.isEmpty()) {
        return Collections.emptyList();
        }
        // 记录在缓存中
        List<Advisor> advisors = new LinkedList<Advisor>();
        for (String aspectName : aspectNames) {
        List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
        if (cachedAdvisors != null) {
        advisors.addAll(cachedAdvisors);
        }
        else {
        MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
        advisors.addAll(this.advisorFactory.getAdvisors(factory));
        }
        }
        return advisors;
        }
      • 上面的逻辑可以看到先是获取所有的beanName然后遍历,找出声明AspectJ注解的类,并将结果加入到缓存中

      • this.advisorFactory.getAdvisors(factory);是最为重要及最为复杂的

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        @Override
        public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
        // 获取标记为AspectJ的类
        Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
        // 获取标记为AspectJ的name
        String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
        // 验证
        validate(aspectClass);

        // We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
        // so that it will only instantiate once.
        MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
        new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

        List<Advisor> advisors = new LinkedList<Advisor>();
        for (Method method : getAdvisorMethods(aspectClass)) {
        // TODO 普通增强器的获取
        Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
        if (advisor != null) {
        advisors.add(advisor);
        }
        }

        // If it's a per target aspect, emit the dummy instantiating aspect.
        // 如果寻找的增强器不为空而且又配置了延迟初始化那么需要在首位加入同步实例化增强器
        if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
        Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
        advisors.add(0, instantiationAdvisor);
        }

        // Find introduction fields.
        // 获取DeclaredField注解
        for (Field field : aspectClass.getDeclaredFields()) {
        Advisor advisor = getDeclareParentsAdvisor(field);
        if (advisor != null) {
        advisors.add(advisor);
        }
        }

        return advisors;
        }
      • 关注for (Method method : getAdvisorMethods(aspectClass))方法,循环切点方法,然后调用Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);获取增强

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        @Override
        public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
        int declarationOrderInAspect, String aspectName) {

        validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());

        // 切点信息的获取
        AspectJExpressionPointcut expressionPointcut = getPointcut(
        candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
        if (expressionPointcut == null) {
        return null;
        }
        // 根据切点信息生成增强器
        return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
        this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
        }

        private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
        // 获取方法上的注解
        AspectJAnnotation<?> aspectJAnnotation =
        AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
        if (aspectJAnnotation == null) {
        return null;
        }
        // 使用AspectJExpressionPointcut实例封装获取的信息
        AspectJExpressionPointcut ajexp =
        new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
        ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
        ajexp.setBeanFactory(this.beanFactory);
        // 提取到的注解中表达式如 @Pointcut("execution(* *.*test*(..))")中的execution(* *.*test*(..)
        return ajexp;
        }

        protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
        // 看到了熟悉的注解类
        Class<?>[] classesToLookFor = new Class<?>[] {
        Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
        for (Class<?> c : classesToLookFor) {
        AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) c);
        if (foundAnnotation != null) {
        return foundAnnotation;
        }
        }
        return null;
        }
      • 这里找出了两个List<Advisor> candidateAdvisors,可以看到第二个是serviceAspectj

    • 找出适合的增强器

      • 上面是获取了所有的增强器,但是对应所有增强器来将并不一定都适用于当前的Bean,还要挑取出合适的增强器,也就是满足我们配置的通配符的增强器

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
        // 获取所有增强器
        List<Advisor> candidateAdvisors = findCandidateAdvisors();
        // 从所有增强器中找出适合的增强器
        List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        extendAdvisors(eligibleAdvisors);
        if (!eligibleAdvisors.isEmpty()) {
        eligibleAdvisors = sortAdvisors(eligibleAdvisors);
        }
        return eligibleAdvisors;
        }
      • 执行List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);方法从所有增强器中找出适合的增强器

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        protected List<Advisor> findAdvisorsThatCanApply(
        List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

        ProxyCreationContext.setCurrentProxiedBeanName(beanName);
        try {
        // 过滤已经得到的advisors
        return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
        }
        finally {
        ProxyCreationContext.setCurrentProxiedBeanName(null);
        }
        }

        public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
        if (candidateAdvisors.isEmpty()) {
        return candidateAdvisors;
        }
        List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();
        // 首先处理引介增强
        for (Advisor candidate : candidateAdvisors) {
        // canApply真正的匹配
        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;
        }
        // 对于普通bean的处理
        if (canApply(candidate, clazz, hasIntroductions)) {
        eligibleAdvisors.add(candidate);
        }
        }
        return eligibleAdvisors;
        }
      • 真正的匹配在canApply()方法,可以看到使用了MethodMatcher接口的boolean matches(Method method, Class<?> targetClass, boolean hasIntroductions);方法进行匹配

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
        if (advisor instanceof IntroductionAdvisor) {
        return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
        }
        else if (advisor instanceof PointcutAdvisor) {
        PointcutAdvisor pca = (PointcutAdvisor) advisor;
        return canApply(pca.getPointcut(), targetClass, hasIntroductions);
        }
        else {
        // It doesn't have a pointcut so we assume it applies.
        return true;
        }
        }
        public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
        Assert.notNull(pc, "Pointcut must not be null");
        if (!pc.getClassFilter().matches(targetClass)) {
        return false;
        }

        MethodMatcher methodMatcher = pc.getMethodMatcher();
        if (methodMatcher == MethodMatcher.TRUE) {
        // No need to iterate the methods if we're matching any method anyway...
        return true;
        }

        IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
        if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
        introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
        }

        Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
        classes.add(targetClass);
        for (Class<?> clazz : classes) {
        Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
        for (Method method : methods) {
        if ((introductionAwareMethodMatcher != null &&
        introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
        methodMatcher.matches(method, targetClass)) {
        return true;
        }
        }
        }

        return false;
        }

2、根据获取的增强创建代理

  • 获取了所有对应bean的增强器后,便可以进行代理的创建了,对于代理类的创建及处理,Spring委托给了ProxyFactory(创建 Proxy 的工厂类)去处理,下面的函数主要是对ProxyFactory的初始化操作,进而对真正的创建代理做准备
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {

if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 对于代理类的创建及处理,Spring委托给了ProxyFactory去处理
ProxyFactory proxyFactory = new ProxyFactory();
// 获取当前类中相关属性
proxyFactory.copyFrom(this);
// 决定对于给定的bean是否应该使用targetClass而不是她的接口代理。检查ProxyTargetClass设置
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 将拦截器封装为增强器
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
for (Advisor advisor : advisors) {
// 加入增强器
proxyFactory.addAdvisor(advisor);
}
// 设置要代理的类
proxyFactory.setTargetSource(targetSource);
// 定制dialing
customizeProxyFactory(proxyFactory);
// 用来控制代理工厂被配置之后是否还允许修改通知 缺省值为false(即在代理被配置之后不允许修改代理的配置)
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 创建代理
return proxyFactory.getProxy(getProxyClassLoader());
}
  • 继续进入proxyFactory.getProxy(getProxyClassLoader())方法
1
2
3
public Object getProxy(ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
  • 可以看到先是调用createAopProxy()创建AopProxy,由下图可以看到一个是cglib的代理,一个是jdk的代理

    • AopProxy 用于生成代理对象的委托类,就俩方法获取代理对象Proxy

      1
      2
      3
      4
      5
      public interface AopProxy {
      Object getProxy();

      Object getProxy(ClassLoader classLoader);
      }
    • 进入createAopProxy()方法,这里根据逻辑判断返回ObjenesisCglibAopProxy或者JdkDynamicAopProxy,如果目标对象实现了接口,默认情况下采用jdk的动态代理,也可以强制使用cglib实现aop(设置方式 <aop:aspectj-autoproxy proxy-target-class="true"/>)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      protected final synchronized AopProxy createAopProxy() {
      if (!this.active) {
      activate();
      }
      // 创建代理
      return getAopProxyFactory().createAopProxy(this);
      }

      /**
      * 如果目标对象实现了接口,默认情况下采用jdk的动态代理,也可以强制使用cglib实现aop
      * 如果目标对象没有实现了接口,必须采用cglib
      * @param config the AOP configuration in the form of an
      * AdvisedSupport object
      * @return
      * @throws AopConfigException
      */
      @Override
      public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
      /**
      * optimize :用来控制通过cglib创建的代理是否使用激进的优化策略,仅对cglib有效,一般不推荐用户使用这个设置
      * proxyTargetClass :为true时,目标类本身被代理而不是目标类的接口,那么cglib代理将被创建,设置方式 <aop:aspectj-autoproxy proxy-target-class="true"/>
      * hasNoUserSuppliedProxyInterfaces: 是否存在代理接口
      *
      */
      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.");
      }
      if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
      return new JdkDynamicAopProxy(config);
      }
      return new ObjenesisCglibAopProxy(config);
      }
      else {
      return new JdkDynamicAopProxy(config);
      }
      }
  • 调用createAopProxy()的到AopProxy之后就是调用AopProxygetProxy(ClassLoader classLoader) 获取代理对象了,AopProxy它有两个子类JdkDynamicAopProxy基于 JDKAOP 代理实现类,ObjenesisCglibAopProxy基于 CGLIBAOP 的代理实现类。

    • JdkDynamicAopProxy

      • 下面看到了我们熟悉的Proxy.newProxyInstance方法

        1
        2
        3
        4
        5
        6
        7
        8
        9
        @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);
        }
      • 可以看到JdkDynamicAopProxy实现了InvocationHandler接口,那么我们可以推断这一定有一个invoke函数

        1
        final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
      • JdkDynamicAopProxyinvoke函数最重要的工作就是创建了一个拦截器链,并实现了拦截器链的逐一调用

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        56
        57
        58
        59
        60
        61
        62
        63
        64
        65
        66
        67
        68
        69
        70
        71
        72
        73
        74
        75
        76
        77
        78
        79
        80
        81
        82
        83
        84
        85
        86
        87
        88
        89
        90
        91
        92
        93
        94
        95
        96
        97
        98
        99
        100
        101
        102
        /**
        * Implementation of {@code InvocationHandler.invoke}.
        * <p>Callers will see exactly the exception thrown by the target,
        * unless a hook method throws an exception.
        */
        @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 {
        // 如果被代理的目标对象要执行的方法是equal则执行JdkDynamicAopProxy(即代理对象的equal)方法
        if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
        // The target does not implement the equals(Object) method itself.
        return equals(args[0]);
        }
        // 如果被代理的目标对象要执行的方法是hashCode则执行JdkDynamicAopProxy(即代理对象的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);
        }
        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;
        }

        // 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.
        // 获取当前方法的拦截器链
        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.
        Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
        // 如果没有发现任何拦截器那么直接调用切点方法
        retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
        }
        else {
        // We need to create a method invocation...
        // 将拦截器封装在ReflectiveMethodInvocation,以便于使用其proceed进行链接表用拦截器
        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);
        }
        }
        }
    • ObjenesisCglibAopProxy

      • Cglib获取代理类

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        56
        57
        58
        59
        60
        61
        62
        63
        64
        65
        66
        @Override
        public Object getProxy(ClassLoader classLoader) {
        if (logger.isDebugEnabled()) {
        logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
        }

        try {
        Class<?> rootClass = this.advised.getTargetClass();
        Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

        Class<?> proxySuperClass = rootClass;
        if (ClassUtils.isCglibProxyClass(rootClass)) {
        proxySuperClass = rootClass.getSuperclass();
        Class<?>[] additionalInterfaces = rootClass.getInterfaces();
        for (Class<?> additionalInterface : additionalInterfaces) {
        this.advised.addInterface(additionalInterface);
        }
        }

        // Validate the class, writing log messages as necessary.
        validateClassIfNecessary(proxySuperClass, 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) {
        throw new AopConfigException("Could not generate CGLIB subclass of class [" +
        this.advised.getTargetClass() + "]: " +
        "Common causes of this problem include using a final class or a non-visible class",
        ex);
        }
        catch (IllegalArgumentException ex) {
        throw new AopConfigException("Could not generate CGLIB subclass of class [" +
        this.advised.getTargetClass() + "]: " +
        "Common causes of this problem include using a final class or a non-visible class",
        ex);
        }
        catch (Throwable ex) {
        // TargetSource.getTarget() failed
        throw new AopConfigException("Unexpected AOP exception", ex);
        }
        }
      • Cglib是一个强大的高性能代码生成包,底层通过使用一个小而快的字节码处理框架ASM,来转化字节码并生成新类

      • Cglib调用方法的核心逻辑在DynamicAdvisedInterceptorintercept方法中,和jdk方式实现代理的invoke方法大同小异
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        56
        57
        58
        59
        60
        61
        62
        63
        /**
        * 核心逻辑
        * General purpose AOP callback. Used when the target is dynamic or when the
        * proxy is not frozen.
        */
        private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {

        private final AdvisedSupport advised;

        public DynamicAdvisedInterceptor(AdvisedSupport advised) {
        this.advised = advised;
        }

        @Override
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        Object oldProxy = null;
        boolean setProxyContext = false;
        Class<?> targetClass = null;
        Object target = null;
        try {
        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 = getTarget();
        if (target != null) {
        targetClass = target.getClass();
        }
        // 获取拦截器链
        List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
        Object retVal;
        // Check whether we only have one InvokerInterceptor: that is,
        // no real advice, but just reflective invocation of the target.
        if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
        // 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 = methodProxy.invoke(target, argsToUse);
        }
        else {
        // We need to create a method invocation...
        // 进入链
        retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
        }
        retVal = processReturnType(proxy, target, method, retVal);
        return retVal;
        }
        finally {
        if (target != null) {
        releaseTarget(target);
        }
        if (setProxyContext) {
        // Restore old proxy.
        AopContext.setCurrentProxy(oldProxy);
        }
        }
        }

总结

  • AnnotationAwareAspectJAutoProxyCreator的继承关系图可以注意到此类实现了 BeanPostProcessor接口,BeanPostProcessor接口是IOCAOP连接的桥梁
  • 在研究源码之前可以尝试着自己想象一下解析思路,看看自己的思路和Spring是否有差别
  • Spring 的容器中,我们面向的对象是一个个的 bean 实例,当我们需要bean的时候通过IOC 容器的 getBean(…) 方法从容器中获取 bean 实例,只不过大部分的场景下,我们都用了依赖注入,所以很少手动调用 getBean(...) 方法。借助IOC的话实现AOP就很简单了,只要在getBean(...)返回新的代理类就可以了
  • Spring使用JDK动态代理和CGLib动态代理技术在运行期织入增强,要使用JDK动态代理,目标类必须实现接口,而CGLib不对目标类作任何限制,他是通过动态生成目标类子类的方式提供代理
  • JDK在创建代理对象时的性能高于CGLib,但生成的代理对象的运行性能却比CGLib的低,如果无需频繁的创建代理对象比较适合采用CGLib动态代理技术,反之比较适合JDK动态代理技术

参考