Junit和Spring配合

JUnit官网

Spring官网

IDEA大杀器:JunitGenerator,可以自动生成Junit的测试接口,剩下我们就只要实现每个todo就好

为了配合Spring的注入,在测试的class前引入XML配置文件,和Spring-test套件

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("application.xml")

私有的方法用反射,public的方法实例化之后直接使用,记得每个java bean用工具生成好equals和hashcode。Junit就能和你的项目好好工作了

为什么我们要用getter/setter方法

第一,历史遗留原因,get/set方法从一种个人习惯被整个产业绑架了;

第二,面向对象的需要,我们可以把基本数据类型做输出前处理;

第三,我们可以把对数据的完整性的校验从流程类往基本对象身上推,逻辑层很少或者根本不用管理任何数据验证的事项,避免在逻辑代码中夹杂大量的数据校验(这个很重要,大部分业务代码为了尽快完成都是想到什么就是添加什么)。

 

代码重构

 

如下几个原则是必要的,也是今后落实代码时候要注意的:

  1. 数据类本身应该对自身的数据完整负责,加解密负责;
  2. 处理逻辑的对象尽量不要包含数据;
  3. 非数据验证的工具类抽取出来存放在单独的Utils类;
  4. 数据类的验证工具如果发现有复用,就要考虑对象是否有继承关系或者是共用一个接口,抽象出接口;
  5. 逻辑复杂的方法一定要降低复杂度,代码控制到20行以内一般就能够轻易地找出bug;
  6. 如果发现一个对象,经常是几部分数据互斥出现使用的,要考虑拆分成多个对象。

网络层级划分

OSI七层就不说了,在transportion描述的太详细了,其实可以归结为五层。

即是:

应用层(Application):Http,P2P这种,基本考虑的是字符串,内容。

运输层(Transportation):传输层用于确定应用层的消息用什么方式传输(可靠地传输或者是不可靠的传输,是否要流量限制等等)

网络层(Network):负责选择路径的层面(两个节点间会有大于等于一个的路由)

链路层(Data Link):协商每两个具体节点间的通信细节(直觉上认为是两个直达节点,没有第三个路由器之间的节点)

如何新建一个Spring MVC+DAO层的项目(一)

如何开始:

整个项目建立好了的结构在这里可以看到:

https://github.com/michaelssss/MealControlSystem

首先这是基于IDEA的一个示例(我表示Eclipse实在不讨喜,Eclispse自己也发现这个问题已经有新的产品了)。

我们选择通过IDEA的模板新建一个Maven工程

继续阅读“如何新建一个Spring MVC+DAO层的项目(一)”

Atmosphere的填坑之旅

事情是这样的,最近在工作中要编写一个在线聊天的工具,当然了,是基于Web开发的。

自然而然的调研到了一个Framework:Atmosphere(StackOverFlow的人各种强力推荐),然后我就下了来试试看。

当然了Demo是一点问题都没法,的确发现意外的好用,而且新版完全遵循J2EE的标准来完成的,包括新的J2EE的注解等等。

这时候自然而然的要移植到自己的软件时候就发现一个问题,死活没办法调用OnMessage的状态。虽然没有仔细阅读源码(我这个人太懒了。。要改,要改),最终还是找到了原因。

这个Framework具体实现上很多都是遵循了需要时注入的原则,具体而言就是当有信息Push到了Server时,因为某些POJO没有调用相应的注入,导致压根就无响应(虽然不理解为毛心跳包和握手包都正常。。。。这个设计者有点不统一)。那么很自然的想到了,这个是不是很像Spring的那种IOC呢?

那么这个Framework压根没有Spring这个组件的,但是Demo里面却能够正常的调用,仔细对比了一下,发现了这个META-INF,这个文件夹按照以前的说明是由编译器生成的METAINFORMATION<通常来说开发者是不需要关心的。但是为了在Servlet3.0以下的容器中使用IOC,在这里做了小小的Trick,写入了META-INF.services一个接口的信息,之前一直都没有注意这些信息导致调用一直失败。

所以这个Meta-INF.services是个什么东西呢:

 

为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。java spi就是提供这样的一个机制:为某个接口寻找服务实现的机制。有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要。

 

java spi的具体约定如下 :

当服务的提供者,提供了服务接口的一种实现之后,在jar包的META-INF/services/目录里同时创建一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类。而当外部程序装配这个模块的时候,就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入。 

基于这样一个约定就能很好的找到服务接口的实现类,而不需要再代码里制定。

具体再来看看我们这个程序中services里面到底写了什么:

2016-03-21 14-48-55 的屏幕截图

其实就是实现了Injectable的接口。

再来看看Injectable具体在程序中是干嘛的,追踪进去:

 

2016-03-22 11-47-02 的屏幕截图

啊哈,在Servlet初始化里面找到了踪迹。

所以呢这个函数是干什么的呢,主要干的和Spring自动装配是同一件事情。。。(为了满足标准的蛋疼。。。感觉Spring真像是个事实上的标准了。。)

所以为什么我们的Message没有发出去呢?

再来仔细观察ObjectInjectableMapper是干了什么:提供了注入的对象的限制。。。

最终,我们知道了。。其实导致不孕不育的原因,啊不。。发不出消息的原因是。。Jackson的MapperObject没有注入,导致编解码失败。。Message的注解其实是个回调函数,其中的Decoder是必须要的。。

因为ManagedSerivce是对整个Framework做的包装,所以想要使得Message的注解能够不用decoder都能生效就只能自己实现咯(当然懒鬼如我。。还是用着把,多方便呢)。

好了,自此都能说的通了。