得到增强器后,开始着手于创建代理对象,那么首先创建代理工厂。
主要在 AbstractAutoProxyCreator#createProxy,简单工厂模式。
能产生两类对象:CglibAopProxyJdkDynamicAopProxy

创建代理工厂,准备创建代理对象所需要的各种资源,具体流程和源码如下:

  1. 公开需要被代理的对象,在该对象的 BeanDefinition 写入属性 org.springframework.aop.framework.autoproxy.AutoProxyUtils.originalTargetClass-targetClass
  2. 新建代理工厂:ProxyFactory,并从当前对象 (AnnotationAwareAspectJAutoProxyCreator,具体看使用注解aop还是xml的aop) 拷贝属性;
  3. 判断proxy-target-class属性(TRUE表示强制使用CGLIB代理对象所有的方法):
    1. true
      1. 判断当前对象是否是JDK代理生成的,如果是把其所有的接口加入ProxyFactory
    2. false
      1. 判断是否应该直接代理目标对象,满足下面俩条件的话:就设置 proxyTargetClass=true
        1. 条件1:beanFactory 是 ConfigurableListableBeanFactory 的实例;
        2. 条件2:目标bean在IOC中存在,并且其定义中包含上面1中暴露的属性;
      2. 上面不满足,那么判断是否应该代理目标对象的接口,如果没有符合条件的接口那么设置 proxyTargetClass=true;如果有符合条件的接口,那么把其所有的接口加入ProxyFactory。这里符合条件的接口需要满足三个条件:
        1. 不容容器内部的接口;
        2. 不是内部语言接口,比如 xx.cglib.proxy.Factory、xx.bytebuddy.MockAccess;
        3. 接口中必须有方法。
  4. 第3步有很多的判断,主要是为了设置 proxyTargetClass 属性。接下来把并增强的方法包装成 Advisor 数组放到 ProxyFactory 中;和我们目标代理对象也放到 ProxyFactory 中;
  5. 留给用户扩展点 customizeProxyFactory(proxyFactory);
  6. 是否需要冻结配置 proxyFactory.setFrozen(this.freezeProxy);
  7. AbstractAdvisorAutoProxyCreator 将 advisorsPreFiltered() 重写为true;
  8. 工厂准备完毕,下一步创建 AOP代理对象 proxyFactory.getProxy(getProxyClassLoader());

源码

  1. protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
  2. @Nullable Object[] specificInterceptors, TargetSource targetSource) {
  3. // 如果beanFactory是ConfigurableListableBeanFactory的实例
  4. if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
  5. // 公开指定需要代理的对象
  6. AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
  7. }
  8. // 新建代理工厂
  9. ProxyFactory proxyFactory = new ProxyFactory();
  10. proxyFactory.copyFrom(this);
  11. // 判断是否配置了 <aop:aspectj-autoproxy proxy-target-class="true"/>,表示使用CGLIB实现AOP。默认false
  12. if (proxyFactory.isProxyTargetClass()) {
  13. // Explicit handling of JDK proxy targets (for introduction advice scenarios)
  14. // 判断当前对象是否是JDK代理生成的
  15. // 当Proxy.newProxyInstance方法动态getProxyClass生成为代理类时,返回 true。
  16. if (Proxy.isProxyClass(beanClass)) {
  17. // Must allow for introductions; can't just set interfaces to the proxy's interfaces only.
  18. for (Class<?> ifc : beanClass.getInterfaces()) {
  19. proxyFactory.addInterface(ifc);
  20. }
  21. }
  22. } else {
  23. // No proxyTargetClass flag enforced, let's apply our default checks...
  24. // 判断是否应该代理该对象
  25. if (shouldProxyTargetClass(beanClass, beanName)) {
  26. proxyFactory.setProxyTargetClass(true);
  27. } else {
  28. // 评估是否应该代理该对象的接口
  29. evaluateProxyInterfaces(beanClass, proxyFactory);
  30. }
  31. }
  32. // 得到增强的拦截方法
  33. Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
  34. proxyFactory.addAdvisors(advisors);
  35. proxyFactory.setTargetSource(targetSource);
  36. // 扩展点
  37. customizeProxyFactory(proxyFactory);
  38. // 冻结配置
  39. proxyFactory.setFrozen(this.freezeProxy);
  40. // 被子类重写为true
  41. if (advisorsPreFiltered()) {
  42. proxyFactory.setPreFiltered(true);
  43. }
  44. // 准工作结束,开始创建代理对象
  45. return proxyFactory.getProxy(getProxyClassLoader());
  46. }

shouldProxyTargetClass

首先判断下 beanFactory 的类型,然后需要判断下 beanDefination了里面的属性值。

  1. protected boolean shouldProxyTargetClass(Class<?> beanClass, @Nullable String beanName) {
  2. return (this.beanFactory instanceof ConfigurableListableBeanFactory &&
  3. AutoProxyUtils.shouldProxyTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName));
  4. }

进入 AutoProxyUtils 的方法 shouldProxyTargetClass
判断bean存在,及其其定义中是否包含属性。

  1. public static boolean shouldProxyTargetClass(
  2. ConfigurableListableBeanFactory beanFactory, @Nullable String beanName) {
  3. if (beanName != null && beanFactory.containsBeanDefinition(beanName)) {
  4. BeanDefinition bd = beanFactory.getBeanDefinition(beanName);
  5. // 判断BeanDefinition中是否有如下属性
  6. // org.springframework.aop.framework.autoproxy.AutoProxyUtils.preserveTargetClass
  7. return Boolean.TRUE.equals(bd.getAttribute(PRESERVE_TARGET_CLASS_ATTRIBUTE));
  8. }
  9. return false;
  10. }

evaluateProxyInterfaces

判断能否使用 jdk 动态代理。能的话拿到接口,不能的话设置 proxyFactory.setProxyTargetClass(true);

  1. protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {
  2. // 返回目标对象所有的接口
  3. Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
  4. // 是否有符合的代理接口
  5. boolean hasReasonableProxyInterface = false;
  6. for (Class<?> ifc : targetInterfaces) {
  7. // isConfigurationCallbackInterface(ifc) 是否为容器的回调接口
  8. // isInternalLanguageInterface(ifc) 是否为内部语言接口
  9. // 接口中必须有方法
  10. if (!isConfigurationCallbackInterface(ifc)
  11. && !isInternalLanguageInterface(ifc)
  12. && ifc.getMethods().length > 0) {
  13. hasReasonableProxyInterface = true;
  14. break;
  15. }
  16. }
  17. if (hasReasonableProxyInterface) {
  18. // Must allow for introductions; can't just set interfaces to the target's interfaces only.
  19. for (Class<?> ifc : targetInterfaces) {
  20. proxyFactory.addInterface(ifc);
  21. }
  22. } else {
  23. proxyFactory.setProxyTargetClass(true);
  24. }
  25. }