文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Spring Service功能有什么作用

2023-07-04 19:06

关注

本文小编为大家详细介绍“Spring Service功能有什么作用”,内容详细,步骤清晰,细节处理妥当,希望这篇“Spring Service功能有什么作用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

1. Spring项目中的核心组成部分

项目的核心组成部分图解:

Spring Service功能有什么作用

2. Spring项目中的Service

2.1 Service的功能作用

Service是项目中用于处理业务逻辑的,因为每种数据在做某种操作时,应该都有某些规则:

这些规则是用于保障数据的有效性、安全性的,使得数据可以随着我们设定的规则而产生或发生变化!

在项目中,关于Service的开发,通常是先定义接口,再定义类实现此接口,接口名通常使用“数据类型Service”这样格式的名称,而实现类通常是在接口名的基础上再添加Impl后缀。

在《阿里巴巴Java开发手册》中的规约:

【强制】对于 Service 和 DAO 类,基于 SOA 的理念,暴露出来的服务一定是接口,内部 的实现类用 Impl 的后缀与接口区别。

2.2 Service的实现

则在项目的根包下创建service.IAlbumService接口:

public interface IAlbumService {}

然后,在根包下创建service.impl.AlbumServiceImpl类,此类需要实现以上的IAlbumService接口:

public class AlbumServiceImpl implements IAlbumService {}

文件结构如下图所示:

Spring Service功能有什么作用

然后,需要在接口中设计“添加相册”的抽象方法:

xx xx(xx);

关于抽象方法的名称:可以完全自定义,当前业务是“添加相册”,可以使用addNewadd等。

关于抽象方法的参数列表:大多参数是由客户端提交到控制器,再由控制器调用时传递过来的参数,另外,也可能是控制器处理出来的某些数据(例如Session中的当前登录用户信息),本次的参数应该包含:相册名称、相册简介、相册的排序序号,可以将这3个数据封装到自定义的DTO类中,并使用DTO类型作为参数。

关于抽象方法的返回值类型:仅以操作成功为前提来设计返回值类型,如果操作失败,将抛出异常。

在项目的根包下创建pojo.dto.AlbumAddNewDTO类:

public class AlbumAddNewDTO {    private String name;    private String description;    private Integer sort;}

并在IAlbumService接口中添加抽象方法:

void addNew(AlbumAddNewDTO albumAddNewDTO);

然后,在AlbumServiceImpl中实现此抽象方法:

@Slf4j@Servicepublic class AlbumServiceImpl implements IAlbumService  {    @Autowired    private AlbumMapper albumMapper;    public AlbumServiceImpl() {        log.debug("创建业务对象:AlbumServiceImpl");    }    @Override    public void addNew(AlbumAddNewDTO albumAddNewDTO) {        // 【稍后再实现】应该保证此相册的名称是唯一的        // 创建Album类型的对象        // 调用BeanUtils.copyProperties(源对象, 目标对象)将参数的属性值复制到新创建的Album对象中// 调用albumMapper的int insert(Album album)方法插入相册数据    }}

初步实现为:

package cn.tedu.csmall.product.service.impl;import cn.tedu.csmall.product.mapper.AlbumMapper;import cn.tedu.csmall.product.pojo.dto.AlbumAddNewDTO;import cn.tedu.csmall.product.pojo.entity.Album;import cn.tedu.csmall.product.service.IAlbumService;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.BeanUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;@Slf4j@Servicepublic class AlbumServiceImpl implements IAlbumService  {    @Autowired    private AlbumMapper albumMapper;    public AlbumServiceImpl() {        log.debug("创建业务对象:AlbumServiceImpl");    }    @Override    public void addNew(AlbumAddNewDTO albumAddNewDTO) {        // 【稍后再实现】应该保证此相册的名称是唯一的        // 创建Album类型的对象        Album album = new Album();        // 调用BeanUtils.copyProperties(源对象, 目标对象)将参数的属性值复制到新创建的Album对象中        BeanUtils.copyProperties(albumAddNewDTO, album);        // 调用albumMapper的int insert(Album album)方法插入相册数据        albumMapper.insert(album);    }}

完成后,在src/test/java下的根包下创建service.AlbumServiceTests测试类,并在类中编写、执行测试方法:

package cn.tedu.csmall.product.service;import cn.tedu.csmall.product.pojo.dto.AlbumAddNewDTO;import cn.tedu.csmall.product.pojo.entity.Album;import lombok.extern.slf4j.Slf4j;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;@Slf4j@SpringBootTestpublic class AlbumServiceTests {    @Autowired    IAlbumService service;    @Test    void addNew() {        AlbumAddNewDTO album = new AlbumAddNewDTO();        album.setName("测试数据9998");        album.setDescription("测试数据的简介");        album.setSort(99); // 注意:sort值必须是[0, 255]之间的        service.addNew(album);        log.debug("添加数据完成!");    }}

在具体实现过程中,还应该保证此次尝试添加的相册的名称是唯一的!

可以通过查询数据库来得知尝试添加的相册的名称是否已经被使用,需要执行的SQL语句可以是:

select id from pms_album where name=?
select count(*) from pms_album where name=?

可以选择使用以上第2种查询来检验相册名称是否已经被使用,则应该在

AlbumMapper.java接口中添加:

int countByName(String name);

并在AlbumMapper.xml中配置SQL:

<!-- int countByName(String name); --><select id="countByName" resultType="int">    SELECT count(*) FROM pms_album WHERE name=#{name}</select>

完成后,应该在AlbumMapperTests.java中编写并执行测试:

@Testvoid countByName() {    String name = "测试数据";    int count = mapper.countByName(name);    log.debug("根据名称【{}】统计完成,结果:{}", name, count);}

接下来,可以在Service的实现过程中进行检查,例如:

String albumName = albumAddNewDTO.getName();int count = albumMapper.countByName(albumName);if (count > 0) {    // 相册名称已经被使用,将不允许添加此相册,应该抛出异常} else {    // 相册名称没有被使用,可以将此相册数据插入到数据库中}

提示:以上代码中,由于满足if条件时将抛出异常,所以,可以不必使用else,并且,在后续的编程中,当需要执行某些判断时,应该优先根据“抛出异常”或“终止当前方法的执行”来设计if的条件!即:

if (count > 0) {

// 相册名称已经被使用,将不允许添加此相册,应该抛出异常 }

// 相册名称没有被使用,可以将此相册数据插入到数据库中

具体实现为:

@Overridepublic void addNew(AlbumAddNewDTO albumAddNewDTO) {    // 应该保证此相册的名称是唯一的    String albumName = albumAddNewDTO.getName();    int count = albumMapper.countByName(albumName);    if (count > 0) {        throw new RuntimeException();    }    // 创建Album类型的对象    Album album = new Album();    // 调用BeanUtils.copyProperties(源对象, 目标对象)将参数的属性值复制到新创建的Album对象中    BeanUtils.copyProperties(albumAddNewDTO, album);    // 调用albumMapper的int insert(Album album)方法插入相册数据    albumMapper.insert(album);}

为了避免测试时因为相册名称冲突出现异常而导致测试失败,应该在测试时捕获所抛出的异常,例如:

@Testvoid addNew() {    AlbumAddNewDTO album = new AlbumAddNewDTO();    album.setName("测试数据9998");    album.setDescription("测试数据的简介");    album.setSort(99); // 注意:sort值必须是[0, 255]之间的    try {        service.addNew(album);        log.debug("添加数据完成!");    } catch (RuntimeException e) {        log.debug("添加数据失败!名称已经被占用!");    }}

关于以上实现过程中抛出的异常,使用的是RuntimeException,是不合适的!因为程序出现RuntimeException的原因有很多,例如空指针异常、数组下标越界异常、类型转换异常,都属于RuntimeException,如果“相册名称被占用”时抛出RuntimeException,则此方法的调用者很难区分出现异常的真正原因!

通常,建议自定义异常,并且,当视为失败时,抛出此自定义异常的对象!

则在根包下创建ex.ServiceException类,继承自RuntimeException

public class ServiceException extends RuntimeException {}

提示:本次自定义的异常应该继承自RuntimeException。

然后,在AlbumServiceImpl中添加相册时,如果相册名称被使用,则抛出ServiceException类型的异常:

if (count > 0) {    throw new ServiceException();}

并且,在测试中,捕获的异常也改为ServiceException

try {    service.addNew(album);    log.debug("添加数据完成!");} catch (ServiceException e) {    log.debug("添加数据失败!名称已经被占用!");}

读到这里,这篇“Spring Service功能有什么作用”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯