7.9 KiB
7.9 KiB
EMS后端开发指南与最佳实践
开发环境准备
必需软件
- JDK 17: Oracle JDK或OpenJDK
- Maven 3.6+: 依赖管理和构建工具
- IDE: IntelliJ IDEA或Eclipse(推荐IDEA)
- Git: 版本控制
- Postman: API测试工具
IDE配置
<!-- Maven配置 -->
<settings>
<localRepository>D:/maven/repository</localRepository>
<mirrors>
<mirror>
<id>aliyun</id>
<url>https://maven.aliyun.com/repository/public</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
</settings>
项目导入
- 克隆项目到本地
- 使用IDE导入Maven项目
- 等待依赖下载完成
- 配置JDK版本为17
开发流程
1. 功能开发流程
需求分析 → 设计API → 编写代码 → 单元测试 → 集成测试 → 代码审查 → 部署
2. 代码提交规范
# 提交信息格式
type(scope): description
# 类型说明
feat: 新功能
fix: 修复bug
docs: 文档更新
style: 代码格式调整
refactor: 重构
test: 测试相关
chore: 构建过程或辅助工具的变动
# 示例
feat(auth): 添加JWT token刷新功能
fix(feedback): 修复反馈状态更新bug
docs(api): 更新API文档
3. 分支管理策略
main: 主分支,生产环境代码
develop: 开发分支,集成最新功能
feature/*: 功能分支
hotfix/*: 紧急修复分支
release/*: 发布分支
编码最佳实践
1. Controller层开发
@RestController
@RequestMapping("/api/v1/users")
@Validated
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public ResponseEntity<UserDTO> getUser(@PathVariable Long id) {
UserDTO user = userService.getUserById(id);
return ResponseEntity.ok(user);
}
@PostMapping
public ResponseEntity<UserDTO> createUser(@Valid @RequestBody UserCreationRequest request) {
UserDTO user = userService.createUser(request);
return ResponseEntity.status(HttpStatus.CREATED).body(user);
}
}
2. Service层开发
@Service
@Transactional
public class UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private ApplicationEventPublisher eventPublisher;
public UserDTO createUser(UserCreationRequest request) {
// 业务逻辑处理
User user = User.builder()
.username(request.getUsername())
.email(request.getEmail())
.build();
User savedUser = userRepository.save(user);
// 发布事件
eventPublisher.publishEvent(new UserCreatedEvent(savedUser));
return UserMapper.toDTO(savedUser);
}
}
3. Repository层开发
@Repository
public class UserRepository extends JsonFileRepository<User> {
public UserRepository() {
super("users.json", User.class);
}
public Optional<User> findByEmail(String email) {
return findAll().stream()
.filter(user -> email.equals(user.getEmail()))
.findFirst();
}
public List<User> findByRole(Role role) {
return findAll().stream()
.filter(user -> role.equals(user.getRole()))
.collect(Collectors.toList());
}
}
测试开发指南
1. 单元测试
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
void shouldCreateUserSuccessfully() {
// Given
UserCreationRequest request = new UserCreationRequest();
request.setUsername("testuser");
User savedUser = User.builder().id(1L).username("testuser").build();
when(userRepository.save(any(User.class))).thenReturn(savedUser);
// When
UserDTO result = userService.createUser(request);
// Then
assertThat(result.getUsername()).isEqualTo("testuser");
verify(userRepository).save(any(User.class));
}
}
2. 集成测试
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestPropertySource(properties = {
"file.upload-dir=./test-uploads"
})
class UserControllerIntegrationTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
void shouldCreateUserSuccessfully() {
UserCreationRequest request = new UserCreationRequest();
request.setUsername("testuser");
ResponseEntity<UserDTO> response = restTemplate.postForEntity(
"/api/v1/users", request, UserDTO.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.CREATED);
assertThat(response.getBody().getUsername()).isEqualTo("testuser");
}
}
调试技巧
1. 日志调试
@Slf4j
@Service
public class UserService {
public UserDTO createUser(UserCreationRequest request) {
log.debug("Creating user with username: {}", request.getUsername());
try {
// 业务逻辑
User user = processUser(request);
log.info("User created successfully with ID: {}", user.getId());
return UserMapper.toDTO(user);
} catch (Exception e) {
log.error("Failed to create user: {}", e.getMessage(), e);
throw new UserCreationException("Failed to create user", e);
}
}
}
2. 断点调试
- 在IDE中设置断点
- 使用条件断点
- 观察变量值变化
- 使用表达式求值
3. 性能调试
@Component
@Aspect
public class PerformanceAspect {
@Around("@annotation(Timed)")
public Object measureExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
Object result = joinPoint.proceed();
long endTime = System.currentTimeMillis();
log.info("Method {} executed in {} ms",
joinPoint.getSignature().getName(),
endTime - startTime);
return result;
}
}
常见问题解决
1. 依赖冲突
# 查看依赖树
mvn dependency:tree
# 排除冲突依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
2. JSON文件锁定问题
@Component
public class FileOperationService {
private final Object fileLock = new Object();
public void writeToFile(String filename, Object data) {
synchronized (fileLock) {
// 文件操作
}
}
}
3. 内存泄漏排查
# 启动时添加JVM参数
java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./dumps/ -jar app.jar
# 使用JProfiler或VisualVM分析
部署指南
1. 打包部署
# 清理并打包
mvn clean package -DskipTests
# 运行
java -jar target/ems-backend-0.0.1-SNAPSHOT.jar
2. 配置文件管理
# 外部配置文件
java -jar app.jar --spring.config.location=classpath:/application.properties,./config/application-prod.properties
3. 健康检查
# 检查应用状态
curl http://localhost:8080/actuator/health
# 检查API文档
curl http://localhost:8080/swagger-ui.html
扩展开发
1. 添加新的API端点
- 创建DTO类
- 创建Controller方法
- 实现Service逻辑
- 添加Repository方法
- 编写测试用例
- 更新API文档
2. 集成新的外部服务
- 添加配置属性
- 创建客户端类
- 实现服务接口
- 添加异常处理
- 编写集成测试
3. 性能优化
- 添加缓存层
- 优化数据库查询
- 使用异步处理
- 实现分页查询
- 添加监控指标