346 lines
7.9 KiB
Markdown
346 lines
7.9 KiB
Markdown
# EMS后端开发指南与最佳实践
|
||
|
||
## 开发环境准备
|
||
|
||
### 必需软件
|
||
1. **JDK 17**: Oracle JDK或OpenJDK
|
||
2. **Maven 3.6+**: 依赖管理和构建工具
|
||
3. **IDE**: IntelliJ IDEA或Eclipse(推荐IDEA)
|
||
4. **Git**: 版本控制
|
||
5. **Postman**: API测试工具
|
||
|
||
### IDE配置
|
||
```xml
|
||
<!-- 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>
|
||
```
|
||
|
||
### 项目导入
|
||
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<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层开发
|
||
```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<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. 单元测试
|
||
```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<UserDTO> 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
|
||
|
||
# 排除冲突依赖
|
||
<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文件锁定问题
|
||
```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. 添加监控指标 |