# 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. 添加监控指标