AopProxyUtils
我理解成它是对org.springframework.aop.support.AopUtils
的一个补充。
public static void main(String[] args) { HelloService helloService = getProxy(new HelloServiceImpl()); //===============演示AopUtils================== // 注意:此处的入参必须是一个Advised:也就是被代理过的对象,否则返回null // 里面的TargetSource必须是SingletonTargetSource才会有所返回 //@since 4.3.8 System.out.println(AopProxyUtils.getSingletonTarget(helloService)); //com.fsx.service.HelloServiceImpl@17d677df // 获取一个代理对象的最终对象类型 System.out.println(AopProxyUtils.ultimateTargetClass(helloService)); //class com.fsx.service.HelloServiceImpl }
接下俩的方法,才是这个工具类真正厉害的方法:
public abstract class AopProxyUtils { ... //很牛逼的方法来了,判断一个advised真正需要代理的目标接口列表 // 这个方法在getProxy()上都有应用,非常的重要。核心实现事下面的这个私有方法 public static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised) { return completeProxiedInterfaces(advised, false); } // 很显然发现,最终代理出来的对象,除了实现了自己的接口外,还实现了额外的接口,如: // SpringProxy、Advised、DecoratingProxy等三个接口(备注:CGLIB代理未实现DecoratingProxy接口) static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) { Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces(); if (specifiedInterfaces.length == 0) { // No user-specified interfaces: check whether target class is an interface. Class<?> targetClass = advised.getTargetClass(); if (targetClass != null) { if (targetClass.isInterface()) { advised.setInterfaces(targetClass); } else if (Proxy.isProxyClass(targetClass)) { advised.setInterfaces(targetClass.getInterfaces()); } specifiedInterfaces = advised.getProxiedInterfaces(); } } boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class); boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class); boolean addDecoratingProxy = (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class)); int nonUserIfcCount = 0; if (addSpringProxy) { nonUserIfcCount++; } if (addAdvised) { nonUserIfcCount++; } if (addDecoratingProxy) { nonUserIfcCount++; } Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount]; System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length); int index = specifiedInterfaces.length; if (addSpringProxy) { proxiedInterfaces[index] = SpringProxy.class; index++; } if (addAdvised) { proxiedInterfaces[index] = Advised.class; index++; } if (addDecoratingProxy) { proxiedInterfaces[index] = DecoratingProxy.class; } return proxiedInterfaces; } //该方法用于获取一个代理对象中的用户定义的接口,即非(Advised接口体系)之外的其他接口 public static Class<?>[] proxiedUserInterfaces(Object proxy) { Class<?>[] proxyInterfaces = proxy.getClass().getInterfaces(); int nonUserIfcCount = 0; if (proxy instanceof SpringProxy) { nonUserIfcCount++; } if (proxy instanceof Advised) { nonUserIfcCount++; } if (proxy instanceof DecoratingProxy) { nonUserIfcCount++; } Class<?>[] userInterfaces = new Class<?>[proxyInterfaces.length - nonUserIfcCount]; System.arraycopy(proxyInterfaces, 0, userInterfaces, 0, userInterfaces.length); Assert.notEmpty(userInterfaces, "JDK proxy must implement one or more interfaces"); return userInterfaces; } //判断两个(即将)代理出来的对象是否相同 public static boolean equalsInProxy(AdvisedSupport a, AdvisedSupport b) { return (a == b || (equalsProxiedInterfaces(a, b) && equalsAdvisors(a, b) && a.getTargetSource().equals(b.getTargetSource()))); } // 判断它哥俩的接口是否相同 public static boolean equalsProxiedInterfaces(AdvisedSupport a, AdvisedSupport b) { return Arrays.equals(a.getProxiedInterfaces(), b.getProxiedInterfaces()); } // 判断它哥俩的增强器(Advisor)是否相同 public static boolean equalsAdvisors(AdvisedSupport a, AdvisedSupport b) { return Arrays.equals(a.getAdvisors(), b.getAdvisors()); } }
JDK代理和CGLIB代理的获取代理对象方法都用使用此方法:
// JDK代理的获取代理对象~~~ @Override public Object getProxy(@Nullable 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); }
AopProxyUtils中的方法不多,但是其中的ultimateTargetClass和completeProxiedInterfaces方法确是Spring AOP中比较重要的方法,也给了我们一个入手观察Spring AOP真正实现过程的一个突破口;我认为这个,才是AopProxyUtils给我们的价值;
AopContext
这个工具类就更简单,它代表AOP的上下文。主要是提供我们访问上下文中当前AOP对象的快速方法。
public abstract class AopContext { // 一个ThreadLocal,和当前上下文绑定的AOP对象 private static final ThreadLocal<Object> currentProxy = new NamedThreadLocal<>("Current AOP proxy"); // public方法,调用者可以在任何地方获取到当前上下文中的AOP代理对象。 // 请注意:这个和exposeProxy参数有关,只有为true了才生效,默认都是false的 public static Object currentProxy() throws IllegalStateException { Object proxy = currentProxy.get(); if (proxy == null) { throw new IllegalStateException( "Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available."); } return proxy; } @Nullable static Object setCurrentProxy(@Nullable Object proxy) { Object old = currentProxy.get(); if (proxy != null) { currentProxy.set(proxy); } else { currentProxy.remove(); } return old; } }
备注:这个工具类主要是和属性exposeProxy相关,让我们能够快捷的获取到AOP代理对象,而不是this对象。这个在事务不生效原因大解读的博文了得到了应用
AutoProxyUtils
为自动代理组件准备的工具类。主要用于框架内部使用(AbstractAutoProxyCreator)
public abstract class AutoProxyUtils { // org.springframework.aop.framework.autoproxy.AutoProxyUtils.preserveTargetClass // preserve:保护的 保留的 // determine:查明 测定 public static final String PRESERVE_TARGET_CLASS_ATTRIBUTE = Conventions.getQualifiedAttributeName(AutoProxyUtils.class, "preserveTargetClass"); // org.springframework.aop.framework.autoproxy.AutoProxyUtils.originalTargetClass public static final String ORIGINAL_TARGET_CLASS_ATTRIBUTE = Conventions.getQualifiedAttributeName(AutoProxyUtils.class, "originalTargetClass"); // 判断该beanName是否应该被代理 // `AbstractAutoProxyCreator`里就有判断是否能够被代理。 如果能够被代理,那就采用CGLIB的代理方式了 // 往里setAttr,目前只有`ConfigurationClassPostProcessor`对config配置类进行增强的时候 // public static boolean shouldProxyTargetClass(ConfigurableListableBeanFactory beanFactory, @Nullable String beanName) { // 容器内存在这个Bean,并且这个Bean的定义信息里面属性值`PRESERVE_TARGET_CLASS_ATTRIBUTE`必须是true才行 说明才能被代理 if (beanName != null && beanFactory.containsBeanDefinition(beanName)) { BeanDefinition bd = beanFactory.getBeanDefinition(beanName); return Boolean.TRUE.equals(bd.getAttribute(PRESERVE_TARGET_CLASS_ATTRIBUTE)); } return false; } // 看看这个Bean定义的TargetClass // 如果Bean定义信息里面有ORIGINAL_TARGET_CLASS_ATTRIBUTE这个字段,那就不用getType()了 // 以及ScopedProxyUtils创建和Scope有关的代理类的时候,其余地方都不会设置此属性 @Nullable public static Class<?> determineTargetClass(ConfigurableListableBeanFactory beanFactory, @Nullable String beanName) { if (beanName == null) { return null; } if (beanFactory.containsBeanDefinition(beanName)) { BeanDefinition bd = beanFactory.getMergedBeanDefinition(beanName); Class<?> targetClass = (Class<?>) bd.getAttribute(ORIGINAL_TARGET_CLASS_ATTRIBUTE); if (targetClass != null) { return targetClass; } } return beanFactory.getType(beanName); } //Expose the given target class for the specified bean, if possible // 就是在它的Bean定义信息里面,设置一个ORIGINAL_TARGET_CLASS_ATTRIBUTE属性,然后吧targetClass类型放进去 // 也是子啊`AbstractAutoProxyCreator`创建代理的时候会这只进去的 static void exposeTargetClass(ConfigurableListableBeanFactory beanFactory, @Nullable String beanName, Class<?> targetClass) { if (beanName != null && beanFactory.containsBeanDefinition(beanName)) { beanFactory.getMergedBeanDefinition(beanName).setAttribute(ORIGINAL_TARGET_CLASS_ATTRIBUTE, targetClass); } } }
AspectJAopUtils
相比于AopUtils
,AspectJAopUtils
是专门针对于AspectJ advisors
的工具类。(当然AspectJ也是当下的主流方式)
public abstract class AspectJAopUtils { //拿到AspectJ的优先信息:AspectJPrecedenceInformation 这个就接口保存着 @Nullable public static AspectJPrecedenceInformation getAspectJPrecedenceInformationFor(Advisor anAdvisor) { if (anAdvisor instanceof AspectJPrecedenceInformation) { return (AspectJPrecedenceInformation) anAdvisor; } Advice advice = anAdvisor.getAdvice(); if (advice instanceof AspectJPrecedenceInformation) { return (AspectJPrecedenceInformation) advice; } return null; } // Advisor 是否是前置通知类型~~~~(Advisor都持有一个advice嘛) public static boolean isBeforeAdvice(Advisor anAdvisor) { AspectJPrecedenceInformation precedenceInfo = getAspectJPrecedenceInformationFor(anAdvisor); if (precedenceInfo != null) { return precedenceInfo.isBeforeAdvice(); } return (anAdvisor.getAdvice() instanceof BeforeAdvice); } // Advisor 是否是后置通知类型~~~~(Advisor都持有一个advice嘛) public static boolean isAfterAdvice(Advisor anAdvisor) { AspectJPrecedenceInformation precedenceInfo = getAspectJPrecedenceInformationFor(anAdvisor); if (precedenceInfo != null) { return precedenceInfo.isAfterAdvice(); } return (anAdvisor.getAdvice() instanceof AfterAdvice); } }
AspectJProxyUtils
同样的,它相对于AopProxyUtils
,它只是专门处理AspectJ代理对象的工具类。
public abstract class AspectJProxyUtils { // 判断,该Advisor是否是AspectJ的的增强器 private static boolean isAspectJAdvice(Advisor advisor) { return (advisor instanceof InstantiationModelAwarePointcutAdvisor || advisor.getAdvice() instanceof AbstractAspectJAdvice || (advisor instanceof PointcutAdvisor && ((PointcutAdvisor) advisor).getPointcut() instanceof AspectJExpressionPointcut)); } // 只提供这么一个公共方法,但是这个方法都还是非常重要的。 Capable:有能力的 // 它在自动代理创建器`AspectJAwareAdvisorAutoProxyCreator#extendAdvisors`方法中有调用(重要~~~) // 在AspectJProxyFactory#addAdvisorsFromAspectInstanceFactory方法中也有调用 // 它的作用:只要发现有AspectJ的Advisor存在,并且advisors还不包含有ExposeInvocationInterceptor.ADVISOR 那就在第一个位置上调添加一个ExposeInvocationInterceptor.ADVISOR // 这个`ExposeInvocationInterceptor.ADVISOR`的作用:就是获取到当前的currentInvocation,也是使用的ThreadLocal public static boolean makeAdvisorChainAspectJCapableIfNecessary(List<Advisor> advisors) { // Don't add advisors to an empty list; may indicate that proxying is just not required if (!advisors.isEmpty()) { boolean foundAspectJAdvice = false; for (Advisor advisor : advisors) { // Be careful not to get the Advice without a guard, as // this might eagerly instantiate a non-singleton AspectJ aspect if (isAspectJAdvice(advisor)) { foundAspectJAdvice = true; } } if (foundAspectJAdvice && !advisors.contains(ExposeInvocationInterceptor.ADVISOR)) { advisors.add(0, ExposeInvocationInterceptor.ADVISOR); return true; } } return false; } }