博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring的代理选择
阅读量:7227 次
发布时间:2019-06-29

本文共 2465 字,大约阅读时间需要 8 分钟。

hot3.png

proxy-target-class属性值决定是基于接口的还是基于类的代理被创建,

TRUE则是基于类的代理将起作用(需要cglib库), 为FALSE或者省略这个属性,则标准的JDK 基于接口的代理将起作用

 

源码解析:

AopNamespaceHandler类,就是spring解析<aop:configproxy-target-class="true">配置的入口,(一般而言,spring的xml中的标签一定是在<beans> 中定义了xmlns及xsi:schemaLocation定义了,并有【 xxxNamespaceHandler 作为xml元素的解析)

则可以看到init方法里注册了ConfigBeanDefinitionParser类来解析,这个类则是实际解析<aop:config proxy-target-class="true">的类

registerBeanDefinitionParser("config",new ConfigBeanDefinitionParser());

打开这个类搜索proxy-target-class,则可以看到configureAutoProxyCreator方法,这个方法则是解析proxy-target-class属性的方法

private void configureAutoProxyCreator(ParserContext parserContext, Element element) {   AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary(parserContext, element);}

进入这个方法,再进入useClassProxyingIfNecessary方法则可以看到

boolean proxyTargetClass = Boolean.valueOf(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));if (proxyTargetClass) {   AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);}

为true则调用forceAutoProxyCreatorToUseClassProxying方法,强制基于类来创建代理,从上面代码可以看出,不设置则默认为false

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

此处可以看到,在bean定义对象中设置了proxyTargetClass属性,后面spring获取bean创建代理类的时候,会判断此属性类决定使用JdkDynamicAopProxy还是ObjenesisCglibAopProxy代理

打开DefaultAopProxyFactory类,查看createAopProxy方法

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()) {         return new JdkDynamicAopProxy(config);      }      return new ObjenesisCglibAopProxy(config);   }   else {      return new JdkDynamicAopProxy(config);   }}

hasNoUserSuppliedProxyInterfaces方法则说明即使你未声明proxy-target-class="true" ,但运行类没有继承接口,spring也会自动使用CGLIB代理。

总结:高版本spring自动根据运行类选择JDK或CGLIB代理,我们无需设置proxy-target-class属性,JDK动态代理是模拟接口实现的方式,cglib是模拟子类继承的方式,一般采用前者,因为前者效率高,  后者不建议使用。

转载于:https://my.oschina.net/u/3434392/blog/2909055

你可能感兴趣的文章
Web前端入门学习(3)——CSS选择器
查看>>
DNS的搭建
查看>>
Apache/Nginx 访问日志分析脚本
查看>>
Curator的使用
查看>>
第五章 集合类型
查看>>
我的友情链接
查看>>
nagios监控服务出现FLAPPING状态时无法发出邮件报警信息
查看>>
数据库链接字符串方法
查看>>
The DCI Architecture: A New Vision of Object-Oriented Programming(一篇具有里程碑式意义的论文)...
查看>>
RIP路由配置实例V2
查看>>
Bytescout Spreadsheet SDK for.NET
查看>>
我的友情链接
查看>>
Haproxy的三种保持客户端会话保持方式
查看>>
iOS的数学函数
查看>>
python 模块 chardet下载及介绍(转)
查看>>
能力工场--关于在JavaScript中使用EL表达式的问题
查看>>
NFS服务器设置
查看>>
s:iterator 中的status 使用方法
查看>>
cocos2d-x 源码剖析系列
查看>>
IT系统架构设计
查看>>