Skip to content
清晨的一缕阳光
返回

Spring Boot 代码质量与规范

前言

代码质量是软件可维护性的关键。Spring Boot 项目可以通过代码规范、静态分析、代码审查等手段保证代码质量。本文将介绍 Spring Boot 代码质量的完整方案。

代码规范

1. 命名规范

// ✅ 推荐 - 类名使用大驼峰
public class UserService { }

// ✅ 推荐 - 方法名使用小驼峰
public UserDTO getUserById(Long id) { }

// ✅ 推荐 - 常量使用大写
public static final int MAX_RETRY_COUNT = 3;

// ✅ 推荐 - 包名全小写
package com.example.demo.service;

// ❌ 不推荐
public class userService { }  // 类名小写
public UserDTO GetUserById() { }  // 方法名大写
public static final int maxRetryCount = 3;  // 常量小写

2. 注释规范

/**
 * 用户服务类
 * 提供用户相关的业务逻辑处理
 * 
 * @author zhangsan
 * @since 1.0.0
 */
@Service
public class UserService {
    
    /**
     * 根据 ID 查询用户
     * 
     * @param userId 用户 ID
     * @return 用户信息
     * @throws NotFoundException 用户不存在时抛出
     */
    public UserDTO getUserById(Long userId) {
        // ...
    }
}

3. 代码格式

// ✅ 推荐
public class UserService {
    
    private final UserRepository userRepository;
    
    private static final int DEFAULT_PAGE_SIZE = 10;
    
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    public UserDTO getUserById(Long userId) {
        if (userId == null) {
            throw new IllegalArgumentException("用户 ID 不能为空");
        }
        
        return userRepository.findById(userId)
            .map(this::convertToDTO)
            .orElseThrow(() -> new NotFoundException("用户不存在"));
    }
}

// ❌ 不推荐
public class UserService{private UserRepository userRepository;public UserDTO getUserById(Long userId){if(userId==null){throw new IllegalArgumentException();}}}

静态分析工具

1. SonarQube

<plugin>
    <groupId>org.sonarsource.scanner.maven</groupId>
    <artifactId>sonar-maven-plugin</artifactId>
    <version>3.10.0.2594</version>
</plugin>
# sonar-project.properties
sonar.projectKey=demo
sonar.projectName=Demo Application
sonar.projectVersion=1.0.0

sonar.sources=src/main/java
sonar.tests=src/test/java
sonar.java.binaries=target/classes

sonar.sourceEncoding=UTF-8
sonar.java.source=21
# 执行分析
mvn clean verify sonar:sonar \
  -Dsonar.host.url=http://localhost:9000 \
  -Dsonar.login=admin \
  -Dsonar.password=admin

2. SpotBugs

<plugin>
    <groupId>com.github.spotbugs</groupId>
    <artifactId>spotbugs-maven-plugin</artifactId>
    <version>4.8.2.0</version>
    <configuration>
        <effort>Max</effort>
        <threshold>Low</threshold>
        <xmlOutput>true</xmlOutput>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>check</goal>
            </goals>
        </execution>
    </executions>
</plugin>
# 执行检查
mvn spotbugs:check

# 生成报告
mvn spotbugs:gui

3. PMD

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-pmd-plugin</artifactId>
    <version>3.21.2</version>
    <configuration>
        <targetJdk>21</targetJdk>
        <printFailingErrors>true</printFailingErrors>
        <rulesets>
            <ruleset>rulesets/java/quickstart.xml</ruleset>
        </rulesets>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>check</goal>
                <goal>cpd-check</goal>
            </goals>
        </execution>
    </executions>
</plugin>

4. Checkstyle

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-checkstyle-plugin</artifactId>
    <version>3.3.1</version>
    <configuration>
        <configLocation>checkstyle.xml</configLocation>
        <encoding>UTF-8</encoding>
        <consoleOutput>true</consoleOutput>
        <failsOnError>true</failsOnError>
    </configuration>
    <executions>
        <execution>
            <id>validate</id>
            <phase>validate</phase>
            <goals>
                <goal>check</goal>
            </goals>
        </execution>
    </executions>
</plugin>
<!-- checkstyle.xml -->
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
    "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
    "https://checkstyle.org/dtds/configuration_1_3.dtd">

<module name="Checker">
    <module name="TreeWalker">
        <module name="PackageName">
            <property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
        </module>
        
        <module name="TypeName">
            <property name="format" value="^[A-Z][a-zA-Z0-9]*$"/>
        </module>
        
        <module name="MethodName">
            <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
        </module>
        
        <module name="ParameterName">
            <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
        </module>
        
        <module name="LineLength">
            <property name="max" value="120"/>
        </module>
    </module>
</module>

代码审查

1. Git Hooks

#!/bin/bash
# .git/hooks/pre-commit

# 运行代码格式化
mvn checkstyle:check

# 运行静态分析
mvn spotbugs:check

# 运行测试
mvn test

# 检查通过
exit 0

2. Pull Request 模板

## PR 检查清单

- [ ] 代码符合项目规范
- [ ] 添加了必要的单元测试
- [ ] 测试覆盖率达标
- [ ] 更新了相关文档
- [ ] 通过了 CI/CD 流水线

## 变更说明

### 功能变更
- 

### 修复问题
- 

### 其他说明
- 

3. 代码审查工具

# .github/workflows/review.yml
name: Code Review

on:
  pull_request:
    branches: [main]

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Set up JDK
        uses: actions/setup-java@v4
        with:
          java-version: '21'
      
      - name: Run Checkstyle
        run: mvn checkstyle:check
      
      - name: Run SpotBugs
        run: mvn spotbugs:check
      
      - name: Run Tests
        run: mvn test
      
      - name: SonarQube Scan
        uses: sonarsource/sonarqube-scan-action@master
        with:
          host-url: ${{ secrets.SONAR_HOST_URL }}
          login: ${{ secrets.SONAR_TOKEN }}

质量门禁

1. 测试覆盖率要求

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.11</version>
    <executions>
        <execution>
            <id>check</id>
            <goals>
                <goal>check</goal>
            </goals>
            <configuration>
                <rules>
                    <rule>
                        <element>BUNDLE</element>
                        <limits>
                            <limit>
                                <counter>INSTRUCTION</counter>
                                <value>COVEREDRATIO</value>
                                <minimum>0.80</minimum>
                            </limit>
                            <limit>
                                <counter>BRANCH</counter>
                                <value>COVEREDRATIO</value>
                                <minimum>0.70</minimum>
                            </limit>
                        </limits>
                    </rule>
                </rules>
            </configuration>
        </execution>
    </executions>
</plugin>

2. 复杂度限制

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>findbugs-maven-plugin</artifactId>
    <configuration>
        <maxRank>20</maxRank>
    </configuration>
</plugin>

3. 重复代码检测

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-pmd-plugin</artifactId>
    <configuration>
        <minimumTokens>100</minimumTokens>
        <ignoreIdentifiers>true</ignoreIdentifiers>
    </configuration>
</plugin>

最佳实践

1. 代码组织

src/
├── main/
│   ├── java/
│   │   └── com/example/demo/
│   │       ├── DemoApplication.java
│   │       ├── controller/      # 控制器层
│   │       ├── service/         # 服务层
│   │       │   └── impl/        # 服务实现
│   │       ├── repository/      # 数据访问层
│   │       ├── entity/          # 实体类
│   │       ├── dto/             # 数据传输对象
│   │       ├── config/          # 配置类
│   │       └── common/          # 公共类
│   └── resources/
│       ├── application.yml
│       └── templates/
└── test/
    └── java/
        └── com/example/demo/

2. 异常处理

// ✅ 推荐
try {
    processOrder(order);
} catch (BusinessException e) {
    log.error("订单处理失败:{}", order.getId(), e);
    throw e;
} catch (Exception e) {
    log.error("系统异常:{}", order.getId(), e);
    throw new SystemException("系统异常", e);
}

// ❌ 不推荐
try {
    processOrder(order);
} catch (Exception e) {
    e.printStackTrace();  // 打印堆栈
}

3. 日志规范

// ✅ 推荐
log.info("订单创建成功:orderId={}", order.getId());
log.warn("库存不足:productId={}", product.getId());
log.error("订单处理失败:orderId={}", order.getId(), e);

// ❌ 不推荐
log.info("订单创建成功");  // 缺少关键信息
System.out.println("调试信息");  // 使用 System.out

4. 事务管理

// ✅ 推荐
@Transactional(rollbackFor = Exception.class)
public void createOrder(Order order) {
    // 业务逻辑
}

// ❌ 不推荐
@Transactional  // 没有指定回滚异常
public void createOrder(Order order) {
    // 业务逻辑
}

5. 依赖注入

// ✅ 推荐 - 构造器注入
@Service
@RequiredArgsConstructor
public class UserService {
    private final UserRepository userRepository;
}

// ❌ 不推荐 - 字段注入
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
}

总结

代码质量要点:

代码质量是软件可维护性的基础。


分享这篇文章到:

上一篇文章
网关限流实战
下一篇文章
A2A 通信协议与协作