作者:nnngu

项目源代码:https://github.com/nnngu/nguSeckill


首先在编写Service层代码前,我们应该首先要知道这一层到底是干什么的。

Service层主要负责业务模块的逻辑应用设计。同样是首先设计接口,再设计其实现的类,接着在Spring的配置文件中配置其实现的关联。这样我们就可以在应用中调用Service接口来进行业务处理。Service层的业务实现,具体要调用到已定义的dao层的接口,封装Service层的业务逻辑有利于通用的业务逻辑的独立性和重复利用性,程序显得非常简洁。

在项目中要降低耦合的话,分层是一种很好的概念,就是各层各司其职,尽量不做不相干的事,所以Service层的话顾名思义就是业务逻辑,处理程序中的一些业务逻辑,以及调用dao层的代码,这里我们的dao层就是连接数据库的那一层,调用关系可以这样表达:

View(页面) > Controller(控制层) > Service(业务逻辑) > Dao(数据访问) > Database(数据库)

首先还是接口的设计,设计秒杀商品的接口,在com.nnngu.service.interfaces包下建立SeckillService.java接口文件,如下图:

SeckillService.java文件里面的内容请参照项目的源代码。

建立好接口之后我们要写实现类了,在写实现类的时候我们肯定会碰到一个这样的问题,你要向前端返回json数据的话,你是返回什么样的数据好?直接返回一个数字状态码或者文字?这样设计肯定是不好的,所以我们应该向前端返回一个实体信息json,里面包含了一系列的信息,无论是哪种状态都应该可以应对,既然是与数据库字段无关的类,那就不是PO了,所以我们建立一个DTO数据传输类。关于常见的几种对象我的解释如下:

  • PO:也就是我们为每一张数据库表写一个实体类

  • VO:对某个页面或者展现层所需要的数据,封装成一个实体类

  • BO:业务对象

  • DTO:跟VO的概念有点混淆,也是相当于页面需要的数据封装成一个实体类

  • POJO:简单的无规则java对象

在com.nnngu下建立dto包,然后建立Exposer类,这个类是秒杀时数据库那边处理的结果的对象

Exposer.java文件里面的内容请参照项目的源代码。

定义秒杀中可能会出现的异常

定义一个基础的异常,所有的子异常继承这个异常SeckillException

package com.nnngu.exception;

/**
* 秒杀基础的异常
* Created by nnngu
*/
public class SeckillException extends RuntimeException {
// 代码省略,请参照项目的源代码
... ...
}

可能会出现秒杀关闭后被秒杀情况,所以建立秒杀关闭异常SeckillCloseException,需要继承我们前面写的基础异常

package com.nnngu.exception;

/**
* 秒杀已经关闭异常,当秒杀结束就会出现这个异常
* Created by nnngu
*/
public class SeckillCloseException extends SeckillException{
// 代码省略,请参照项目的源代码
... ...
}

定义重复秒杀异常RepeatKillException

package com.nnngu.exception;

/**
* 重复秒杀异常,不需要我们手动去try catch
* Created by nnngu
*/
public class RepeatKillException extends SeckillException{
// 代码省略,请参照项目的源代码
... ...
}

实现Service接口

com.nnngu.service包下创建SeckillServiceImpl.java类,具体代码请参照项目的源代码。

在这里我们捕获了运行时异常,这样做的原因就是Spring的事务默认发生了RuntimeException才会回滚,可以检测出来的异常是不会导致事务的回滚的,这样的目的就是你明知道这里会发生异常,所以你一定要进行处理。如果只是为了让编译通过的话,那捕获异常也没意思,所以这里要注意事务的回滚。

然后我们还发现这里存在硬编码的现象,就是返回各种字符常量,例如秒杀成功,秒杀失败等等,这些字符串是可以被重复使用的,而且这样维护起来也不方便,要到处去类里面寻找这样的字符串,所有我们使用枚举类来管理这样状态,在con.nnngu包下建立enums包,专门放置枚举类,然后再建立SeckillStatEnum枚举类。

枚举类SeckillStatEnum.java的代码请参照项目的源代码。

注入Service

resources/spring下建立applicationContext-service.xml文件,用来配置Service

applicationContext-service.xml的代码请参照项目的源代码。

在这里开启了基于注解的事务,常见的事务操作有以下几种方法:

  • 在Spring早期版本中是使用ProxyFactoryBean+XMl方式来配置事务。

  • 在Spring配置文件使用tx:advice+aop命名空间,好处就是一次配置永久生效,你无须去关心中间出的问题,不过出错了你很难找出在哪里出了问题。

  • 注解@Transactional的方式,注解可以在方法定义,接口定义,类定义。可以在public方法上,但是不能注解在private、final、static等方法上,因为Spring的事务管理默认是使用cglib动态代理的:

    • private方法因为访问权限限制,无法被子类覆盖
    • final方法无法被子类覆盖
    • static时类级别的方法,无法被子类覆盖
    • protected方法可以被子类覆盖,因此可以被动态字节码增强

不能被Spring AOP事务增强的方法

序号 动态代理策略 不能被事务增强的方法
1 基于JDK的动态代理 除了public以外的所有方法,并且 public static 的方法也不能被增强
2 基于cglib的动态代理 privatestaticfinal 的方法

Service层的测试

添加测试类SeckillServiceImplTest.java,如下图:

SeckillServiceImplTest.java的代码请参照项目的源代码。

测试结果:

测试的方法:public void getSeckillList()

测试结果如下图:

到此,我们成功完成了Service层开发及测试。

下一篇:03 Java高并发秒杀项目之web层

02 整合IDEA+Maven+SSM框架的高并发的商品秒杀项目之Service层的更多相关文章

  1. 03 整合IDEA+Maven+SSM框架的高并发的商品秒杀项目之web层

    Github:https://github.com/nnngu 项目源代码:https://github.com/nnngu/nguSeckill 前端交互流程设计 对于一个系统,需要产品经理.前端工 ...

  2. 01 整合IDEA+Maven+SSM框架的高并发的商品秒杀项目之业务分析与DAO层

    作者:nnngu 项目源代码:https://github.com/nnngu/nguSeckill 这是一个整合IDEA+Maven+SSM框架的高并发的商品秒杀项目.我们将分为以下几篇文章来进行详 ...

  3. 04 整合IDEA+Maven+SSM框架的高并发的商品秒杀项目之高并发优化

    Github:https://github.com/nnngu 项目源代码:https://github.com/nnngu/nguSeckill 关于并发 并发性上不去是因为当多个线程同时访问一行数 ...

  4. [JSP]Maven+SSM框架(Spring+SpringMVC+MyBatis) - Hello World

    来源:http://blog.csdn.net/zhshulin/article/details/37956105?utm_source=tuicool&utm_medium=referral ...

  5. Maven+SSM框架(Spring+SpringMVC+MyBatis) - Hello World(转发)

    [JSP]Maven+SSM框架(Spring+SpringMVC+MyBatis) - Hello World 来源:http://blog.csdn.net/zhshulin/article/de ...

  6. Java高并发秒杀API之Service层

    Java高并发秒杀API之Service层 第1章 秒杀业务接口设计与实现 1.1service层开发之前的说明 开始Service层的编码之前,我们首先需要进行Dao层编码之后的思考:在Dao层我们 ...

  7. 史上最详细的IDEA优雅整合Maven+SSM框架(详细思路+附带源码)

    目录 前言: 1. 搭建整合环境 2.Spring框架代码的编写 3.SpringMVC框架代码的编写 4. Spring整合SpringMVC的框架 5.MyBatis框架代码的编写 6. Spri ...

  8. 手把手教你整合最优雅SSM框架

    我们看招聘信息的时候,经常会看到这一点,需要具备 SSM 框架的技能, SpringMVC 可以完全替代 Struts,配合注解的方式,编程非常快捷,而且通过 restful 风格定义 url,让地址 ...

  9. Maven+SSM框架实现简单的增删改查

    Spring介绍: spring 使用基本的 JavaBean 来完成以前只可能由 EJB 完成的事情.然而, Spring的用途不仅限于服务器端的开发.从简单性.可测试性和松耦合的角度而言,任何Ja ...

随机推荐

  1. 使用XML序列化实现系统配置 - 开源研究系列文章

    在实际的C#软件系统开发过程中,会遇到系统配置的保存问题,以及系统存储问题.在以前的系统开发过程中,笔者使用的是INI文件配置管理的方式.到了现在,INI文件配置保存仍然是一个平常使用的方式.在博客园 ...

  2. javascript中对象字面量与数组字面量

    第一部分 我们知道JavaScript中的数据类型有基本数据类型和引用类型,其中Object类型就是非常常用的类型.那么如果创建一个Object类型的实例呢?下面我介绍两种方法: 第一:构造函数法. ...

  3. 转:JAVA常见错误处理方法 和 JVM内存结构

    OutOfMemoryError在开发过程中是司空见惯的,遇到这个错误,新手程序员都知道从两个方面入手来解决:一是排查程序是否有BUG导致内存泄漏:二是调整JVM启动参数增大内存.OutOfMemor ...

  4. 浅谈JavaScript的面向对象程序设计(二)

    前面介绍通过Object构造函数或者字面量创建单个对象,但是通过这个的方法创建对象有明显的缺点:调用同一个接口创建多个实例,会产生大量的重复代码.怎么样解决? 工厂模式 工厂模式是软件工程领域经常使用 ...

  5. jq选择器汇总

    $("div") //标签 $(".box") //类 $("#box") //ID $("a[href][name]" ...

  6. IDEA第八章----远程调试

    大家有没有遇到相同分支的代码在本地就是没有问题的,但是到测试环境死活不能实现功能,且还不报错.通常我们的解决办法就是打日志,然后一点一点跟踪日志. 这时我们在想如果也可以按照本地一样能断点测试的程序就 ...

  7. angular4.0配置同时使用localhost和本机IP访问项目

    之前写过<angular4.0配置本机IP访问项目>的文章,今天再次更新一个,谢谢大家的指正. 今天的目的是:使用本机IP地址,或者localhost都可以访问项目. 第一步:找到此文件& ...

  8. window64 PHP ffmpeg详解简单上手 音频amr转mp3

    从网上找了一大堆关于window 64 ffmpeg的信息,都是又长又不关键,让人难消化. 我只要简单的amr转MP3格式而已. 终于搞明白.自己总结了下! 希望能帮助到喜欢言简意赅,一眼上手的同学. ...

  9. (转)Linux下运行python

    原文: http://blog.csdn.net/jackywgw/article/details/48847187 在linux命令行下运行python,可以直接输出hello world jack ...

  10. JavaScript(二)基本概念

    JS区分大小写 html/css 中 标签选择器不区分大小写 id class 选择器区分大小写 其中属性名 属性名 属性值  不区分大小写 行间事件  onclick  等  不区分大小写 而  执 ...