前言
代码质量是软件可维护性的关键。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;
}
总结
代码质量要点:
- ✅ 代码规范 - 命名、注释、格式
- ✅ 静态分析 - SonarQube、SpotBugs、PMD
- ✅ 代码审查 - Git Hooks、PR 模板
- ✅ 质量门禁 - 覆盖率、复杂度、重复代码
- ✅ 最佳实践 - 组织、异常、日志、事务
代码质量是软件可维护性的基础。