B/S架构,三层架构,跟分层解耦

张开发
2026/4/13 21:33:38 15 分钟阅读

分享文章

B/S架构,三层架构,跟分层解耦
B/S架构浏览器 → Web 服务器 → 数据库即浏览器通过web服务器与数据库交互B 端浏览器S 端TomcatControllerServiceDao/Mapper数据库TomCate是标准的标准 Java Web 服务器。用于监听端口8080接收 HTTP 请求解析请求把请求交给你的项目Servlet / SpringMVC返回 HTTP 响应浏览器B ↓ HTTP 请求底层走 Socket 连接 ┌───────────────────────────┐ │ sereverSocket │ ← 网络通信通道TCP 连接,接受请求建立通道创建socket读 └───────────────────────────┘ 取数据 ↓ ┌─────────────────────┐ │ Tomcat服务器 │ ←—— 服务器容器不属于三层任何一层监听socket,接受请求 └─────────────────────┘ ↓ 把请求交给 Controller ┌─────────────────────┐ │ Controller │ ←—— 表现层三层之一 │ Service │ ←—— 业务层 │ Dao/Mapper │ ←—— 数据访问层 └─────────────────────┘ ↓ 数据库 返回是原路返回三层架构表现层Presentation Layer——Controller业务逻辑层Business Logic Layer——Service数据访问层Data Access Layer——Dao / Mapper另外还有配套的实体类层Entity/Model/Pojo不属于三层但必须一起用。表现层Controller接收前端浏览器 / Postman发来的求参数校验、简单格式处理调用 Service 层完成业务把结果封装成 JSON 返回给前端不写业务逻辑不直接操作数据库业务逻辑层Service真正写业务逻辑的地方事务控制、权限判断、数据计算、流程编排调用 Dao/Mapper 层操作数据库一个 Service 可以调用多个 Dao也可以调用其他 Service数据访问层Dao / Mapper只负责和数据库交互增删改查CRUD写 SQL 或使用 MyBatis/MyBatis-Plus/JPA不处理业务逻辑只做数据存取调用关系只能从上往下调用不能反向前端 →Controller → Service → Dao/Mapper→ 数据库标准的包结构com.xxx ├── controller │ └── UserController.java // 控制器 ├── service │ ├── UserService.java // 接口 │ └── impl │ └── UserServiceImpl.java // 实现类 ├── mapper │ └── UserMapper.java └── entity └── User.java分层的作用利于团队协作方便更改解耦....分层解耦分层把代码按职责切成三层Controller表现层接收请求、返回结果Service业务层写逻辑、判断、计算Dao/Mapper数据层操作数据库各干各的耦合就是就是类和类绑得太紧。public class UserController { private UserService userService new UserServiceImpl(); }Controller直接 new Service→ Controller 死死依赖 UserServiceImpl→ 这就叫高耦合耦合的坏处换实现类必须改源码一处改处处动代码难维护、难测试解耦就是解除这种硬绑定让类之间只依赖 “接口”不依赖具体类。解耦的操作依赖于IOC DI Bean 这套 Spring 机制IOC DI Bean1. IOC 控制反转 —— 解耦的思想IOC 前对象是你自己 new控制权在自己写的代码里IOC 之后对象由Spring 容器创建控制权从代码 → 反转给容器变成被动接2.Bean Spring 容器创建并管理的对象被IOC 注解标记类后就会被spring创建Controller、Service、Dao 这些类的实例是 由Spring 创建的放在 Spring 容器里统一管理3. DI 依赖注入 —— IOC 的具体动作。DI 做的事Spring 容器里已经有一堆 Bean 了只用在类里写AutowiredSpring 自动把对应的 Bean 赋值给你的变量全程不用 new不用管对象从哪来这就叫依赖注入。完整的讲就是先用 IOC 相关注解RestController、Service、Repository、Component标记类 → 告诉 Spring这个类要创建对象放进容器里。 Spring 项目启动时自动扫描这些类自己 new 出对象放进 Spring 容器。 容器里的这些对象就叫 Bean。 然后用 DI 注解Autowired告诉 Spring把容器里对应的 Bean 拿过来赋值给我这个变量。IOC相关注解注解归属层 / 用途使用位置核心作用RestController表现层Controller控制器类标记为 Web 接口返回 JSON前后端分离专用Controller表现层Controller控制器类标记为控制器返回页面 / 视图传统项目用Service业务层Service业务实现类标记业务逻辑类处理规则、计算、判断Repository数据访问层Dao/Mapper数据操作类标记数据库操作类自动包装数据库异常Component通用组件工具类、公共类不属于三层的通用类交给 Spring 管理Configuration配置类配置类用于编写配置、注册第三方 Bean现在//Controller RestController // 标记交给容器管理 RequestMapping(/user) public class UserController { // 连接方式注入 Service Autowired private UserService userService;//接口变量用来装它实现类对象的变量 GetMapping(/user/{id}) public User get(PathVariable Long id) { // 调用接口方法 return userService.findById(id); } // Service 接口 public interface UserService { User getById(Long id); } // Service 实现 Service public class UserServiceImpl implements UserService { // 注入 Mapper Autowired private UserMapper userMapper; Override public User findById(Long id) { // 1. 查数据库 User user userMapper.selectById(id); // 2. 业务判断 if (user null) { throw new RuntimeException(用户不存在); } // 3. 返回给 Controller return user; } } Mapper//Mapper(接口)代替了 Repository 因为MyBatis会自动生成实现类(代理对象)并交给Spring 生成Bean public interface UserMapper { // 写 SQL操作数据库 // MyBatis 帮你写的 实现类 // (你看不见但是真的存在) public class **UserMapperImpl** implements UserMapper { // 真正干活的代码 (JDBC连接数据库) } }以前public class UserController { // 1. 声明一个变量 private UserService userService; public UserController() { // 2. 自己 new 对象赋值给变量 userService new UserServiceImpl(); } }

更多文章