02 整合IDEA+Maven+SSM框架的高并发的商品秒杀项目之Service层
作者: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的动态代理 | private ,static ,final 的方法 |
Service层的测试
添加测试类SeckillServiceImplTest.java
,如下图:
SeckillServiceImplTest.java
的代码请参照项目的源代码。
测试结果:
测试的方法:public void getSeckillList()
测试结果如下图:
到此,我们成功完成了Service层开发及测试。
下一篇:03 Java高并发秒杀项目之web层
02 整合IDEA+Maven+SSM框架的高并发的商品秒杀项目之Service层的更多相关文章
- 03 整合IDEA+Maven+SSM框架的高并发的商品秒杀项目之web层
Github:https://github.com/nnngu 项目源代码:https://github.com/nnngu/nguSeckill 前端交互流程设计 对于一个系统,需要产品经理.前端工 ...
- 01 整合IDEA+Maven+SSM框架的高并发的商品秒杀项目之业务分析与DAO层
作者:nnngu 项目源代码:https://github.com/nnngu/nguSeckill 这是一个整合IDEA+Maven+SSM框架的高并发的商品秒杀项目.我们将分为以下几篇文章来进行详 ...
- 04 整合IDEA+Maven+SSM框架的高并发的商品秒杀项目之高并发优化
Github:https://github.com/nnngu 项目源代码:https://github.com/nnngu/nguSeckill 关于并发 并发性上不去是因为当多个线程同时访问一行数 ...
- [JSP]Maven+SSM框架(Spring+SpringMVC+MyBatis) - Hello World
来源:http://blog.csdn.net/zhshulin/article/details/37956105?utm_source=tuicool&utm_medium=referral ...
- Maven+SSM框架(Spring+SpringMVC+MyBatis) - Hello World(转发)
[JSP]Maven+SSM框架(Spring+SpringMVC+MyBatis) - Hello World 来源:http://blog.csdn.net/zhshulin/article/de ...
- Java高并发秒杀API之Service层
Java高并发秒杀API之Service层 第1章 秒杀业务接口设计与实现 1.1service层开发之前的说明 开始Service层的编码之前,我们首先需要进行Dao层编码之后的思考:在Dao层我们 ...
- 史上最详细的IDEA优雅整合Maven+SSM框架(详细思路+附带源码)
目录 前言: 1. 搭建整合环境 2.Spring框架代码的编写 3.SpringMVC框架代码的编写 4. Spring整合SpringMVC的框架 5.MyBatis框架代码的编写 6. Spri ...
- 手把手教你整合最优雅SSM框架
我们看招聘信息的时候,经常会看到这一点,需要具备 SSM 框架的技能, SpringMVC 可以完全替代 Struts,配合注解的方式,编程非常快捷,而且通过 restful 风格定义 url,让地址 ...
- Maven+SSM框架实现简单的增删改查
Spring介绍: spring 使用基本的 JavaBean 来完成以前只可能由 EJB 完成的事情.然而, Spring的用途不仅限于服务器端的开发.从简单性.可测试性和松耦合的角度而言,任何Ja ...
随机推荐
- vue-router源码学习(一)
因为v3.01版本中的 /src代码使用TypeScript进行书写,我这里仅仅用作模块学习, 具体学习的还是 /dist/vue-router.js 代码. (一)基本使用方式 JS代码 // ...
- Node.js 蚕食计划(三)—— Express 启航
如果看过上一篇<Node.js 蚕食计划>,就会发现手动搭建一个 web 服务器还是比较繁琐 而 express 就是一个可以极大地提高开发效率的 web 开发框架 一.创建项目 在 ex ...
- Git添加远程库和从远程库中获取
一. Git添加远程库 1. 在本地新建一个文件夹,在该文件夹使用Git工具,运行$ git init,将该文件夹变为本地Git仓库,同时会生成一个隐藏的.git文件夹. 2. 在该文件夹中用Note ...
- spring boot RESTFul API拦截 以及Filter和interceptor 、Aspect区别
今天学习一下RESTFul api拦截 大概有三种方式 一.通过Filter这个大家很熟悉了吧,这是java规范的一个过滤器,他会拦截请求.在springboot中一般有两种配置方式. 这种过滤器拦截 ...
- Python中的单例模式的几种实现方式的优缺点及优化
单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...
- iOS 中使用 XIB 自定义cell 的两种方法 以及 编译出现常见 的错误 ++++(xcode6.0之后)
一. 注册cell 1.创建自定义cell并勾选 xib :(勾选xib就会自动生成与cell文件关联的xib) 2.在 tableViewController里注册自定义Cell (或者遵守tabl ...
- 【转载】ipcs与Linux共享内存
一.共享内存相关知识 所谓共享内存,就是多个进程间共同地使用同一段物理内存空间,它是通过将同一段物理内存映射到不同进程的 虚拟空间来实现的.由于映射到不同进程的虚拟空间中,不同进程可以直接使用,不需要 ...
- Redis in Docker on Linux Container
记录:在Docker中运行一个Redis实例当我们在Windows系统中安装好Docker以后,在Hyper-V中会自动创建一个Linux虚拟机,如果这个虚拟机没有运行,说明当前运行的是Windows ...
- 强化学习 - Q-learning Sarsa 和 DQN 的理解
本文用于基本入门理解. 强化学习的基本理论 : R, S, A 这些就不说了. 先设想两个场景: 一. 1个 5x5 的 格子图, 里面有一个目标点, 2个死亡点二. 一个迷宫, 一个出发点, ...
- Django的生命周期图解
下边的图就是一次完整的django生命周期,从客户端输入url,经过wsgi模块处理,得到符合HTTP协议的字符串,走中间件,假如中间件return None,继续往下走到urls......; 假如 ...