# EMS后端开发指南与最佳实践 ## 开发环境准备 ### 必需软件 1. **JDK 17**: Oracle JDK或OpenJDK 2. **Maven 3.6+**: 依赖管理和构建工具 3. **IDE**: IntelliJ IDEA或Eclipse(推荐IDEA) 4. **Git**: 版本控制 5. **Postman**: API测试工具 ### IDE配置 ```xml D:/maven/repository aliyun https://maven.aliyun.com/repository/public central ``` ### 项目导入 1. 克隆项目到本地 2. 使用IDE导入Maven项目 3. 等待依赖下载完成 4. 配置JDK版本为17 ## 开发流程 ### 1. 功能开发流程 ``` 需求分析 → 设计API → 编写代码 → 单元测试 → 集成测试 → 代码审查 → 部署 ``` ### 2. 代码提交规范 ```bash # 提交信息格式 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层开发 ```java @RestController @RequestMapping("/api/v1/users") @Validated public class UserController { @Autowired private UserService userService; @GetMapping("/{id}") public ResponseEntity getUser(@PathVariable Long id) { UserDTO user = userService.getUserById(id); return ResponseEntity.ok(user); } @PostMapping public ResponseEntity createUser(@Valid @RequestBody UserCreationRequest request) { UserDTO user = userService.createUser(request); return ResponseEntity.status(HttpStatus.CREATED).body(user); } } ``` ### 2. Service层开发 ```java @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层开发 ```java @Repository public class UserRepository extends JsonFileRepository { public UserRepository() { super("users.json", User.class); } public Optional findByEmail(String email) { return findAll().stream() .filter(user -> email.equals(user.getEmail())) .findFirst(); } public List findByRole(Role role) { return findAll().stream() .filter(user -> role.equals(user.getRole())) .collect(Collectors.toList()); } } ``` ## 测试开发指南 ### 1. 单元测试 ```java @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. 集成测试 ```java @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 response = restTemplate.postForEntity( "/api/v1/users", request, UserDTO.class); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.CREATED); assertThat(response.getBody().getUsername()).isEqualTo("testuser"); } } ``` ## 调试技巧 ### 1. 日志调试 ```java @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. 性能调试 ```java @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. 依赖冲突 ```bash # 查看依赖树 mvn dependency:tree # 排除冲突依赖 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-logging ``` ### 2. JSON文件锁定问题 ```java @Component public class FileOperationService { private final Object fileLock = new Object(); public void writeToFile(String filename, Object data) { synchronized (fileLock) { // 文件操作 } } } ``` ### 3. 内存泄漏排查 ```bash # 启动时添加JVM参数 java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./dumps/ -jar app.jar # 使用JProfiler或VisualVM分析 ``` ## 部署指南 ### 1. 打包部署 ```bash # 清理并打包 mvn clean package -DskipTests # 运行 java -jar target/ems-backend-0.0.1-SNAPSHOT.jar ``` ### 2. 配置文件管理 ```bash # 外部配置文件 java -jar app.jar --spring.config.location=classpath:/application.properties,./config/application-prod.properties ``` ### 3. 健康检查 ```bash # 检查应用状态 curl http://localhost:8080/actuator/health # 检查API文档 curl http://localhost:8080/swagger-ui.html ``` ## 扩展开发 ### 1. 添加新的API端点 1. 创建DTO类 2. 创建Controller方法 3. 实现Service逻辑 4. 添加Repository方法 5. 编写测试用例 6. 更新API文档 ### 2. 集成新的外部服务 1. 添加配置属性 2. 创建客户端类 3. 实现服务接口 4. 添加异常处理 5. 编写集成测试 ### 3. 性能优化 1. 添加缓存层 2. 优化数据库查询 3. 使用异步处理 4. 实现分页查询 5. 添加监控指标