proxy-target-class属性值: FALSE 或 省略 基于接口(JDK || AspectJ )代理, TRUE 基于类 (CGLIB ) 代理。java
(通常而言,spring的xml中的标签必定是在<beans> 中定义了xmlns及 xsi:schemaLocation 的标签,并有【 xxxNamespaceHandler】 做为xml元素的解析)spring
AopNamespaceHandler:对于<aop:config>的解析使用ConfigBeanDefinitionParser性能
private void configureAutoProxyCreator(ParserContext parserContext, Element element) { AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary(parserContext, element); }
执行进入AopNamespaceUtils.useClassProxyingIfNecessary方法: 优化
private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, @Nullable Element sourceElement) { if (sourceElement != null) { boolean proxyTargetClass = Boolean.parseBoolean(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE)); if (proxyTargetClass) { AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); } boolean exposeProxy = Boolean.parseBoolean(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE)); if (exposeProxy) { AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry); } } }
proxy-target-class = true 则调用AopConfigUtils.forceAutoProxyCreatorToUseClassProxying方法,给beanDefinition对象绑定proxyTargetClass=trueui
public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) { if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) { BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME); definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE); } }
ProxyFactoryBean.getObject() 构建bean的代理对象:spa
调用 DefaultAopProxyFactory.createAopProxy方法来断定使用哪一种代理方式.net
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { 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); } }
终于看到JDK和CGLIB的字样了,这个方法决定了是使用JDK动态代理仍是CGLIB动态代理。下面对if中的判断逻辑逐个解释代理
这个类的说明:code
specify {@code proxyTargetClass} to enforce a CGLIB proxy, or specify one or more interfaces to use a JDK dynamic proxy.
指定{@code proxyTargetClass}来强制执行CGLIB代理,或指定一个或多个接口以使用JDK动态代理xml
结合类说明和判断逻辑,能够得出结论:
指定proxyTargetClass=true后, target对象 非接口类型 && 非DK代理类 时,执行CGLIB代理!其余状况下都是用JDK代理