Spring MVC 挺直腰板儿说:依赖注入,我自个儿来!

来源:互联网 发布:淘宝链接微信打不开 编辑:程序博客网 时间:2024/06/05 18:18

研究 Spring MVC 将请求分发到 Spring 依赖注入的类实例

太阳火神的美丽人生 (http://blog.csdn.net/opengl_es)

本文遵循“署名-非商业用途-保持一致”创作公用协议

转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS、Android、Html5、Arduino、pcDuino否则,出自本博客的文章拒绝转载或再转载,谢谢合作。



一上午时间,碰了 N 个钉子,不断地把钉子拨掉,记录一下选择的工具和方法:

1、首先 Spring Mvc 框架的下载,那么有三个包是必不可少的: 

spring-webmvc-3.2.9.RELEASE.jar

spring-web-3.2.9.RELEASE.jar

spring-core-3.2.9.RELEASE.jar

还有一个,暂不考虑 ;

这些包,之前从 Spring 官网下载,那叫一个费劲儿,只能在网上下载一些别人的示例,其中带的包来用。其实是示例为主,包为辅 微笑,从头学起就得这样啦。

从以下地址可以搜到想要的 Jar 包

http://mvnrepository.com/

我们输入 spring-webmvc-3.2.9.RELEASE.jar  点按搜索,得到下图内容:


点第一条 Spring Web MVC ,转入到如下页面内容部分:


点按其中的 3.2.9 RELEASE ,终于周折到目标位置了:


点那个 Download(JAR)(623 KB)就可以下载了。

该页面,往下滚动,找到如下内容部分:



除了 Java Spec 和 JSP Tag Library ,是 J2EE 自带的库外,其它的可能都要下来试一试了,不过并不是所有的都是必须的,仅当你用到了 Spring 提供的该项功能,而该项功能是依托于以上所列特定包时,才需要。

这些里面已经包含了上面所提到的所有 Jar 了,真是了不起的 Maven,不过我并没有把工程转成 Maven 管理,老程序员嘛,N年前用过的,Maven 还没有出来,不太习惯,不过要说它确实不错。但目前网上评论,都是它有点复杂,而 Gradle 又成为了热点,这个我相信,Grails 的兴起足以说明。


2、在从头配置的过程中,按网上的例子,创建了动态 Web 工程,并在 web.xml 中添加了 Spring 的上下文参数以指定 Spring 的配置文件位置;添加 Spring 的上下文加载监听器,这样 Spring 就配置完了,Spring 有三种加载方式,在网上看过了 N 篇,从远及近或从近及远,都说 Servlet 的方式已经不支持?插件方式对于 structs 2 也不支持了?不知道弄没弄混,最后,只有监听器的加载方式依然绿树常青,也许有它的道理吧,不得而知,待俺把门入了,再研究。

3、配置 SpringMVC 的分发器 Servlet 及映射,这个,俺把十年前的 Java Web 书从书堆里扒啦出来,一顿翻,终于又熟悉了,这个也怪,我记忆犹新,当年看的时侯,确实只能记住,确看不懂,而现在是从另一个角度和方向来看,就不存在懂不懂的问题,而成为了一个参考书,这里要这样写,那里要那样写,最后配成了访问这个地址,就转到同名的那个 Servlet 被调用,高度不同,看问题的角度诚然是不同的,当然了,在 Java Web 面向俺高度很低,但俺已经养成,俺很低的时侯,我会把它放到地坑里去看它,哈哈,说笑。。。

这样配完,默认 Spring MVC 找给它配置的对应的 Servlet 名开头,后跟 -servlet.xml 的配置文件加载。

是的,就是在这里纠结了 N 多时侯,正常在其配置文件中配置了控制器的搜索包路径,那么添加了注解  @Controller 的类都会被搜索到,再根据这些类中的方法前的注解 @RequestMapping(method = RequestMethod.GET)  来找对应的映射,这些都不用在 XML 中配置了,据说这是 Spring MVC 现在比较流行的原因,这样性能没有瓶颈,而 Structs 的团队也承认 XML 配置文件的方式导致性能问题,这些说法,俺也是道听途说,真假难辩,至少目前最新的 Java Web 的框架来说,能搜到较多的是 Spring MVC ,足以说明问题了。

这个请求与方法的映射的注解写法,俺还得继续深入研究、测试后,再补足说明。

俺的简简单单地就能进这个方法的断点了,而俺还配了一些 Mybatis 的依赖注入在 Spring 的配置文件中,实际运行时,确死活也没有接口对应的实现被注入。

重新研究 Spring 的依赖注入,才发现,和 N 年前的理解相去甚远,N 年前,把它想得太伟大了,以前是动态侦测类的调用,然后去实例化对象,现在明白了,Srping 上下文对象里有个 控制反转容器,用于存储从配置文件中实例化的这些 bean 并把它们装配起来,所谓的装配,就是谁是谁的属性,那就放到那个属性里去。

这样来看,Spring 实例化的这些类形成了一个大串串,如果没有 Spring 所掌管的容器,这些顶层的类实例就没有人引用它了,结果自然是释放了,顶级实放,其属性消失,属性索引的类实例也就释放了,一级一级的下去。这当然是不可能的,因为 Spring 确实索引了这些类实例,并放到了 Web 应用上下文中,以便能被访问到。

确实有想过,在控制器类中去这样取,但这种套路,未免小看 Spring 了吧,基于这个想法,Spring MVC 根据请求搜索控制器类的时侯,按注解找到了能响应这个请求的类之后,该怎么做呢?

一种,实例化它,另一种从 Spring MVC 索引的类中取到对应的实例,但确实不知道 web.xml 中配置的Srping MVC 和 Spring 两者如何关联起来,而实际是否使用了,也不得而知。

这里想到一个好办法,在 Spring 的配置中,对控制器类加个属性,并设一个字符串值,在控制器类中,真实地加个字符串类型的属性,这样再断点调试,进入到控制器后,发现这个新加的属性的值并不是在 Spring配置中设置的值,这一点说明,Spring MVC 确实没有使用 Spring 索引的那些个类,说明二者并不互相知道对方的存在。

经网查,确实有人也提出,Spring 和Spring MVC 一起配的这种方式,不可用。

那么 Srping MVC 不会弱智到这种程度,没办法和 Spring 整合吧,这一家的东西出现这种情况,那不被人家笑掉大牙才怪,那不成了祸里搞了吗!

此时需要正能量,正能量面前,人们总会以积极的方式来思考问题,那就是,这两个东西要么互相能接口,要么 Spring MVC 本身就已经基于 Spring 在做事情,那它内部自然会实现了 Spring 的机制。

不妨试试,把 Spring 的配置文件,同时配给 Spring MVC ,而且网查结果,两者用的是同一个名称的参数名:  contextConfigLocation ,有点意思,应该可行。

意思就是让 SpringMVC 即负责 MVC 请求分发,又管理类的依赖注入,开动,调试。

进入控制器类,查看运行时新加字符串属性的值,啊哈哈,已经是 Spring 配置文件中设定的属性值了。


由此可见,Spring MVC 内部不光能处理 MVC 的请求分发,同时也维护着 Spring 的依赖注入,即配置文件中类的实例化与装配,当一个请求交给 Spring MVC 分发器时,它先去指定路径搜索类中的注解,及方法注解,找到能匹配该请求的类及方法后,从其维护的 Spring 依赖注入类树中找到该类,并调用该类的对应方法。


至此,问题解决了。


还有一个问题,就是 Mybatis 的映射的依赖注入,如下官方文档中的 Java 代码,如何在 Spring 中配置,稍侯研究,再行发文:

SqlSession session = sqlSessionFactory.openSession();try {  BlogMapper mapper = session.getMapper(BlogMapper.class);  Blog blog = mapper.selectBlog(101);} finally {  session.close();}

----------补充----------

上面的问题,终于找到答案了,原来,这个需要用到 MyBatis-Spring ,它会通过配置于 Spring 中来注入可用的实例;

下面是一种针对一组映射器生成注入实例的方式,由 MapperScannerConfigurer 负责生成多个 MapperFactoryBean,可以直接拿来注入到其它地方的对应接口上,当然了,确实接口声明同包路径下有同名的 .xml 映射器文件是前提,要不然就得另外指定映射器配置文件位置了,约定重于配置,尽量还是别配置了,就按约定的来吧,简单且有条理。

(这里需要补充说明一下,虽然看似注入的 MapperFactoryBean ,而我确说是映射器的实现,这里有个饶头,那就是 MapperFactoryBean 是一个工厂 bean,工厂 bean 在 Spring 注入中有特殊的用途,注入时会调用工厂类的 getObject() 方法,将获得的对象进入注入,这就是解释了,工厂类不实例化,确要注入,另注入工厂类确得到映射器接口的实现类的原因。这个可以参考一下这篇文章)



以上问题纠结,源于最新的一份官方文档,其中并未明确提及依赖注入,而一篇老文档中有说到,这个透露着什么样的信息呢?不得而知,也或许这份最新的文档,还没完善呢吧。。。

Mybatis 最新文档?



Mybatis 老文档


噢,原来这一篇是 MyBatis-Spring 的文档,原来两者是有不同的。。。啊!

由此可见,知道的多而不会用,总比啥都不知道要强,真要找资料,也能门儿清,这就是解决问题的思路吧!

平时扯蛋时,其实扯的就是思路,平时多扯点儿这方面儿的蛋,真正研究时,也就不那么难了。




0 0
原创粉丝点击