`
Kingson_Wu
  • 浏览: 123405 次
文章分类
社区版块
存档分类
最新评论

Spring源码阅读之数据自动绑定

 
阅读更多

SpringMVC的调用过程:
DispatcherServlet ——> 根据url找到相应的Controller,反射方式调用Controller相应的方法。

研究下面两种调用方式:

    @RequestMapping("/baseType")
    public User baseType(int count, long id) {
        User user = new User();
        user.setId(id);
        user.setName("zhang");
        return user;
    }

    @RequestMapping("/object")
    public User object(User user) {
        return user;
    }

上述代码中,基本类型参数以及Java Bean参数,spring都能进行自动数据绑定。

对于第一种基本数据类型的,假如请求url为http://localhost:8080/user/baseType?count=2&id=5,url参数能自动绑定到后端方法相应名字的参数,正如上面所说的,Controller的方法是反射调用的,因此通过反射取得的方法是不会保存方法参数的参数名的,那么在反射调用的时候是怎么能够对应参数名进行传递的呢?
通过debug方式阅读spring的源码(请求过程中debug,以及容器启动过程中debug),重点查看了
DefaultParameterNameDiscoverer,
ConstructorResolver,
AspectJAdviceParameterNameDiscoverer, LocalVariableTableParameterNameDiscoverer,
PrioritizedParameterNameDiscoverer这几个类发现,spring在启动的时候通过类似asm的方式(没采用asm库)从class文件中读取了方法的参数名,并保存到相应的对象缓存中。这里我还没有仔细研究,我的猜测是class文件是有保存方法参数的参数名的,另外我记得javaassist也是通过读取class文件获取方法的参数名的(但是自己用javac生成的class文件貌似没保存参数名)。后续需要研究一下原生java如何解析class文件内容。

在idea的java compiler中加入 -g:none ,再跑起来,调用url,会报错:
java.lang.IllegalArgumentException: Name for argument type [int] not available, and parameter name information not found in class file either.

由此说明,使用maven编译打包时回把方法的参数名信息加入class文件的,也就是说asm读取参数名字时从class文件获取的。


spring-core中有个ParameterNameDiscoverer就是用来获取参数名的,底层用的是asm解析,但是接口方法的参数名无法得到,即只能是非接口类的方法参数名可以
ParameterNameDiscoverer pnd=new DefaultParameterNameDiscoverer();
String[] parameterNames=pnd.getParameterNames(用反射获取到的方法对象);//返回的就是方法中的参数名列表了
http://bbs.csdn.net/topics/391054482?page=1

Java运行时通过asm读取方法参数名:
http://www.oschina.net/code/snippet_2438265_54195
asm获取参数名的原理??

利用javassist获取java的方法参数名:
http://www.tuicool.com/articles/jMjaIr

java如何获取方法参数名:http://blog.csdn.net/mhmyqn/article/details/47294485

/**
* javac -g:none ,加上这个参数就没有了
* —
* javac -g:vars
* 以及
* mvn clean install 都可以
*/
反射是取不到的,如果在编译时使用默认选项的话。javac带有-g:vars编译参数的话,局部变量及方法形式参数名会在字节码中保存着,但是Java代码是访问不到的。
如果需要抽取字节码中的形式参数名称需要自己去了解JVM字节码规范自己去解析!


对于第二种Java Bean参数自动绑定的,因为是是对象,并不需要上述的参数名,但是需要通过反射方式设值。通过查看源码,发现确实是通过反射方式设值的,但是,正如大家一直所强调的,反射的效率较低,能不用反射尽量别用,但是spring为什么频繁用反射,而且现在每一次请求都是通过反射来赋值,那岂不是效率很低?
反射方法缓存
通过进一步查看代码发现,虽然第一次请求同过反射方式生成方法,但是所生成的方法会被保存到相应的对象缓存,当请求再次发生,调用相同的方法时,方法并不需要重新通过反射生成,而是直接从缓存中取(其实就是Map或List),不过还是通过此方法代理调用。

其实无论是DispatcherServlet通过反射调用Controller的方法,还是JavaBean参数反射调用赋值,需要反射调用的方法都是只生成一次(之后保存在缓存),而反射调用才是多次重复的。所以我的理解是生成反射方法才是效率低的,而方法的代理调用并不会太影响性能。

<script type="text/javascript"> $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('<ul/>').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('<li/>').text(i)); }; $numbering.fadeIn(1700); }); }); </script>
分享到:
评论

相关推荐

    Spring+MVC数据绑定大全+

    Spring MVC 数据绑定大全 Spring MVC 框架提供了强大的数据绑定机制,帮助开发者快速地将 HTTP 请求中的数据绑定到 JavaBean 对象中。数据绑定是指将 HTTP 请求中的参数转换为 Java 对象的过程。在 Spring MVC 中,...

    spring MVC数据绑定大全

    在Spring MVC中,数据绑定是一项核心功能,它允许开发者将用户输入的数据与控制器中的对象属性进行关联,简化了数据处理的复杂性。本文将详细介绍Spring MVC中的数据绑定,并提供实例帮助初学者理解。 1. **模型...

    spring mvc 参数绑定漏洞

    3. **默认配置不当**:Spring MVC的默认配置可能允许过于宽松的数据绑定,例如允许空值绑定到非null字段,或者允许任意类型的参数绑定。 针对这些风险,开发者可以采取以下措施来增强Spring MVC应用的安全性: 1. *...

    Spring源代码解析

    同时,了解Spring源码也有助于开发者更好地选择和集成其他Java库,提升开发效率和应用性能。 总结来说,Spring源代码解析涵盖了IoC容器的运作、AOP的实现、数据访问的策略以及Web MVC的流程。深入研究这些内容,将...

    精通spring 源代码

    10. **源码分析**:深入阅读Spring源码,可以帮助我们理解其内部设计思想,如事件驱动、设计模式的应用(如单例、工厂、装饰者等)、类加载机制以及线程安全等Java编程基础。 以上只是Spring框架中部分关键知识点的...

    spring源代码下载地址

    在Spring源码的压缩包中,"Spring源码.txt"可能包含了源代码的说明、导入指南或其他相关信息。打开这个文本文件,可以获取更多关于如何使用和理解Spring源码的提示。 总的来说,获取并研究Spring的源代码是提升Java...

    精通spring源代码精通spring源代码

    要真正精通Spring源代码,除了理解上述知识点外,还需要阅读和分析Spring的源码,理解其实现细节和设计模式。Spring源码中包含了大量优秀的编程实践,如工厂模式、代理模式、观察者模式等,这些都是提升编程技能的...

    Mastering Spring MVC 4(2015.09)源码

    总的来说,"Mastering Spring MVC 4(2015.09)源码"提供了深入学习Spring MVC的机会,你可以通过阅读和分析源码来了解如何配置DispatcherServlet、怎样编写控制器、如何进行数据绑定与验证,以及如何利用拦截器等特性...

    spring 编译后源码(有注释)

    在"spring 编译后源码(有注释)"这个压缩包中,你将获得 Spring 框架 5.0.2.RELEASE 版本的源代码,这些源码已经包含了中文注释,对于学习和理解 Spring 框架的工作原理极其有价值。 1. **IoC(Inversion of ...

    spring源码分析(1-10)

    Spring 源代码分析系列涵盖了多个关键模块,包括事务处理、IoC容器、JDBC、MVC、AOP以及与Hibernate和Acegi安全框架的集成。以下是对这些知识点的详细阐述: 1. **Spring 事务处理**:Spring 提供了声明式事务管理...

    教你阅读Spring源码资源.zip

    这个压缩包“教你阅读Spring源码资源.zip”包含了调试代码、Spring库和JDK库,提供了学习Spring源码的良好起点。 首先,让我们从源码的主要部分开始。Spring的核心组件包括IoC(Inversion of Control,控制反转)...

    spring源码

    Controller通过@RequestMapping注解与URL路径绑定,@RequestParam用于从请求参数中获取数据。 2. 业务逻辑层(Business Logic Layer):也称为服务层,由Service组件实现。Service层封装了业务逻辑,对数据进行处理...

    spring源码(注释+测试版)

    通过阅读和分析这些源代码,开发者可以学习到Spring如何实现依赖注入、AOP代理、事件传播、异常处理、国际化和本地化、数据绑定、类型转换等机制。同时,测试代码可以帮助理解Spring如何测试自己的组件,这对于编写...

    spring多数据源

    6. **在代码中切换数据源**:在业务代码中,可以通过ThreadLocal或其他方式设置当前数据源的标识,使得在执行SQL操作时,Spring能够根据设定自动选择正确的数据源。 7. **读写分离**:多数据源的一个常见应用场景是...

    spring数据绑定.docx

    Spring框架中的数据绑定是将用户输入或其他数据源的数据与应用程序对象的属性进行关联的过程。它使得我们可以方便地在HTTP请求参数、配置文件等与JavaBean属性之间进行转换和赋值。Spring提供了强大的数据绑定功能,...

    spring 动态切换数据源

    - 如果使用Spring Boot,可以利用其自动配置功能,将数据源配置移到`application.properties`或`application.yml`中,并使用`@ConfigurationProperties`注解绑定配置。同时,可以使用`@Bean`注解创建动态数据源bean...

    spring-framework-2.0 Java源代码,spring2源代码

    Spring 框架是Java开发领域中的一个核心框架,它为构建高质量的、松耦合的应用程序提供了...对于想要深入理解Spring框架的开发者来说,研究其源代码是极有价值的,能够帮助他们更好地运用和定制Spring,提升开发技能。

    spring-framework-4.3.0源代码

    对于开发者来说,阅读和理解SpringMVC的源代码不仅可以提高编程技巧,还能帮助优化应用性能,解决潜在的问题,以及更好地利用框架提供的各种功能。通过分析源码,我们还可以了解到Spring如何优雅地实现设计模式,...

    spring源码包.zip

    Spring MVC强调解耦,提供了模型绑定、数据验证、异常处理等特性,使得Web应用的开发更为便捷。 `spring-web`模块则关注于Web应用的基础支持,如Servlet API的封装、HTTP请求和响应对象的处理,以及与WebSocket等...

    Spring攻略(第二版)书籍源码

    通过深入阅读和实践这些源码,你可以对Spring框架有更深入的理解,并能应用于实际项目中,提升开发效率和代码质量。对于正在研读《Spring攻略》的开发者来说,这份源码无疑是一份宝贵的辅助资料。

Global site tag (gtag.js) - Google Analytics