第一次给Spring-Framework贡献代码

鲁肃说建议去看Spring框架的代码,之前其实我想看来着,不过一看到还要gradlew,换jdk就好麻烦.这次各种折腾把代码fork下来,然后安装gradlew,然后转换成eclipse支持的,期间升级了eclipse版本和jdk版本到8.否则会有个方法不支持,

流程很简单,先fork一下代码,然后自己改好提交上去,再去Spring框架的pull request请求一下.等大牛合并就行了.

刚开始看测试用例,我当时看到这个方法调用了一个下线的方法.于是改了一下.提交上去之后,**sbrannen ** 回复说: > while you’re at it, why don’t you go ahead fix the related deprecated issues in all of the test classes in spring-jdbc 于是我把spring-jbdc包下面的几个方法调用都改掉了.记得谁说过,任何事情都不是别人的事情,你发现了你就要去做,不要等着别人去做,不会就去学.于是再次修改提交,sbrannen 问我有没有签CLA,这个坑爹的网站挂了.等了几天,昨天终于ok了.今天代码已经合并.

截图留念:

spring

https://github.com/spring-projects/spring-framework/commits?author=leizhiyuan

今天要吃两个煎饼果子.

Spring揭秘-23章,Spring MVC初体验

 鸟瞰Spring MVC

与其他请求驱动的Web框架思路类似。org.springframework.web.servlet.DispatcherServlet就是Spring mvC中的Front Controller。负责处理请求,但是不针对具体的处理逻辑。而是委派给下一级的控制器,也就是org.springframework.web.servlet.mvc.Controller去执行。
DispatcherServlet的处理流程如下:
1.HandlerMapping
DispathcherServlet是FrontController,所以他服务于一组Web请求,需要在web.xml中配置。
DispathcherServlet需要自己处理请求和处理之前的对应关系,比如根据参数对应到不同的Controller上。为了更加方便的处理映射的匹配,引入HandlerMapping用来获取需要处理请求的对应的Controller类。
2.Controller
对应于DispathcherServlet的次级控制器,本身实现了对应某个具体Web请求的处理逻辑,当HandlerMapping查到了Controller之后,DispathcherServlet获得了HandlerMapping的返回结果。然后调用Controller处理请求,处理完成后,返回一个ModelAndView实例,里面包含两部分内容
视图的逻辑名称,DispathcherServlet根据名称决定显示哪个视图
模型数据,渲染过程中需要将这些模型数据并入视图的显示中
ViewResolver和View
我们已经来到了最后一步,要转成最终的JSP视图文件。由于模板引擎很多,Spring提供了一套基于ViewResolver和View的抽象层。

[来自为知笔记(Wiz)](http://www.wiz.cn/i/e0140d75 "来自为知笔记(Wiz)")
java  spring 

Spring揭秘-22章,迈向Spring MVC的旅程

Spring揭秘-22章,迈向Spring MVC的旅程

Servlet导致数据访问逻辑和业务处理逻辑和对应的视图渲染逻辑相互混杂。之后,JSP出现,通过将输出渲染以模板的形式抽取到jsp后缀的模板文件中,jsp开始繁盛,同时要注意,Servlet处理web请求的时候,要在web.xml中,注册相应的请求url和具体的Serlet的映射关系。于是,jsp有开始混合着写代码
于是,我们引入了JavaBean,来封装相关业务逻辑,经过一次升级后,
这个模型就比较清楚了。但是和MVC还是有点差别
一个典型的mvc模式应该是这样的
控制器处理请求,模型封装逻辑和状态,视图给用户,
Structs以请求/响应框架为基础。
Spring MVC属于请求渠道的WEb框架。框架引入Front Controller做分发之后,就更加好管理了。

[来自为知笔记(Wiz)](http://www.wiz.cn/i/e0140d75 "来自为知笔记(Wiz)")
java  spring 

Spring揭秘-第13章 统一的数据访问异常层次体系

Spring揭秘-第13章 统一的数据访问异常层次体系 DAO可以分离数据哭的访问和存储,屏蔽各种数据访问方式的差异性,下面以访问顾客信息为例,使用DAO模式 首先定义一个数据访问对象接口,如下 public interrface ICustomerDao{ Customer findCustomerByPK(String customerId); void updateCustomerStatus(Customer customer);   之后,所有的数据访问都通过该接口进行,不论底层存储机制如何改变,DAO的实现因此会扩展,但客户端代码不需要调整 客户端要用的时候这样使用即可。 publicclassCustomerService { privateICustomerDao customerDao; publicvoid disableCustomerCampain(String customerId) { Customer customer=getCustomerDao().findCustomerByPK(customerId); customer.setCampainStatus(CampainStatus.DISABLE); getCustomerDao().updateCustomerStatus(customer); } publicICustomerDao getCustomerDao() { return customerDao; } publicvoid setCustomerDao(ICustomerDao customerDao) { this.customerDao=customerDao; }   我们只要针对不同的数据存储方式实现不同的Dao类即可。 我们开始实现具体的访问数据了。 publicCustomer findCustomerByPK(String customerId) { Connection con=null; try{ con=getDataSource().getConnection(); Customer cust=..; return cust; } catch(SQLException e){ //这里咋办,直接抛出还是直接处理? } finally{ releaseConnection(con); } } privatevoid releaseConnection(Connection con){ }   [Read More]
java  spring 

Spring揭秘-第四章BeanFactory笔记

之前说了,IoC容器就是一个IoC Service Provider,但是容器是个啥意思?![](/images/d4d1615a6c1a06895088631c37e3fca7692f0b8a.png) 可以看到IoC容器提供了更多的内容, Spring的IoC容器又分成两种, 1.BeanFactory 。基础类型IoC容器,提供完整的IoC服务支持。如果没有特殊指定,默认采用延 迟初始化策略(lazy-load)。只有当客户端对象需要访问容器中的某个受管对象的时候,才对 该受管对象进行初始化以及依赖注入操作。所以,相对来说,容器启动初期速度较快,所需 要的资源有限。对于资源有限,并且功能要求不是很严格的场景,BeanFactory是比较合适的 IoC容器选择。 2.ApplicationContext。ApplicationContext在BeanFactory的基础上构建,是相对比较高 级的容器实现,除了拥有BeanFactory的所有支持,ApplicationContext还提供了其他高级特性,比如事件发布、国际化信息支持等,这些会在后面详述。ApplicationContext所管理 的对象,在该类型容器启动之后,默认全部初始化并绑定完成。所以,相对于BeanFactory来 说,ApplicationContext要求更多的系统资源,同时,因为在启动时就完成所有初始化,容 器启动时间较之BeanFactory也会长一些。在那些系统资源充足,并且要求更多功能的场景中, ApplicationContext类型的容器是比较合适的选择。   通过 图4-2,我们可以对BeanFactory和ApplicationContext之间的关系有一个更清晰的认识。 ![](/images/f531ea3e11bb391453eb5f763283398c938634b2.png) Bean工长,就是生成Bean的嘛,每个业务对象被看成Javabean,我们与工厂打交道就简单得多,我们只要告诉他我要什么对象,至于怎么组装,那是他的事情。 工厂提供了一些对外的接口,比如获取Bean,渠道Bean的状态等等。 以xml为例 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="djNewsProvider" class="..FXNewsProvider"> <constructor-arg index="0"> <ref bean="djNewsListener"/> </constructor-arg> <constructor-arg index="1"> <ref bean="djNewsPersister"/> </constructor-arg> </bean> <bean id="djNewsListener" class="..impl.DowJonesNewsListener"> </bean> <bean id=" [Read More]
java  spring 

Spring揭秘-第三章IoC Service Provider读书笔记

我们虽然已经通过IoC声明了相应的依赖,但是最终总要有个啥东西将这些依赖对象绑定在一起,这里而IoC Service Provider, 来啦,表示一种绑定的实现方式,可以使一段代码,也可以是一组相关的泪,甚至是框架或容器。 比如前一篇提到的 IFXNewsListener newsListener = new DowJonesNewsListener(); IFXNewsPersister newsPersister = new DowJonesNewsPersister(); FXNewsProvider newsProvider = new FXNewsProvider(newsListener,newsPersister); newsProvider.getAndPersistNews();   就是一个容器,只不过太简单了,不适用于更多的场景, IoC容器就是Spring提供依赖注入服务的Provider IoC Service Provider 是干嘛? 1.业务对象的构建管理,剥离客户端对象的构建的依赖逻辑,比如A引用B,那么A是B的客户端对象,容器需要理清这种关系。 2.业务对象之间的依赖绑定,通过1的实现, 识别各个对象的依赖关系,然后将这些对象依赖的对象注入绑定,用的时候就有了。 那你要问了,这怎么管理对象间的依赖关系呢 IoC Service Provider怎么就能完全领会代码的意图呢?他怎么记住这么多的依赖关系等等,他要这么做 1.元数据方式 2.通过描述性较强的xml来记录对应信息 3.通过编写代码的方式注册这些信息 3.直接编码方式, 明确了依赖关系 IoContainer container = …; container.register(FXNewsProvider.class,new FXNewsProvider()); container.register(IFXNewsListener.class,new DowJonesNewsListener()); … FXNewsProvider newsProvider = (FXNewsProvider)container.get(FXNewsProvider.class); newProvider.getAndPersistNews();   2.配置文件方式 最常见的还是xml方式, <bean id=“newsProvider” class=“. [Read More]
java  spring 

《Spring揭秘》读书笔记-第二章IoC的基本概念

理念就是让别人为你服务,中文名控制反转,也叫依赖注入DI public class FXNewsProvider { private IFXNewsListener newsListener; private IFXNewsPersister newPersistener; public void getAndPersistNews() { String[] newsIds = newsListener.getAvailableNewsIds(); if(ArrayUtils.isEmpty(newsIds)) { return; } for(String newsId : newsIds) { FXNewsBean newsBean = newsListener.getNewsByPK(newsId); newPersistener.persistNews(newsBean); newsListener.postProcessIfNecessary(newsId); } } }  假设这个类用来处理新闻, IFXNewsListener 用来获取新闻, IFXNewsPersister  用来把获取的新闻持久化 当我们需要获取不同的新闻源,比如道琼斯的新闻时,我们会写一个 DowJonesNewsListener 类和 DowJonesNewsPersister 类,然后实例化 public FXNewsProvider() { newsListener = new DowJonesNewsListener(); newPersistener = new DowJonesNewsPersister(); }   如果我们依赖于某个类或服务,最简单而有效的方式就是直接 在类的构造函数中新建相应的依赖类。 注意看, ,我们都是自己主动地去获 取依赖的对象! 可是回头想想,我们自己每次用到什么依赖对象都要主动地去获取,这是否真的必要?我们最终 所要做的,其实就是直接调用依赖对象所提供的某项服务而已 能不能我们用的时候自动送过来呢? [Read More]

《Spring揭秘》读书笔记-第一章Spring框架的由来

1.框架的由来

倡导J2EE轻量级应用解决方案

框架总结结构

Spring Framework 整个Spring架构建立在Core核心模块上,是基础,该模块中,有一个IoC容器的实现,用来以依赖注入的方式管理对象之间的依赖关系。Core中还有一些气筒工具类,比如IO工具类

从图中看到,AOP模块,提供了轻便二强大的AOP框架,一AOP的形式增强POJO的能力,弥补OOP/OOSD的不足,采用Proxy模式,与IoC容器相结合

继续向上看,在Core和AOP之上,提供了完毕的数据访问和事务管理的抽象,其中,对JDBC API的最佳实践简化了API的使用,还未ORM产品提供了统一的支持,

为了简化Java EE的服务,比如JNDI,JMS等等,Spring还提供了这些的集成服务,

最后就是Web模块,提供了一套自己的Web MVC框架,上层模块依赖于下层模块,水平之间的模块彼此基本可以认为独立。

Spring不仅仅是容器,更是开发任何Java应用的框架,

Spring 框架之上衍生的产品包括不限于Spring Web Flow,Spring Web Services,Spring Security,Spring Integration,Spring Rich Client 等等等等

Spring依赖注入

在Spring框架中,依赖注入设计模式主要用来定义对象之间的依赖,存在两种主要类型 1)setter注入(设置器) 2)constructor注入(构造器) 1.Setter注入 是最流行最简单的DI方法,通过一个setter方法来完成依赖。 例子: 一个有一个setter方法的Helper类 package com.mkyong.output; import com.mkyong.output.IOutputGenerator; public class OutputHelper { IOutputGenerator outputGenerator; public void setOutputGenerator(IOutputGenerator outputGenerator){ this.outputGenerator = outputGenerator; } } 再写一个bean配合iwenjianshengming这些bean,并且通过property(属性)标签来设置依赖 <beans xmlns=“http://www.springframework.org/schema/beans" xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=“http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> &lt;bean id="OutputHelper" class="com.mkyong.output.OutputHelper"&gt; &lt;property name="outputGenerator"&gt; &lt;ref bean="CsvOutputGenerator" /&gt; &lt;/property&gt; &lt;/bean&gt; <bean id=“CsvOutputGenerator” class=“com.mkyong.output.impl.CsvOutputGenerator” /> <bean id=“JsonOutputGenerator” class=“com.mkyong.output.impl.JsonOutputGenerator” /> </beans> 看到了把。我们只需要一个setter方法把CsvOutputGenerator注入进去就行了 2.Constructor注入 这种方式是通过一个构造函数来完成依赖设置的 例子: 一个有着一个构造函数的Helper类 package com.mkyong.output; import com.mkyong.output.IOutputGenerator; public class OutputHelper { IOutputGenerator outputGenerator; OutputHelper(IOutputGenerator outputGenerator){ this.outputGenerator = outputGenerator; } } 然后当然是一个bean配置文件了。通过constructor-arg标签来写依赖 <beans xmlns=“http://www. [Read More]

Spring松耦合示例

面向对象设计的理念是把整个系统分成一组可重用的组件,然而,当系统变得越大的时候,尤其是在java中,这最大的对象依赖将会紧紧耦合,以至于非常难以管理和修改,而现在,你可以使用Spring框架扮演一个中间模块的角色,方便高效地管理其他组件依赖 输出生成的例子 看个例子,假设你的项目有一个方法可以输出内容到csv或者json格式,你可能写出这样的代码 package com.mkyong.output; public interface IOutputGenerator { public void generateOutput(); } ,然后是实现接口的类 package com.mkyong.output.impl; import com.mkyong.output.IOutputGenerator; public class CsvOutputGenerator implements IOutputGenerator { public void generateOutput(){ System.out.println(“Csv Output Generator”); } } 再写个Json生成的类 package com.mkyong.output.impl; import com.mkyong.output.IOutputGenerator; public class JsonOutputGenerator implements IOutputGenerator { public void generateOutput(){ System.out.println(“Json Output Generator”); } } 有好几种方法来调用IOutputGenerator接口,以及我们如何使用Spring来避免对象的过度耦合。 方法1-直接调用 package com.mkyong.common; import com.mkyong.output.IOutputGenerator; import com.mkyong.output.impl.CsvOutputGenerator; public class App { public static void main( String[] args ) { IOutputGenerator output = new CsvOutputGenerator(); output. [Read More]