首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 圖書銷售系統:輔助類與配置文件架構設計

     編輯:Java 相關知識

輔助類與配置文件是系統工程化程度的體現。本文梳理圖書銷售系統中的工具類體系、常量定義、配置管理、異常處理、日誌規範與第三方集成配置,構建可維護、可擴展的基礎設施層。

配置文件體系

分層配置策略


src/main/resources/
├── application.yml              # 核心配置 (數據源、Redis、端口、上下文路徑)
├── application-dev.yml          # 開發環境覆蓋
├── application-prod.yml         # 生產環境覆蓋 (密碼加密、連接池調優)
├── application-test.yml         # 測試環境 (內存數據庫、Mock 服務)
├── logback-spring.xml           # 日誌配置 (按環境區分輸出)
├── mybatis-config.xml           # MyBatis 全局配置 (類型別名、映射器、插件)
├── mapper/                      # SQL 映射文件目錄
├── templates/                   # 郵件/短信/發票/面單模板
├── validation-messages.properties # Bean Validation 國際化訊息
└── messages.properties          # 業務錯誤碼/提示訊息 (i18n 基礎)

核心配置項示例 (application.yml)

spring:
  datasource:
    url: jdbc:mysql://${DB_HOST:localhost}:3306/bookstore?useSSL=false&serverTimezone=Asia/Shanghai
    username: ${DB_USER:root}
    password: ${DB_PASS:}
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      connection-timeout: 30000
  redis:
    host: ${REDIS_HOST:localhost}
    port: 6379
    lettuce:
      pool:
        max-active: 8
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 50MB

mybatis:
  mapper-locations: classpath:mapper/**/*.xml
  type-aliases-package: com.bookstore.domain
  configuration:
    map-underscore-to-camel-case: true
    cache-enabled: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

app:
  jwt:
    secret: ${JWT_SECRET:change-me-in-prod}
    expiration: 86400000  # 24h
  upload:
    path: /data/uploads
    cdn-prefix: https://cdn.bookstore.com
  email:
    host: smtp.exmail.qq.com
    port: 465
    ssl: true
  pagination:
    default-page-size: 20
    max-page-size: 100

核心輔助類體系

1. 統一響應封裝


// Result.java - 所有 Controller 返回統一格式
@Data @Builder @AllArgsConstructor @NoArgsConstructor
public class Result<T> {
    private int code;           // 200 成功、4xx 客戶端錯誤、5xx 服務端錯誤
    private String message;     // 用戶可讀提示
    private T data;             // 業務數據
    private long timestamp;     // 響應時間戳
    private String traceId;     // 鏈路追蹤 ID
    
    public static <T> Result<T> ok(T data) { return Result.<T>builder().code(200).message("成功").data(data).build(); }
    public static <T> Result<T> fail(String msg) { return Result.<T>builder().code(400).message(msg).build(); }
    public static <T> Result<T> fail(int code, String msg) { return Result.<T>builder().code(code).message(msg).build(); }
}

2. 異常處理體系


// BizException.java - 業務異常基類
public class BizException extends RuntimeException {
    private final int code;
    private final String userMessage;  // 給用戶看
    private final String devMessage;   // 給開發看 (含堆棧)
    // 構造器、靜態工廠方法...
}

// GlobalExceptionHandler.java - 全局異常攔截
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
    @ExceptionHandler(BizException.class)
    public Result<Void> handleBiz(BizException e, HttpServletRequest req) {
        log.warn("BizException: code={}, userMsg={}, traceId={}", e.getCode(), e.getUserMessage(), MDC.get("traceId"));
        return Result.fail(e.getCode(), e.getUserMessage());
    }
    
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<Void> handleValid(MethodArgumentNotValidException e) {
        String msg = e.getBindingResult().getFieldErrors().stream()
            .map(fe -> fe.getField() + ": " + fe.getDefaultMessage())
            .collect(Collectors.joining("; "));
        return Result.fail(400, "參數校驗失敗: " + msg);
    }
    
    @ExceptionHandler(Exception.class)
    public Result<Void> handleOther(Exception e, HttpServletRequest req) {
        log.error("Unexpected error: {}", req.getRequestURI(), e);
        return Result.fail(500, "系統繁忙,請稍後重試");
    }
}

3. 常量與枚舉定義


// OrderStatus.java - 訂單狀態機枚舉
public enum OrderStatus {
    UNPAID(0, "待付款", "UNPAID"),
    PAID(1, "已付款", "PAID"),
    SHIPPED(2, "已發貨", "SHIPPED"),
    COMPLETED(3, "已完成", "COMPLETED"),
    CANCELLED(4, "已取消", "CANCELLED"),
    REFUNDED(5, "已退款", "REFUNDED");
    
    private final int value;
    private final String label;
    private final String code;
    
    // 狀態流轉規則
    public static final Map<OrderStatus, Set<OrderStatus>> TRANSITIONS = Map.of(
        UNPAID, Set.of(PAID, CANCELLED),
        PAID, Set.of(SHIPPED, REFUNDED, CANCELLED),
        SHIPPED, Set.of(COMPLETED, REFUNDED),
        COMPLETED, Set.of(REFUNDED)
    );
    
    public boolean canTransitionTo(OrderStatus target) {
        return TRANSITIONS.getOrDefault(this, Collections.emptySet()).contains(target);
    }
}

4. 工具類精選

類名核心方法用途
SnowflakeIdUtilnextId()分布式唯一 ID (訂單號、流水號)
PriceUtilyuanToFen(), fenToYuan(), round()金額分/元轉換、銀行家圓整
BeanCopyUtilcopyProperties(), copyList()DTO/VO/Entity 互轉 (基於 MapStruct/BeanUtils)
PageUtiltoPageResult(Page<T>)MyBatis PageInfo → 統一分頁 VO
IpUtilgetClientIp(request)穿透代理獲取真實 IP
IdCardUtilmask(), validate()身份證脫敏/校驗 (實名認證)
ExcelUtilexport(), importTemplate()POI 封裝、大數據流式導出

5. 切面增強


// @OperationLog - 方法級操作審計
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME)
public @interface OperationLog {
    String module();      // 模塊: ORDER/BOOK/USER
    String action();      // 動作: CREATE/UPDATE/DELETE/EXPORT
    String description() default "";
}

// OperationLogAspect.java
@Aspect @Component @Slf4j
public class OperationLogAspect {
    @Around("@annotation(opLog)")
    public Object log(ProceedingJoinPoint pjp, OperationLog opLog) throws Throwable {
        long start = System.currentTimeMillis();
        String traceId = MDC.get("traceId");
        Object result = pjp.proceed();
        long cost = System.currentTimeMillis() - start;
        
        // 異步持久化操作日誌 (不阻塞主流程)
        logService.asyncSave(OperationLogDTO.builder()
            .traceId(traceId).module(opLog.module()).action(opLog.action())
            .operator(getCurrentUser()).method(pjp.getSignature().toShortString())
            .params(JSON.toJSONString(pjp.getArgs())).result(JSON.toJSONString(result))
            .costMs(cost).success(true).build());
        return result;
    }
}

第三方集成配置

  • 支付:微信支付 V3 / 支付寶 SDK 配置 (商戶號、私鑰、證書、回調地址)
  • 物流:快遞 100 / 騰訊地圖 / 高德地圖 Key、Secret
  • 存儲:阿里云 OSS /騰訊云 COS / MinIO (Endpoint、Bucket、AK/SK)
  • 消息:RabbitMQ / RocketMQ / Kafka (集群地址、Topic、消費組)
  • 搜索:Elasticsearch 集群地址、索引前綴、同步策略
  • 監控:Prometheus + Grafana / SkyWalking / Sentry DSN

構建與部署配置


# Dockerfile
FROM eclipse-temurin:17-jre-alpine
ARG JAR_FILE=target/bookstore-*.jar
COPY ${JAR_FILE} app.jar
ENV JAVA_OPTS="-Xms512m -Xmx1g -XX:+UseG1GC"
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar /app.jar"]

# docker-compose.yml (開發環境)
version: '3.8'
services:
  app:
    build: .
    ports: ["8080:8080"]
    environment:
      - DB_HOST=mysql
      - REDIS_HOST=redis
    depends_on: [mysql, redis]
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: bookstore
    volumes: ["mysql_data:/var/lib/mysql"]
  redis:
    image: redis:7-alpine
volumes: {mysql_data: {}}

完善的輔助類與配置體系,讓業務代碼聚焦核心邏輯,基礎設施層支撐系統穩健演進。這是從「能跑通」走向「好維護」的關鍵分水嶺。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved