【黑马JavaWeb+AI知识梳理】Web后端开发08 - 总结

JavaWeb后端架构系统学习笔记

一、整体架构流程

1.1 请求-响应路径
复制代码
流程说明:
请求从浏览器发出,依次经过 过滤器 → 拦截器 → Controller → Service → Dao → 数据库
响应路径为反向流程:数据库 → Dao → Service → Controller → 拦截器 → 过滤器 → 浏览器
1.2 分层架构解析

分层架构 是JavaWeb后端开发的核心设计模式,它将复杂的系统划分为多个独立层级,每个层级专注于特定功能,显著降低了系统耦合度,提高了可维护性和扩展性 。

层级 职责 技术栈 与相邻层级关系
过滤器层 预处理/后处理所有请求 Servlet API、Filter 接收浏览器请求,传递给拦截器层
拦截器层 拦截特定请求,执行横切关注点 Spring Interceptor 接收过滤器处理后的请求,传递给Controller层
Controller层 接收前端请求,调用业务逻辑 Spring MVC、@RestController 接收拦截器处理后的请求,调用Service层
Service层 处理核心业务逻辑 Spring Service、@Transactional 接收Controller请求,协调多个Dao操作
Dao层 数据持久化操作 MyBatis、JPA、JDBC 执行Service层的数据访问指令
数据库层 存储和管理数据 MySQL、PostgreSQL 接收并执行Dao层的SQL语句
1.3 架构优势

分层架构提供了以下关键优势:

  1. 职责清晰:每个层级只关注特定功能,避免代码混杂 。
  2. 解耦性强:层级间通过接口通信,降低模块依赖 。
  3. 扩展性高:新增功能只需修改对应层级,不影响其他模块 。
  4. 复用性好:通用组件(如工具类、实体类)可跨层级复用 。
  5. 维护简便:问题定位和修复集中在特定层级,效率显著提高。

二、核心组件解析

2.1 过滤器(Filter)
2.1.1 概念与作用

过滤器 是基于Servlet规范的组件,对所有HTTP请求进行预处理和响应的后处理 。它不依赖具体业务逻辑,是Web应用的第一道防线。

2.1.2 常见用途
  • 编码设置:统一处理请求编码(如UTF-8)
  • 日志记录:记录请求路径、参数和响应时间
  • 安全防护:防止XSS攻击、CSRF攻击等
  • 请求头处理:添加或修改HTTP头信息
  • 权限校验:基础权限验证(如未登录用户重定向)
2.1.3 实现方式

通过实现Filter接口并配置web.xml或使用注解注册过滤器:

java 复制代码
public class EncodingFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
        req.setCharacterEncoding("UTF-8");
        res.setCharacterEncoding("UTF-8");
        chain.doFilter(req, res);
    }
    // 初始化和销毁方法略
}

在web.xml中配置:

xml 复制代码
<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>com.example过滤器 EncodingFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
2.2 拦截器(Interceptor)
2.2.1 概念与作用

拦截器 是Spring框架提供的组件,拦截特定请求,执行横切关注点 。与过滤器不同,拦截器仅作用于Spring管理的请求 ,更灵活且业务关联性更强。

2.2.2 与过滤器的区别
特性 过滤器 拦截器
规范 Servlet规范 Spring框架层
作用范围 所有请求 Spring管理的请求
配置方式 web.xml或注解 Spring配置类或注解
执行时机 在Servlet容器层面 在Spring MVC层面
扩展性 较低 较高
2.2.3 常见用途
  • 登录状态检查:结合Cookie/Session或JWT验证用户身份
  • 权限控制:基于角色(RBAC)或属性(ABAC)验证访问权限
  • 性能监控:记录方法执行时间,分析系统瓶颈
  • 请求参数校验:验证请求参数格式和有效性
  • 日志记录:记录业务方法执行日志
2.2.4 实现方式

通过实现HandlerInterceptor接口并注册到Spring容器 :

java 复制代码
@Component
public class AuthInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 权限校验逻辑
        return true; // 放行请求
    }
}

在Spring配置类中注册拦截器:

java 复制代码
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private AuthInterceptor authInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authInterceptor)
                .addPathPatterns("/api/**") // 拦截所有API请求
                .excludePathPatterns("/login", "/register"); // 排除登录注册接口
    }
}
2.3 Controller层
2.3.1 职责与特点

Controller层 是用户请求的入口,负责接收前端请求、调用业务逻辑并返回响应结果 。它不处理业务逻辑 ,仅作为请求的中转站。

2.3.2 技术栈与注解

主要技术栈:Spring MVC、Spring Boot、RESTful API设计

常用注解:

java 复制代码
@RestController  // 表示这是一个RESTful控制器,返回数据直接序列化为JSON
@RequestMapping("/api/user")  // 定义基础请求路径
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/{id}")  // 处理GET请求
    public ResponseEntity<User> getUser(@PathVariable Long id) {
        User user = userService.findById(id);
        return ResponseEntity.ok(user);
    }

    @PostMapping  // 处理POST请求
    public ResponseEntity<User> createUser(@Valid @RequestBody UserCreateRequest request) {
        User user = userService.createUser(request);
        return ResponseEntity.created(URI.create("/api/user/" + user.getId())).body(user);
    }
}
2.3.3 参数接收方式

Spring MVC提供了多种参数接收方式,根据需求灵活选择:

  • @RequestParam:接收查询参数或请求体中的简单参数
  • @RequestBody:接收请求体中的复杂对象(如JSON数据)
  • @PathVariable:接收URL中的动态路径参数
  • @CookieValue:接收请求中的Cookie值
  • @SessionAttribute:接收Session中的属性值
2.4 Service层
2.4.1 职责与特点

Service层 是业务逻辑的核心,封装系统的核心业务规则和流程 。它通常不直接与数据库交互 ,而是通过调用Dao层实现数据访问 。Service层是事务管理的主要场所 ,保证业务操作的原子性。

2.4.2 技术栈与注解

主要技术栈:Spring Service、事务管理、AOP

常用注解:

java 复制代码
@Service  // 表示这是一个业务服务类
public class UserService {
    @Autowired
    private UserMapper userMapper;

    @Transactional  // 声明事务管理
    public void updateUser(User user) {
        userMapper.update(user);
        // 其他业务操作...
    }
}
2.5 Dao层(Data Access Object)
2.5.1 职责与特点

Dao层 负责与数据库交互 ,执行数据的增删改查操作 。它不包含业务逻辑 ,仅专注于数据访问 。在Spring框架中,通常通过JDBC、MyBatis或JPA实现。

2.5.2 实现方式

MyBatis实现:

java 复制代码
@Mapper  // 声明这是一个MyBatis映射接口
public interface UserMapper {
    @Select("SELECT * FROM user WHERE id = #{id}")
    User getUserById(Long id);

    @Update("UPDATE user SET name = #{name}, age = #{age} WHERE id = #{id}")
    void updateUser(User user);
}

JPA实现:

java 复制代码
@Repository  // 声明这是一个数据访问层组件
public interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findByName(String name);
    List<User> findByAgeLessThanEqual(Integer maxAge);
}

三、核心技术栈支持

3.1 IOC(Inversion of Control)控制反转
3.1.1 概念

IOC是Spring框架的核心思想 ,将对象的创建和管理权从程序员转移到Spring容器 。对象的依赖关系通过容器自动装配 ,而非手动创建。

3.1.2 实现机制

Spring容器通过反射机制 和工厂模式实现IOC :

  1. 读取配置:从XML或注解中获取Bean定义
  2. 实例化对象:根据类信息动态创建实例
  3. 依赖注入:根据依赖关系自动注入其他Bean
  4. 管理生命周期:控制Bean的初始化和销毁时机
3.1.3 容器类型

Spring提供了两种主要IOC容器:

容器类型 特点 适用场景
BeanFactory 基础容器,延迟加载,轻量级 资源受限环境,如移动端
ApplicationContext 扩展型容器,支持预初始化单例、事件机制等 企业级应用,如Web应用
3.2 DI(Dependency Injection)依赖注入
3.2.1 概念

DI是IOC的具体实现方式 ,通过容器自动将对象依赖注入到目标对象中 。它解决了传统开发中手动管理依赖的繁琐问题 ,使代码更简洁、可维护性更高。

3.2.2 注入方式

Spring支持两种主要依赖注入方式:

构造器注入 :通过构造方法传递依赖,强制依赖不可变 ,适合强制依赖场景 。

java 复制代码
@Service
public class UserService {
    private final IDEAcess Dal;

    @Autowired
    public UserService(IDataAccess Dal) {
        this.Dal = Dal;
    }
}

设值注入 :通过setter方法或字段注解注入依赖,灵活性更高 ,适合可选依赖场景 。

java 复制代码
@Service
public class UserService {
    @Autowired
    private IDEAcess Dal;
}
3.2.3 依赖管理

通过**@Autowired或@Resource**注解实现自动装配 :

java 复制代码
@Autowired
private IDEAcess Dal;  // 自动注入IDEAcess类型的Bean
3.3 AOP(Aspect Oriented Programming)面向切面编程
3.3.1 概念

AOP是Spring框架的另一个核心特性 ,通过横切面(Aspect)将通用功能(如日志、事务)与业务逻辑分离 。它解决了传统开发中重复代码的问题 ,使代码更简洁、可维护性更高。

3.3.2 通知类型

Spring AOP支持五种主要通知类型:

通知类型 注解 执行时机 典型应用场景
前置通知 @Before 目标方法执行前 方法调用前记录日志
后置通知 @After 目标方法执行后 方法调用后释放资源
返回后通知 @AfterReturning 方法正常返回后 方法成功执行后的记录
异常通知 @AfterThrowing 方法抛出异常后 方法异常时的错误处理
环绕通知 @Around 完全围绕目标方法 事务管理、方法执行计时
3.3.3 切点表达式

切点表达式 用于定义哪些方法会被AOP拦截 :

java 复制代码
@Aspect
@Component
public class LoggingAspect {
    // 定义切点:拦截所有Service层的方法
    @Pointcut("execution(* com.example.service.*.*(..))")
    private void serviceMethods() {}

    // 定义切点:拦截所有带有@Log注解的方法
    @Pointcut("@annotation(com.example.annotation.Log)")
    private void logAnnotatedMethods() {}

    // 使用切点
    @Before("serviceMethods() || logAnnotatedMethods()")  // 拦截Service层方法或带有@Log注解的方法
    public void logBefore(JoinPoint joinPoint) {
        String method = joinPoint.getSignature().getName();
        String args = Arrays.toString(joinPoint.getArgs());
        System.out.println("方法调用前: " + method + " 参数: " + args);
    }
}
3.3.4 实际应用场景

AOP在JavaWeb中的典型应用:

  1. 日志记录:记录方法执行前后的信息
  2. 事务管理:通过@Around通知实现事务控制
  3. 权限控制:在方法执行前验证用户权限
  4. 性能监控:记录方法执行时间,分析系统瓶颈
  5. 异常处理:统一处理方法抛出的异常
3.4 事务管理
3.4.1 概念

事务管理 确保一系列数据库操作要么全部成功,要么全部失败 ,保证数据的一致性和完整性 。在JavaWeb中,通常通过Spring的声明式事务管理实现。

3.4.2 传播行为

事务传播行为 定义方法调用时如何处理事务 :

传播行为 注解值 行为说明 适用场景
Required 传播行为值 支持当前事务,无则新建 大多数业务方法
RequiresNew 传播行为值 挂起当前事务,新建独立事务 需要独立事务的方法
Never 传播行为值 禁止事务,若存在则抛异常 必须非事务的方法
Mandatory 传播行为值 必须在事务中执行 必须事务的方法
Support 传播行为值 支持事务但不强制 可选事务的方法
3.4.3 隔离级别

事务隔离级别 定义事务之间如何隔离 ,平衡并发性能与数据一致性 :

隔离级别 注解值 特点 适用场景
默认 默认值 使用数据库默认级别(通常为READ_COMMITTED) 大多数场景
读未提交 隔离级别值 允许脏读,但并发性能高 对一致性要求不高的场景
读已提交 隔离级别值 禁止脏读,允许不可重复读 一般业务场景
可重复读 隔离级别值 禁止脏读和不可重复读,但允许幻读 需要高一致性的场景
序列化 隔离级别值 串行化事务,完全隔离但性能差 对一致性要求极高的场景
3.4.4 事务管理实现

通过@Transactional注解实现声明式事务管理 :

java 复制代码
@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;

    @Transactional propagation =传播行为, isolation =隔离级别)
    public void updateUser(User user) {
        userMapper.update(user);
        // 其他业务操作...
    }
}
3.5 全局异常处理
3.5.1 概念

全局异常处理 将异常捕获和处理逻辑集中管理 ,避免在每个方法中重复编写异常处理代码 。它提高了代码的复用性和可维护性。

3.5.2 实现方式

通过@ControllerAdvice注解实现 :

java 复制代码
@ControllerAdvice
@RestController
public class GlobalExceptionHandler {
    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    // 捕获参数缺失异常
    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    public Result handleMissingParam(MissingServletRequestParameterException ex) {
        logger.error("缺少必要参数: {}", ex.getMessage());
        return Result.error(400, "缺少必要参数", ex.getMessage());
    }

    // 捕获空指针异常
    @ExceptionHandler(NullPointerException.class)
    public Result handleNullPointerException(NullPointerException ex) {
        logger.error("空指针异常: {}", ex.getMessage());
        return Result.error(500, "系统内部错误", "空指针异常");
    }

    // 捕获自定义业务异常
    @ExceptionHandler(BusinessException.class)
    public Result handleBusinessException(BusinessException ex) {
        logger.error("业务异常: {}", ex.getMessage());
        return Result.error(ex码, ex信息, ex详情);
    }
}
3.5.3 异常封装

建议将异常封装为统一格式 :

json 复制代码
{
    "code": 状态码(数字),
    "msg": 中文解析(字符串),
    "data": 返回数据(对象),
    "traceId": 请求追踪ID(字符串)
}

四、辅助功能模块

4.1.1 概念

Cookie 是存储在客户端的小型文本数据 ,通常用于标识用户身份 。Session 是服务器端存储的用户状态信息 ,与Cookie配合使用实现用户身份保持 。

4.1.2 配置与使用

Cookie操作:

java 复制代码
// 设置Cookie
@GetMapping("/set-cookie")
public String setCookie(HttpServletResponse response) {
    Cookie cookie = new Cookie("user_token", "abc123");
    cookie.setMaxAge(3600);  // 有效期1小时
    cookie.setPath("/");  // 全站有效
    cookie.setHttpOnly(true);  // 防止XSS攻击
    response.addCookie cookie);
    return "Cookie设置成功";
}

// 读取Cookie
@GetMapping("/read-cookie")
public String readCookie(@CookieValue(name = "user_token", defaultValue = "") String token) {
    if (token.isEmpty()) {
        return "未找到用户Token";
    }
    return "当前用户Token: " + token;
}

// 删除Cookie
@GetMapping("/delete-cookie")
public String deleteCookie(HttpServletResponse response) {
    Cookie cookie = new Cookie("user_token", null);
    cookie.setMaxAge(0);  // 立即过期
    response.addCookie cookie);
    return "Cookie已删除";
}

Session配置:

在application.properties中设置Session超时时间:

properties 复制代码
server.servlet.session.timeout=30m  # Session有效期30分钟

Session操作:

java 复制代码
// 设置Session属性
@GetMapping("/set-session")
public String setSession(HttpServletRequest request) {
    HttpSession session = request.getSession();
    session.setAttribute("cart", Arrays.asList("item1", "item2"));
    return "Session数据已存储";
}

// 读取Session属性
@GetMapping("/get-session")
public String getSession(HttpServletRequest request) {
   (HttpSession session = request sessions);
    List<String> cart = (List<String>) session.getAttribute("cart");
    return "购物车内容: " + (cart != null ? cart : "空");
}
4.1.3 分布式Session管理

在微服务架构中,推荐使用Redis实现分布式Session共享 :

依赖引入:

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
</dependency>

配置文件:

properties 复制代码
spring redis host=localhost
spring redis port=6379
spring session store-type=redis

启用Redis Session:

java 复制代码
@EnableRedisHttpSession
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
4.2 JWT(JSON Web Token)
4.2.1 概念

JWT是一种基于令牌的无状态认证方案 ,将用户信息加密后存储在令牌中 ,服务端无需存储Session 。它特别适合分布式系统和移动端应用。

4.2.2 JWT结构

一个标准的JWT由三个部分组成:

  1. Header(头部):声明令牌类型和加密算法
  2. Payload(负载):存储用户信息和声明(如过期时间)
  3. Signature(签名):验证令牌完整性和来源

三部分之间用英文句点分隔,格式为:

复制代码
Header base64Url编码 . Payload base64Url编码 . Signature
4.2.3 JWT工具类实现

使用JJWT库生成和解析JWT :

java 复制代码
@Component
public class JWTUtil {
    // 从配置文件获取密钥
    @Value("${jwt秘密}")
    private String secret;

    // 生成JWT
    public String generateToken(Map<String, Object> claims) {
        return JWT.create()
                .withClaim("个人信息", claims)
                .withExpiresAt(new Date(System.currentTimeMillis() + 3600000))  // 1小时后过期
                .sign(Algorithm.HMAC256(secret));
    }

    // 解析JWT
    public DecodedJWT decodeToken(String token) {
        try {
            return JWT.decode(token);
        } catch (JWTVerificationException ex) {
            throw new JWTDecodeException("无效的Token", ex);
        }
    }

    // 验证JWT有效性
    public boolean validateToken(String token) {
        try {
            DecodedJWT decodedJWT = decodeToken(token);
            return !decodedJWT.is糖过期();
        } catch (JWTDecodeException ex) {
            return false;
        }
    }

    // 获取JWT中的用户信息
    public Map<String, Object> getUserInfo(String token) {
        DecodedJWT decodedJWT = decodeToken(token);
        return decodedJWT.getClaim("个人信息").asMap();
    }
}
4.2.4 JWT拦截器实现

自定义拦截器验证JWT令牌 :

java 复制代码
@Component
public class JWTInterceptor implements HandlerInterceptor {
    @Autowired
    private JWTUtil jwtUtil;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 从请求头获取Token
        String token = request.getHeader("Authorization");
        if (token == null) {
            // 从请求参数获取Token
            token = request.getParameter("token");
        }

        // 验证Token
        if (token == null || !jwtUtil.validateToken(token)) {
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            response.setContentType("application/json");
            try {
                response.getWriter().write JSON格式的错误响应);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return false; // 拒绝访问
        }

        // 将用户信息存入请求属性
        Map<String, Object> userInfo = jwtUtil.getUserInfo(token);
        request.setAttribute("个人信息", userInfo);

        return true; // 放行请求
    }
}
4.2.5 安全最佳实践

JWT安全配置建议:

  1. 密钥管理:使用环境变量存储JWT密钥,避免硬编码
  2. IP绑定:在Payload中设置客户端IP,验证时检查IP一致性
  3. 加密算法:使用AES等强加密算法保护Token
  4. 设置合理过期时间:根据业务场景设置Token有效期
  5. 定期更新密钥:定期更换JWT签名密钥,降低密钥泄露风险
4.3 阿里云OSS
4.3.1 概念

阿里云OSS是对象存储服务 ,用于存储和管理非结构化数据(如图片、视频) 。它提供了高可用、高可靠的存储解决方案 ,适合Web应用的静态资源存储。

4.3.2 配置与使用

依赖引入:

xml 复制代码
<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.19.0</version>
</dependency>

配置文件:

properties 复制代码
# 阿里云OSS配置
oss endpoint=oss-cn-hangzhou.aliyuncs.com
oss bucket name=my-bucket
oss access key id=YOUR_ACCESS_KEY_ID
oss access key secret=YOUR_ACCESS_KEY_SECRET

文件上传示例:

java 复制代码
@RestController
@RequestMapping("/api/oss")
public class OSSController {
    @Value("${oss endpoint}")
    private String endpoint;
    @Value("${oss bucket name}")
    private String bucketName;
    @Value("${oss access key id}")
    private String accessKeyId;
    @Value("${oss access key secret}")
    private String accessKeySecret;

    @PostMapping("/upload")
    public Result uploadFile(@RequestParam("file") MultipartFile file) {
        try {
            // 创建OSS客户端
            OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);

            // 上传文件
            String key = "images/" + UUID.randomUUID().toString() + "." + file.getExtension();
            ossClient.putObject(bucketName, key, file.getInputStream());

            // 关闭客户端
            ossClient.close();

            // 返回文件URL
            String url = "https://"+ bucketName + "." + endpoint + "/" + key;
            return Result.success(url);
        } catch (IOException e) {
            e.printStackTrace();
            return Result.error("文件上传失败");
        }
    }
}

文件下载示例:

java 复制代码
@GetMapping("/download/{key}")
public void downloadFile(HttpServletRequest request, HttpServletResponse response, @PathVariable String key) {
    try {
        // 创建OSS客户端
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);

        // 获取文件信息
        ObjectListing listing = ossClient.listObjects (bucketName, key);
        OSSObject ossObject = ossClient.getObject (bucketName, key);

        // 设置响应头
        response.reset();
        response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(key, "UTF-8"));
        response.addHeader("Content-Type", ossObject.getMetadata().getContentType());
        response.addHeader("Content-Length", String.valueOf(ossObject.getMetadata(). ContentLength));

        // 将文件流写入响应
       IOUtils.copy(ossObject.getObjectContent(), response.getOutputStream());

        // 关闭客户端
        ossClient.close();
    } catch (Exception e) {
        e.printStackTrace();
        response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
    }
}
4.3.3 安全配置建议

OSS安全配置建议:

  1. 最小权限原则:为RAM用户分配最小必要权限
  2. 开启防盗链:防止他人直接访问OSS资源
  3. 设置合理的过期时间:为临时访问链接设置过期时间
  4. 使用HTTPS:确保数据传输安全
  5. 定期轮换密钥:降低密钥泄露风险
4.4 MyBatis
4.4.1 概念

MyBatis是持久层框架 ,通过XML或注解配置SQL语句 ,简化了JDBC操作 。它提供了灵活的数据库操作能力 ,适合复杂SQL场景。

4.4.2 整合Spring Boot

依赖引入:

xml 复制代码
<dependency>
    <groupId>org mybatis spring. boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.0</version>
</dependency>

配置文件:

properties 复制代码
# MyBatis配置
mybatis mapper locations=classpath:mapper/*.xml
mybatis typealiases package=com.example entity
mybatis configuration map underying column with骆驼命名法=true

动态SQL示例:

xml 复制代码
<select id="getUserByCondition" resultType="User">
    SELECT * FROM user
    <where>
        <if test="name != null and name != ''">
            AND name LIKE CONCAT('%', #{name}, '%')
        </if>
        <if test="age != null">
            AND age = #{age}
        </if>
        <if test="status != null">
            AND status = #{status}
        </if>
    </where>
    ORDER BY id DESC
</select>

注解方式:

java 复制代码
@Mapper
public interface UserMapper {
    @Select("SELECT * FROM user WHERE id = #{id}")
    User getUserById(Long id);

    @Insert("INSERT INTO user (name, age) VALUES (#{name}, #{age})")
    @Options(keyProperty = "id", useActualParamName = true)
    void insertUser(User user);

    @Update("UPDATE user SET name = #{name}, age = #{age} WHERE id = #{id}")
    void updateUser(User user);

    @Delete("DELETE FROM user WHERE id = #{id}")
    void.deleteUser(Long id);
}
4.4.4 安全配置建议

MyBatis安全配置建议:

  1. 使用参数化查询 :避免SQL注入,使用#{param}而非${param}
  2. 开启SQL日志:调试阶段开启,生产环境关闭
  3. 设置合理的超时时间:防止长时间等待导致资源浪费
  4. 使用连接池:如HikariCP,提高数据库连接效率
  5. 定期检查SQL性能:使用Explain分析慢查询

五、架构总结与最佳实践

5.1 架构总结

JavaWeb后端架构具有以下核心特点:

  1. 分层清晰:从浏览器到数据库的明确请求-响应路径
  2. 职责分明:各层专注自身任务,降低耦合
  3. 扩展性强:易于引入新功能(如Redis缓存、消息队列)
  4. 安全可控:通过拦截器和JWT实现权限控制
  5. 性能可调:通过缓存、索引优化提升系统性能
  6. 可维护性高:分层设计使问题定位和修复更高效
5.2 最佳实践建议
5.2.1 模块化设计

按功能+层次组合拆分模块 :

text 复制代码
项目名/
├── parent/               # 父工程,管理依赖和配置
├── common/                # 公共模块
│   ├── config/            # 配置文件
│   ├── utils/             # 工具类
│   └── entity/            # 实体类
├── order/                  # 订单模块
│   ├── controller/
│   ├── service/
│   └── mapper/
├── user/                   # 用户模块
│   ├── controller/
│   ├── service/
│   └── mapper/
└── web/                    # Web入口模块
5.2.2 安全实践

安全是JavaWeb架构的核心考量:

  1. 输入验证:对所有用户输入进行验证,防止注入攻击
  2. 权限控制:实现细粒度权限管理,如RBAC或ABAC模型
  3. 加密传输:使用HTTPS确保数据传输安全
  4. 定期安全审计:检查系统漏洞和配置问题
  5. 使用安全框架:如Spring Security、Shiro等
5.2.3 性能优化

性能优化是JavaWeb架构的关键:

  1. 缓存策略:使用Redis缓存高频访问数据

    java 复制代码
    @Cacheable(value = "users", key = "#id")
    public User getUserById(Long id) {
        return userMapper.getUserById(id);
    }
  2. 数据库优化:合理设计索引,避免全表扫描

    sql 复制代码
    CREATE INDEX idx_user_name ON user(name);
  3. 异步处理:使用消息队列处理耗时操作

    java 复制代码
    @Async
    public void sendEmail(User user, String content) {
        // 发送邮件逻辑
    }
  4. 连接池管理:配置合理的数据库连接池参数

    properties 复制代码
    spring.datasource.hikari.maximum-pool-size=20
    spring.datasource.hikari.minimum-idle=5
  5. 监控与日志:使用ELK栈或Spring Boot Actuator监控系统状态

5.2.4 部署实践

现代部署实践提升系统可用性:

  1. 容器化部署:使用Docker容器化应用

    dockerfile 复制代码
    FROM openjdk:17-jre-slim
    VOLUME /tmp
    COPY target/*.jar app.jar
    ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
  2. 微服务架构:使用Spring Cloud实现微服务

    java 复制代码
    @SpringBootApplication
    @EnableEurekaClient  // 服务注册
    public class User服务中心 {
        public static void main(String[] args) {
            SpringApplication.run(User服务中心.class, args);
        }
    }
  3. 配置中心:使用Spring Cloud Config实现动态配置

    properties 复制代码
    # 配置中心地址
    spring.config尿服务器=http://config-server:8888
  4. 服务网关:使用Spring Cloud Gateway实现统一入口

    yaml 复制代码
    spring:
      cloud:
        gateway:
          routes:
          - id: user-service
            uri: lb://USER-SERVICE
            predicates:
            - Path=/api/user/**
  5. 断路器模式:使用Hystrix或Resilience4j实现容错

    java 复制代码
    @HystrixCommand(fallbackMethod = "fallback")
    public User getUserById(Long id) {
        return userMapper.getUserById(id);
    }
    
    public User fallback(Long id) {
        // 回退逻辑
        return new User(id, "匿名用户", 0);
    }
5.2.5 监控与维护

完善的监控体系是架构成功的关键:

  1. 健康检查:使用Spring Boot Actuator提供健康检查端点

    properties 复制代码
    management端点 enabled end points=health,info,env
    management端点暴露端点=web
  2. 日志管理:使用ELK栈集中管理日志

    java 复制代码
    @Value("${log.level}")
    private String logLevel;
    
    @Bean
    public滚筒文件日志配置配置() {
        Logback滚筒文件日志配置配置 = new滚筒文件日志配置();
        configuration.setFile(logPath + "/app.log");
        configuration.set contexts contexts);
        configuration.set contexts contexts);
        return configuration;
    }
  3. 性能监控:使用Prometheus+Grafana监控系统性能

    java 复制代码
    @Bean
    public米特里克斯() {
        return new米特里克斯();
    }
    
    @Bean
    public斯普林米特里克斯配置() {
        SpringMetricsConfig config = new SpringMetricsConfig();
        config.set contexts contexts);
        return config;
    }
  4. 自动化测试:使用JUnit5、Mockito进行单元测试和集成测试

    java 复制代码
    @SpringBootTest
    @AutoConfiguration类
    class UserServiceTest {
        @Autowired
        private UserService userService;
    
        @MockBean
        private UserMapper userMapper;
    
        @Test
        void测试获取用户信息() {
            // 模拟数据库返回
            User user = new User(1L, "测试用户", 25);
            when(userMapper.getUserById(1L)).thenReturn(user);
    
            // 调用服务方法
            User result = userService.getUserById(1L);
    
            // 验证结果
            assertEquals("测试用户", result.getName());
        }
    }
  5. 持续集成:使用Jenkins或GitHub Actions实现自动化构建和测试

    yaml 复制代码
    name: Java CI with Maven
    
    on:
      push:
        branches: [main]
      pull_request:
        branches: [main]
    
    jobs:
      build:
        runs-on: ubuntu-latest
    
        steps:
        - uses: actions/checkout@v2
        - name: Set up JDK 17
          uses: actions/setup-java@v2
          with:
            java-version: '17'
            distribution: 'temurin'
        - name: Build with Maven
          run: mvn clean package -DskipTests
        - name: Run tests
          run: mvn test
5.3 架构演进路径

JavaWeb架构可随系统规模发展而演进:

  1. 单体架构:小型项目,所有功能集中在单一应用
  2. 模块化单体架构:中型项目,按功能或层次拆分模块
  3. 微服务架构:大型分布式系统,按业务拆分服务
  4. 云原生架构:超大规模系统,使用容器化和Serverless技术

六、补充知识

6.1 分层架构设计原则

分层架构应遵循以下核心原则:

  1. 高内聚:每个层级内部功能紧密相关,减少内部冗余
  2. 低耦合:层级间依赖最小化,通过接口通信
  3. 单一职责:每个层级只关注单一功能,避免职责混杂
  4. 可替换性:层级可独立替换,如替换数据库或认证方式
  5. 清晰边界:层级间有明确的接口定义和数据格式
6.2 模块间依赖管理

模块间依赖应遵循以下规则:

  1. 单向依赖:层级间依赖方向一致,避免循环依赖
  2. 接口隔离:上层通过接口调用下层,而非直接依赖实现类
  3. 依赖版本统一:使用父工程的dependencyManagement统一管理依赖版本
  4. 避免过度拆分:模块粒度适中,避免因拆分过多增加维护成本
  5. 考虑未来扩展:预留接口和扩展点,便于后续功能扩展
6.3 代码规范与风格

良好的代码规范是架构成功的基础:

  1. 命名规范 :清晰表达含义,如User服务中心、UserMapper
  2. 注释规范:关键逻辑添加注释,但避免过度注释
  3. 异常处理:统一异常处理策略,避免重复代码
  4. 日志规范:使用统一的日志框架和格式
  5. 代码复用:提取公共代码为工具类或父类,提高复用性

七、常见问题与解决方案

7.1 依赖冲突问题

现象:编译或运行时出现类冲突

解决方案:

  1. 使用mvn dependency:tree分析依赖树
  2. 通过<exclusion>排除冲突依赖
  3. 在父工程<dependencyManagement>中统一版本
7.2 构建顺序问题

现象:模块间依赖关系导致构建失败

解决方案:

  • 在聚合工程<modules>标签中声明模块顺序
  • 确保子模块pom.xml正确声明依赖关系
  • 使用<dependency>标签明确指定依赖范围
7.3 事务管理问题

现象:事务未按预期提交或回滚

解决方案:

  1. 确保Service层方法使用@Transactional注解
  2. 检查事务传播行为和隔离级别设置
  3. 避免在Service层内部调用其他Service方法,使用AOP或代理模式
7.4 JWT安全问题

现象:Token被截获或篡改

解决方案:

  1. 使用强加密算法(如AES)保护Token
  2. 实现Token IP绑定,验证请求IP与Payload中的IP是否一致
  3. 设置合理的Token过期时间,避免长期有效
  4. 定期轮换签名密钥,降低密钥泄露风险
  5. 实现Token黑名单机制,支持主动失效
7.5 数据库性能问题

现象:查询速度慢,系统响应延迟高

解决方案:

  1. 使用Explain分析慢查询
  2. 合理设计索引,避免全表扫描
  3. 使用缓存(如Redis)减少数据库访问次数
  4. 分库分表处理大数据量场景
  5. 使用连接池管理数据库连接

八、面试高频考点

8.1 分层架构设计

高频问题:

  • 请描述JavaWeb的分层架构及其各层职责
  • 过滤器和拦截器的区别是什么?
  • Controller层为什么不应该包含业务逻辑?

回答要点:

  • 分层架构包括:浏览器层、过滤器层、拦截器层、Controller层、Service层、Dao层、数据库层
  • 过滤器基于Servlet规范,作用于所有请求;拦截器基于Spring框架,仅拦截Spring管理的请求
  • Controller层负责接收请求和返回响应,业务逻辑应放在Service层,保持职责清晰
8.2 IOC/DI原理

高频问题:

  • 什么是IOC?其核心思想是什么?
  • DI和IOC的关系是什么?
  • Spring的依赖注入有哪些方式?

回答要点:

  • IOC(控制反转)将对象创建和管理权从程序员转移到容器
  • DI(依赖注入)是IOC的具体实现方式,通过容器自动注入依赖
  • Spring支持设值注入(setter注入)和构造器注入两种主要方式
8.3 AOP应用

高频问题:

  • 什么是AOP?与OOP的区别是什么?
  • Spring AOP支持哪些通知类型?
  • 如何实现一个日志记录的AOP切面?

回答要点:

  • AOP通过横切面将通用功能与业务逻辑分离,解决OOP中重复代码问题
  • Spring AOP支持前置通知、后置通知、返回后通知、异常通知和环绕通知
  • 使用@Aspect注解定义切面,@Before、@After等注解定义通知,@Pointcut定义切点
8.4 事务管理

高频问题:

  • Spring事务传播行为有哪些?
  • 事务隔离级别如何选择?
  • 如何保证分布式系统中的事务一致性?

回答要点:

  • 常见传播行为包括REQUIRED、REQUIRES_NEW、NEVER等
  • 隔离级别根据业务需求选择,默认为READ_COMMITTED
  • 分布式事务可使用TCC、Saga或Seata等方案实现
8.5 JWT认证

高频问题:

  • JWT认证原理是什么?
  • JWT与Session认证的区别是什么?
  • 如何保证JWT的安全性?

回答要点:

  • JWT将用户信息加密后存储在令牌中,服务端无需存储Session
  • JWT适合分布式系统和移动端,Session适合传统Web应用
  • JWT安全性通过密钥管理、IP绑定、加密算法和合理过期时间保证
8.6 分布式架构

高频问题:

  • 微服务架构有哪些优势?
  • 如何实现微服务间的通信?
  • 如何解决微服务中的配置管理问题?

回答要点:

  • 微服务架构优势包括服务自治、高扩展性、技术栈灵活等
  • 微服务通信可通过REST API、RPC(如Dubbo)或消息队列(如RabbitMQ)实现
  • 使用Spring Cloud Config或Nacos实现微服务配置中心

九、总结

JavaWeb后端架构是构建企业级应用的基础 ,掌握其核心组件和技术栈对开发高质量应用至关重要 。分层架构通过职责分离和接口定义,提供了良好的可维护性和扩展性 。IOC/DI和AOP等Spring核心功能,使开发更加简洁高效 。随着系统规模扩大,架构可从单体逐步演进到微服务和云原生架构 ,适应不同业务需求。

在实际开发中,应根据项目规模和团队能力选择合适的架构复杂度 。小型项目可采用模块化单体架构 ,中大型项目推荐使用微服务架构 。无论选择哪种架构,都应遵循分层设计原则,确保系统清晰、安全、高效 。

相关推荐
Rain的Java大神之路3 分钟前
10 万人抢 2000 个座位,电影票选座系统怎么防超卖?一文讲透大厂高频场景题
java·后端·面试
武子康6 分钟前
用户说“算了”,设备指令真的取消了吗?
人工智能·后端·agent
砚底藏山河9 分钟前
量化新手误区:因子计算与行情数据的工程化解耦
java·数据库·python·金融
威哥爱编程12 分钟前
【AI全栈12-07】Spring Boot 用 Agent 自动完成多步运营任务
java·spring boot·后端
未秃头的程序猿15 分钟前
我用 Spring AI + MCP 把公司内部系统接给了 AI,过程没想象中顺利
java·后端
m0_5873830028 分钟前
碰碰好评卡功能落地实战 从需求梳理到上线部署全流程实操指南
java·linux·服务器·前端·javascript·vue.js·人工智能
geovindu44 分钟前
rust: Chain of Responsibility Pattern (续)
开发语言·后端·设计模式·rust·责任链模式·行为模式
诚心呈意共享外卖配送系统1 小时前
多平台订单聚合系统的技术架构:接 API 只是开始
java·开发语言·架构·系统架构·创业创新
Java爱好狂.1 小时前
Java小白如何三天速通redis?
java·数据库·redis·架构师·分布式锁·java面试·java程序员
大风起兮云飞扬丶1 小时前
Java——多线程
java