当前位置: 首页 > wzjs >正文

手机网站头部店铺起名网免费取名

手机网站头部,店铺起名网免费取名,wordpress网站怎么设置关键词,有了域名怎么制作网站编者想说: 作为Java开发者,我们每天都在和Spring框架打交道,但你是否真正理解过Spring项目中表现层、业务逻辑层、数据访问层这三层架构的设计逻辑?为什么需要分层?各层的职责边界在哪里?Spring又是如何通…

 

编者想说:

作为Java开发者,我们每天都在和Spring框架打交道,但你是否真正理解过Spring项目中表现层、业务逻辑层、数据访问层这三层架构的设计逻辑?为什么需要分层?各层的职责边界在哪里?Spring又是如何通过IOC和AOP支撑这种分层结构的?

本文将从底层设计思想出发,结合Spring核心特性(IOC/AOP),通过一个完整的用户登录场景,带你彻底掌握Spring三层架构的精髓。


一、为什么需要三层架构?从"面条代码"到工程化

在早期的Java Web开发中,我们经常能看到这样的代码:

// 混合了HTML拼接、数据库查询、业务逻辑的"万能Servlet"
public class UserServlet extends HttpServlet {protected void doPost(HttpServletRequest req, HttpServletResponse resp) {String username = req.getParameter("username");String password = req.getParameter("password");// 直接连接数据库查询(数据访问逻辑)Connection conn = DriverManager.getConnection(...);Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery("SELECT * FROM user WHERE username='" + username + "'");if (rs.next()) {String dbPassword = rs.getString("password");if (dbPassword.equals(password)) { // 密码校验(业务逻辑)req.setAttribute("msg", "登录成功");req.getRequestDispatcher("/success.jsp").forward(req, resp); // 视图渲染(表现逻辑)} else {req.setAttribute("msg", "密码错误");req.getRequestDispatcher("/login.jsp").forward(req, resp);}} else {req.setAttribute("msg", "用户不存在");req.getRequestDispatcher("/login.jsp").forward(req, resp);}}
}

这种表面"大而全"的代码其实里面存在的问题可是很严重的:

  • 可维护性差​:修改数据库连接方式需要改动所有Servlet
  • 可测试性低​:无法单独测试业务逻辑(依赖Servlet容器和数据库)
  • 协作效率低​:前端和后端开发人员需要频繁修改同一份代码

而我们的spring提出的三层架构,正是为了解决这些问题。它通过职责分离将复杂系统拆解为三个高内聚、低耦合的模块,让代码更易维护、扩展和测试。


二、Spring三层架构的核心定义与职责边界

Spring框架下的三层架构通常指:​表现层(Web层)、业务逻辑层(Service层)、数据访问层(DAO/Mapper层)​。各层的核心职责和Spring中的典型实现如下:

1. 表现层(Web Layer):用户交互的入口

核心职责​:处理HTTP请求/响应,负责参数校验、视图渲染(或JSON返回)、简单的参数转换。
Spring实现​:通过@Controller(返回视图)或@RestController(返回JSON)注解的类实现,配合@RequestMapping系列注解定义路由。

关键原则​:

  • 不包含业务逻辑(如密码加密、权限校验)
  • 不直接操作数据库(禁止出现JDBC/MyBatis代码)
  • 参数校验应尽量前置(如使用@Valid+JSR-380注解)

示例代码​:

@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService; // 注入Service层@PostMapping("/login")public Result login(@RequestBody @Valid LoginForm form) {// 仅做简单参数格式校验(如非空),复杂校验交给Servicereturn userService.login(form.getUsername(), form.getPassword());}
}

2. 业务逻辑层(Service Layer):系统的核心大脑

核心职责​:封装核心业务逻辑(如交易流程、权限控制、事务管理),协调多个DAO完成复杂操作,处理业务异常。
Spring实现​:通过@Service注解的类实现,使用@Transactional管理事务,通过依赖注入调用DAO层。

关键原则​:

  • 包含业务规则(如"新用户首单9折")
  • 控制事务边界(通过@Transactional注解)
  • 处理业务异常(如"库存不足"需抛出自定义异常)
  • 避免直接暴露底层数据结构(返回DTO而非Entity)

示例代码​:

@Service
@Transactional(rollbackFor = Exception.class)
public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper userMapper; // 注入DAO层@Overridepublic Result login(String username, String password) {// 1. 查询用户(调用DAO层)User user = userMapper.selectByUsername(username);if (user == null) {throw new BusinessException("用户不存在"); // 业务异常}// 2. 密码校验(业务逻辑)String encryptedPassword = BCrypt.hashpw(password, BCrypt.gensalt());if (!encryptedPassword.equals(user.getPassword())) {throw new BusinessException("密码错误");}// 3. 生成Token(附加业务操作)String token = JwtUtil.generateToken(user.getId());return Result.success(token);}
}

3. 数据访问层(DAO/Mapper Layer):数据库的翻译官

核心职责​:封装数据库操作(CRUD、复杂查询),处理SQL优化,隔离数据库方言(如MySQL/Oracle)。
Spring实现​:通过@Repository注解的接口(MyBatis Mapper)或JpaRepository(Spring Data JPA)实现,Spring自动处理JDBC连接和事务管理。

关键原则​:

  • 仅负责数据持久化(不包含业务逻辑)
  • 使用DTO/Entity与数据库表映射(避免直接操作VO)
  • 复杂查询建议使用SQL语句(而非HQL/JPQL),保证性能
  • 隔离数据库差异(如分页插件统一处理不同数据库的分页语法)

示例代码(MyBatis Mapper)​​:

@Mapper // MyBatis注解,Spring会自动生成实现类
public interface UserMapper {@Select("SELECT * FROM user WHERE username = #{username}")User selectByUsername(String username);@Insert("INSERT INTO user(username, password) VALUES(#{username}, #{password})")@Options(useGeneratedKeys = true, keyProperty = "id")int insert(User user);
}

三、以用户登录为例的请求流程

通过一个完整的用户登录流程,看三层如何协作:

  1. 表现层​:接收前端发送的JSON请求(LoginForm),通过@RequestBody反序列化。
  2. 表现层调用Service​:将参数传递给UserService.login(),不处理任何业务逻辑。
  3. Service层处理业务​:
    • 调用UserMapper.selectByUsername()查询用户(数据访问层)。
    • 校验密码(业务逻辑)。
    • 生成Token(附加业务操作)。
  4. Service返回结果​:将Result对象返回给表现层。
  5. 表现层响应前端​:将Result序列化为JSON,返回HTTP 200响应。

四、Spring分层的关键支撑技术

Spring框架通过以下核心技术,让三层架构的落地变得简单高效:

1. IOC(控制反转):解耦层间依赖

通过@Autowired注解,Spring容器自动将DAO层的实例注入到Service层,Service层的实例注入到Controller层,实现了依赖的自动管理。开发者无需手动new对象,避免了层间硬编码依赖。

2. AOP(面向切面):实现横切逻辑的解耦

通过AOP可以轻松实现日志记录、权限校验、事务管理等横切逻辑,避免将这些代码侵入三层核心业务中。例如:

@Aspect
@Component
public class LogAspect {@Around("execution(* com.example.service.*.*(..))")public Object logService(ProceedingJoinPoint joinPoint) throws Throwable {long start = System.currentTimeMillis();Object result = joinPoint.proceed();long cost = System.currentTimeMillis() - start;log.info("方法:{},耗时:{}ms", joinPoint.getSignature(), cost);return result;}
}

这段日志切面会自动拦截所有Service层方法的执行,无需在每个Service方法中手动添加日志代码。

3. 事务管理:Service层的天然屏障

Spring的@Transactional注解让事务管理变得极其简单。只需在Service方法上添加该注解,Spring会自动:

  • 开启事务(获取数据库连接,设置autoCommit=false)。
  • 执行方法内的数据库操作。
  • 若出现异常则回滚事务,否则提交事务。

五、常见误区与最佳实践

误区1:业务逻辑层"空心化"

很多新手会将本应属于Service层的业务逻辑写到Controller或DAO中,例如:

  • 在Controller中直接校验用户权限(应在Service中处理)。
  • 在DAO中拼接复杂业务SQL(如"查询用户并计算积分",应在Service中组合多个DAO调用)。

最佳实践​:Service层是业务逻辑的唯一载体,所有涉及"业务规则"的操作都应在此完成。

误区2:数据访问层"越权"操作

部分开发者会在Mapper中直接处理业务逻辑,例如:

// 错误示例:在Mapper中计算用户等级(业务逻辑)
@Select("SELECT * FROM user WHERE id = #{id}")
User selectWithLevel(@Param("id") Long id);// Mapper XML中
<resultMap id="userWithLevel" type="User"><result column="id" property="id"/><result column="username" property="username"/><result property="level" column="score" typeHandler="com.example.handler.LevelTypeHandler"/> <!-- 直接计算等级 -->
</resultMap>

最佳实践​:数据访问层仅负责数据的CRUD,业务相关的计算(如等级、状态转换)应在Service层完成。

最佳实践1:使用DTO隔离内外数据

表现层与前端交互使用VO(View Object),Service层与DAO层交互使用Entity,两者之间通过DTO(Data Transfer Object)转换,避免直接暴露数据库结构。

// VO(返回给前端)
public class UserVO {private String username;private String nickname;// getter/setter
}// Entity(数据库映射)
@Data
@TableName("user")
public class User {@TableId(type = IdType.AUTO)private Long id;private String username;private String password; // 数据库有password字段,但VO中不暴露private String nickname;
}// Service层转换
public UserVO getUserInfo(Long userId) {User user = userMapper.selectById(userId);return UserVO.builder().username(user.getUsername()).nickname(user.getNickname()).build();
}

最佳实践2:合理使用异常体系

  • 业务异常​:继承RuntimeException(如UserNotFoundException),由全局异常处理器捕获并返回友好提示。
  • 系统异常​:如数据库连接失败,由Spring默认的事务管理回滚,并记录日志。
// 全局异常处理器
@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(BusinessException.class)public Result handleBusinessException(BusinessException e) {return Result.error(e.getCode(), e.getMessage());}@ExceptionHandler(DataAccessException.class)public Result handleDataAccessException(DataAccessException e) {log.error("数据库异常", e);return Result.error(500, "服务器繁忙,请稍后再试");}
}

六、总结:三层架构的未来与演进

三层架构是Java企业级开发的基石,尽管近年来DDD(领域驱动设计)、CQRS(命令查询职责分离)等模式逐渐兴起,但三层架构的思想(职责分离、低耦合)依然是底层支撑。

对于初学者,建议先熟练掌握三层架构的规范写法;对于进阶开发者,可以结合DDD优化领域模型的设计,但切记不要为了"追新"而忽视基础架构的重要性。

最后送大家一句话:​好的架构不是设计出来的,而是演进出来的。但无论怎么演进,清晰的职责划分永远是架构设计的第一原则。​

http://www.dtcms.com/wzjs/796961.html

相关文章:

  • 森马网站建设情况网站外包开发 代码的版权问题
  • 厦门博客网站制作建一个简单的网站多少钱
  • 巫山网站开发1688代运营
  • 网站建设用什么工具网站做seo的好处
  • 五合一网站做优化好用吗wordpress代码运行
  • 蔬菜水果网站建设昆明百度小程序
  • 海外医疗手机网站建设收录网站查询
  • 北京网站开发要多少钱最美情侣免费观看
  • 网站建设 发展历程通州上海网站建设
  • PHP视频类网站应该怎么做电子商务网站建设实训
  • 安防网站模板下载无敌在线观看免费完整版高清
  • 百度网站建设怎么联系建e网怎么赚钱
  • 城乡与住房建设部网站办事大厅海外服务器 vps
  • 国内可访问的海外网站和应用什么是sem推广
  • 做网站地图的步骤网站开发技术文档格式
  • 又好又快自助建站建设银行 网站用户变成个人用户
  • 网站优化排名软件网聊城做网站比较不错的公司
  • 城乡与住房建设部网站首页电脑培训班速成班附近
  • 建站公司费用情况石家庄学生
  • 免费的网站制作表白二维码图片
  • 花都低价网站建设农业科技公司网站模板
  • 阿升网站免费学设计淘宝 网站建设教程视频
  • 网页设计与制作网站教程哪里找网站建设的兼职
  • 自己做的网站怎么弄成app湛江seo网站管理
  • 讯代理网站网站建设需要上传数据库吗
  • 软件下载站网站源码免费js调用wordpress文章列表
  • 我想做个网站 详解怎么做作品设计思路范文
  • 远近互联网站建设网站 点击率
  • 防盗网站人做清洁软件开发者路线图
  • 学校网站建立WordPress grace7主题