# Java代码规范

## 1. 命名规范

### 1.1 包命名
- 包名全部小写，使用点分隔
- 示例：`com.emotionmuseum.user.controller`

### 1.2 类命名
- 使用大驼峰命名法（PascalCase）
- 示例：`UserController`、`UserService`

### 1.3 方法命名
- 使用小驼峰命名法（camelCase）
- 示例：`getUserById`、`createUser`

### 1.4 变量命名
- 使用小驼峰命名法（camelCase）
- 常量使用全大写+下划线（UPPER_SNAKE_CASE）
- 示例：`userName`、`MAX_RETRY_COUNT`

## 2. 导入包规范

### 2.1 导入方式规范
**重要原则：必须使用常规的import方式导入类，严禁在代码中使用全路径限定名方式导入类。**

#### 2.1.1 正确的导入方式
```java
// ✅ 正确示例：使用import语句导入类
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.beans.factory.annotation.Autowired;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import com.emotionmuseum.dto.request.CreateUserRequest;
import com.emotionmuseum.dto.response.UserResponse;
import com.emotionmuseum.service.UserService;
import com.emotionmuseum.common.result.Result;

@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
@Slf4j
public class UserController {
    
    private final UserService userService;
    
    @PostMapping
    public Result<UserResponse> createUser(@RequestBody CreateUserRequest request) {
        UserResponse response = userService.createUser(request);
        return Result.success(response);
    }
}
```

#### 2.1.2 错误的导入方式
```java
// ❌ 错误示例：在代码中使用全路径限定名
public class UserController {
    
    @org.springframework.beans.factory.annotation.Autowired
    private com.emotionmuseum.service.UserService userService;
    
    @org.springframework.web.bind.annotation.PostMapping
    public com.emotionmuseum.common.result.Result<com.emotionmuseum.dto.response.UserResponse> 
        createUser(@org.springframework.web.bind.annotation.RequestBody 
                   com.emotionmuseum.dto.request.CreateUserRequest request) {
        
        com.emotionmuseum.dto.response.UserResponse response = userService.createUser(request);
        return com.emotionmuseum.common.result.Result.success(response);
    }
}
```

### 2.2 导入顺序规范
```java
// 1. Java标准库导入
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

// 2. 第三方库导入（按字母顺序）
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

// 3. 项目内部导入（按包层次顺序）
import com.emotionmuseum.common.result.Result;
import com.emotionmuseum.dto.request.CreateUserRequest;
import com.emotionmuseum.dto.response.UserResponse;
import com.emotionmuseum.service.UserService;
```

### 2.3 导入优化规范
```java
// ✅ 推荐：使用通配符导入相关的类
import org.springframework.web.bind.annotation.*;

// ✅ 推荐：分别导入不同包的类
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

// ❌ 不推荐：过度使用通配符导入
import org.springframework.*;

// ❌ 不推荐：导入未使用的类
import java.util.ArrayList; // 如果代码中没有使用ArrayList
```

### 2.4 静态导入规范
```java
// ✅ 正确：静态导入常用的静态方法
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

// ✅ 正确：静态导入项目中的工具类方法
import static com.emotionmuseum.common.util.DateUtil.formatDateTime;
import static com.emotionmuseum.common.util.StringUtil.isBlank;

// ❌ 错误：避免过度使用静态导入
import static java.lang.Math.*;
import static java.util.Collections.*;
```

### 2.5 导入冲突处理
```java
// 当出现类名冲突时，使用import别名或明确指定包名
import com.emotionmuseum.dto.response.Result;
import org.springframework.http.ResponseEntity;

public class UserController {
    
    // 使用别名避免冲突
    public com.emotionmuseum.dto.response.Result<UserResponse> createUser() {
        // 业务逻辑
    }
    
    // 或者使用import别名（如果IDE支持）
    // import com.emotionmuseum.dto.response.Result as EmotionResult;
}
```

## 3. 代码结构规范

### 3.1 类结构顺序
```java
public class ExampleClass {
    // 1. 静态常量
    public static final String CONSTANT = "value";
    
    // 2. 实例变量
    private String instanceVariable;
    
    // 3. 构造方法
    public ExampleClass() {}
    
    // 4. 公共方法
    public void publicMethod() {}
    
    // 5. 私有方法
    private void privateMethod() {}
}
```

### 3.2 方法结构
```java
public Result<UserResponse> getUserById(Long userId) {
    // 1. 参数校验
    if (userId == null) {
        throw new IllegalArgumentException("用户ID不能为空");
    }
    
    // 2. 业务逻辑
    User user = userService.getById(userId);
    
    // 3. 数据转换
    UserResponse response = UserConverter.toResponse(user);
    
    // 4. 返回结果
    return Result.success(response);
}
```

## 4. 注释规范

### 4.1 类注释
```java
/**
 * 用户控制器
 * 
 * @author 作者名
 * @since 1.0.0
 */
@RestController
public class UserController {
}
```

### 4.2 方法注释
```java
/**
 * 根据用户ID获取用户信息
 * 
 * @param userId 用户ID
 * @return 用户信息响应对象
 * @throws UserNotFoundException 当用户不存在时抛出
 */
public Result<UserResponse> getUserById(Long userId) {
}
```

## 5. 异常处理规范

### 5.1 异常定义
```java
public class UserNotFoundException extends BusinessException {
    public UserNotFoundException(String message) {
        super(message);
    }
}
```

### 5.2 异常抛出
```java
if (user == null) {
    throw new UserNotFoundException("用户不存在，ID: " + userId);
}
```

## 6. Log4j2日志规范

### 6.1 日志级别使用
```java
// FATAL: 致命错误，系统无法继续运行
logger.fatal("系统严重错误，无法继续运行", e);

// ERROR: 系统错误
logger.error("数据库连接失败", e);

// WARN: 警告信息
logger.warn("用户{}尝试访问未授权资源", userId);

// INFO: 重要业务信息
logger.info("用户{}登录成功", username);

// DEBUG: 调试信息
logger.debug("查询用户参数: {}", queryParams);

// TRACE: 详细调试信息
logger.trace("进入方法: {}", methodName);
```

### 6.2 日志记录规范
```java
// 使用占位符，避免字符串拼接
logger.info("用户{}在{}登录成功", username, LocalDateTime.now());

// 异常日志记录
try {
    // 业务逻辑
} catch (Exception e) {
    logger.error("处理用户请求失败，用户ID: {}, 错误信息: {}", userId, e.getMessage(), e);
    throw new BusinessException("处理失败");
}

// 性能日志记录
long startTime = System.currentTimeMillis();
// 业务逻辑
long endTime = System.currentTimeMillis();
logger.info("查询用户信息耗时: {}ms", endTime - startTime);
```

### 6.3 MDC日志追踪
```java
// 设置MDC信息
MDC.put("userId", userId.toString());
MDC.put("requestId", UUID.randomUUID().toString());

try {
    // 业务逻辑
} finally {
    // 清理MDC
    MDC.clear();
}
```

## 7. 数据库操作规范

### 7.1 MyBatis-Plus使用
```java
// 查询单个
User user = userMapper.selectById(userId);

// 条件查询
List<User> users = userMapper.selectList(
    new LambdaQueryWrapper<User>()
        .eq(User::getStatus, UserStatus.ACTIVE)
        .orderByDesc(User::getCreateTime)
);
```

## 8. 接口设计规范

### 8.1 Controller层规范
**重要原则：Controller层只负责接收请求、参数校验、调用Service层、返回结果，严禁在Controller层编写任何业务逻辑代码。**

```java
@RestController
@RequestMapping("/api/users")
@Validated
@Slf4j
public class UserController {
    
    @Autowired
    private UserService userService;
    
    @PostMapping
    public Result<UserResponse> createUser(@Valid @RequestBody CreateUserRequest request) {
        // Controller层只做：参数校验（通过@Valid）、调用Service、返回结果
        UserResponse response = userService.createUser(request);
        return Result.success(response);
    }
    
    @GetMapping("/{id}")
    public Result<UserResponse> getUserById(@PathVariable Long id) {
        // Controller层只做：调用Service、返回结果
        UserResponse response = userService.getUserById(id);
        return Result.success(response);
    }
    
    @PutMapping("/{id}")
    public Result<UserResponse> updateUser(@PathVariable Long id, 
                                         @Valid @RequestBody UpdateUserRequest request) {
        // Controller层只做：参数校验、调用Service、返回结果
        UserResponse response = userService.updateUser(id, request);
        return Result.success(response);
    }
    
    @DeleteMapping("/{id}")
    public Result<Void> deleteUser(@PathVariable Long id) {
        // Controller层只做：调用Service、返回结果
        userService.deleteUser(id);
        return Result.success(null);
    }
}
```

### 8.2 Controller层禁止事项
```java
// ❌ 错误示例：在Controller层编写业务逻辑
@PostMapping("/users")
public Result<UserResponse> createUser(@Valid @RequestBody CreateUserRequest request) {
    // 错误：在Controller层进行业务判断
    if (userMapper.selectByUsername(request.getUsername()) != null) {
        throw new BusinessException("用户名已存在");
    }
    
    // 错误：在Controller层进行数据转换
    User user = new User();
    user.setUsername(request.getUsername());
    user.setPassword(passwordEncoder.encode(request.getPassword()));
    
    // 错误：在Controller层直接操作数据库
    userMapper.insert(user);
    
    // 错误：在Controller层进行复杂的数据处理
    UserResponse response = new UserResponse();
    response.setId(user.getId());
    response.setUsername(user.getUsername());
    
    return Result.success(response);
}

// ✅ 正确示例：Controller层只负责调用Service
@PostMapping("/users")
public Result<UserResponse> createUser(@Valid @RequestBody CreateUserRequest request) {
    UserResponse response = userService.createUser(request);
    return Result.success(response);
}
```

### 8.3 请求响应对象规范
```java
@Data
public class CreateUserRequest {
    @NotBlank(message = "用户名不能为空")
    private String username;
    
    @NotBlank(message = "密码不能为空")
    private String password;
}

@Data
public class UserResponse {
    private Long id;
    private String username;
    private LocalDateTime createTime;
}
```

### 8.4 Service层业务逻辑规范
**重要原则：所有业务逻辑必须在Service层完成，包括数据校验、业务规则判断、数据处理、事务管理等。**

```java
@Service
@Transactional
@Slf4j
public class UserServiceImpl implements UserService {
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    @Override
    public UserResponse createUser(CreateUserRequest request) {
        // 1. 业务参数校验
        validateCreateUserRequest(request);
        
        // 2. 业务规则判断
        checkUserExists(request.getUsername());
        
        // 3. 数据转换和业务处理
        User user = convertToUser(request);
        user.setPassword(passwordEncoder.encode(request.getPassword()));
        
        // 4. 数据持久化
        userMapper.insert(user);
        
        // 5. 返回结果转换
        return convertToResponse(user);
    }
    
    @Override
    public UserResponse getUserById(Long id) {
        // 1. 参数校验
        if (id == null) {
            throw new IllegalArgumentException("用户ID不能为空");
        }
        
        // 2. 业务逻辑：查询用户
        User user = userMapper.selectById(id);
        if (user == null) {
            throw new UserNotFoundException("用户不存在，ID: " + id);
        }
        
        // 3. 返回结果转换
        return convertToResponse(user);
    }
    
    @Override
    public UserResponse updateUser(Long id, UpdateUserRequest request) {
        // 1. 参数校验
        validateUpdateUserRequest(id, request);
        
        // 2. 业务逻辑：检查用户是否存在
        User existingUser = userMapper.selectById(id);
        if (existingUser == null) {
            throw new UserNotFoundException("用户不存在，ID: " + id);
        }
        
        // 3. 业务规则判断
        if (StringUtils.hasText(request.getUsername())) {
            checkUserExists(request.getUsername(), id);
        }
        
        // 4. 数据更新
        updateUserFields(existingUser, request);
        userMapper.updateById(existingUser);
        
        // 5. 返回结果转换
        return convertToResponse(existingUser);
    }
    
    @Override
    public void deleteUser(Long id) {
        // 1. 参数校验
        if (id == null) {
            throw new IllegalArgumentException("用户ID不能为空");
        }
        
        // 2. 业务逻辑：检查用户是否存在
        User user = userMapper.selectById(id);
        if (user == null) {
            throw new UserNotFoundException("用户不存在，ID: " + id);
        }
        
        // 3. 业务规则判断：检查是否可以删除
        checkUserCanBeDeleted(user);
        
        // 4. 执行删除
        userMapper.deleteById(id);
        
        log.info("用户删除成功，ID: {}", id);
    }
    
    // 私有方法：业务校验
    private void validateCreateUserRequest(CreateUserRequest request) {
        if (request == null) {
            throw new IllegalArgumentException("请求参数不能为空");
        }
        // 其他业务校验逻辑
    }
    
    private void checkUserExists(String username) {
        User existingUser = userMapper.selectByUsername(username);
        if (existingUser != null) {
            throw new BusinessException("用户名已存在: " + username);
        }
    }
    
    private void checkUserExists(String username, Long excludeId) {
        User existingUser = userMapper.selectByUsernameAndIdNot(username, excludeId);
        if (existingUser != null) {
            throw new BusinessException("用户名已存在: " + username);
        }
    }
    
    private void checkUserCanBeDeleted(User user) {
        // 检查用户是否可以删除的业务逻辑
        if (user.getStatus() == UserStatus.ACTIVE) {
            // 检查是否有未完成的订单等
            if (hasUnfinishedOrders(user.getId())) {
                throw new BusinessException("用户有未完成的订单，无法删除");
            }
        }
    }
    
    // 私有方法：数据转换
    private User convertToUser(CreateUserRequest request) {
        User user = new User();
        user.setUsername(request.getUsername());
        user.setEmail(request.getEmail());
        user.setStatus(UserStatus.ACTIVE);
        return user;
    }
    
    private UserResponse convertToResponse(User user) {
        UserResponse response = new UserResponse();
        response.setId(user.getId());
        response.setUsername(user.getUsername());
        response.setEmail(user.getEmail());
        response.setStatus(user.getStatus());
        response.setCreateTime(user.getCreateTime());
        return response;
    }
}
```

## 9. 缓存使用规范

### 9.1 Redis缓存注解
```java
@Cacheable(value = "user", key = "#userId")
public UserResponse getUserById(Long userId) {
    // 业务逻辑
}

@CacheEvict(value = "user", key = "#userId")
public void updateUser(Long userId, UpdateUserRequest request) {
    // 更新逻辑
}
```

## 10. 异步处理规范

### 10.1 异步方法定义
```java
@Async("notificationExecutor")
public CompletableFuture<Void> sendNotificationAsync(Long userId, String message) {
    try {
        sendNotification(userId, message);
        return CompletableFuture.completedFuture(null);
    } catch (Exception e) {
        logger.error("发送通知失败", e);
        return CompletableFuture.failedFuture(e);
    }
}
```

## 11. 单元测试规范

### 11.1 测试类结构
```java
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
    
    @Mock
    private UserMapper userMapper;
    
    @InjectMocks
    private UserServiceImpl userService;
    
    @Test
    @DisplayName("根据ID获取用户 - 成功")
    void getUserById_Success() {
        // Given
        Long userId = 1L;
        User user = new User();
        user.setId(userId);
        
        when(userMapper.selectById(userId)).thenReturn(user);
        
        // When
        UserResponse result = userService.getUserById(userId);
        
        // Then
        assertThat(result).isNotNull();
        assertThat(result.getId()).isEqualTo(userId);
    }
}
```

## 12. Spring Security安全规范

### 12.1 安全注解使用
```java
@RestController
@RequestMapping("/api/users")
public class UserController {
    
    @PreAuthorize("hasRole('ADMIN')")
    @GetMapping("/admin")
    public Result<List<UserResponse>> getAllUsers() {
        // 只有ADMIN角色可以访问
    }
    
    @PreAuthorize("hasRole('USER') and #userId == authentication.principal.id")
    @GetMapping("/{userId}")
    public Result<UserResponse> getUserById(@PathVariable Long userId) {
        // 只有USER角色且只能访问自己的信息
    }
    
    @PreAuthorize("permitAll()")
    @PostMapping("/register")
    public Result<UserResponse> register(@Valid @RequestBody CreateUserRequest request) {
        // 允许所有人访问
    }
}
```

### 12.2 输入验证
```java
@PostMapping("/users")
public Result<UserResponse> createUser(@Valid @RequestBody CreateUserRequest request) {
    return userService.createUser(request);
}
```

### 12.3 敏感信息处理
```java
// 日志中脱敏
logger.info("用户{}登录成功", maskUsername(username));

private String maskUsername(String username) {
    if (username == null || username.length() <= 2) {
        return username;
    }
    return username.substring(0, 1) + "***" + username.substring(username.length() - 1);
}
```

### 12.4 密码处理规范
```java
@Service
public class UserServiceImpl implements UserService {
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    public void createUser(CreateUserRequest request) {
        // 密码加密存储
        String encodedPassword = passwordEncoder.encode(request.getPassword());
        user.setPassword(encodedPassword);
        
        // 密码验证
        if (passwordEncoder.matches(rawPassword, encodedPassword)) {
            // 密码正确
        }
    }
}
```

### 12.5 JWT Token处理
```java
@Component
public class JwtTokenProvider {
    
    public String generateToken(UserDetails userDetails) {
        return Jwts.builder()
                .setSubject(userDetails.getUsername())
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + jwtExpirationMs))
                .signWith(SignatureAlgorithm.HS512, jwtSecret)
                .compact();
    }
    
    public String getUsernameFromToken(String token) {
        return Jwts.parser()
                .setSigningKey(jwtSecret)
                .parseClaimsJws(token)
                .getBody()
                .getSubject();
    }
}
```

## 13. 版本控制规范

### 13.1 Git提交规范
```bash
feat(user): 添加用户注册功能
fix(auth): 修复登录验证bug
docs(api): 更新API文档
style(code): 格式化代码
refactor(service): 重构用户服务
```

## 总结

本代码规范涵盖了Java开发中的主要方面，包括命名规范、代码结构、注释规范、异常处理、日志记录、数据库操作、接口设计、缓存使用、异步处理、单元测试、安全规范和版本控制等。遵循这些规范可以确保代码的质量、可维护性和可扩展性。 
遵循这些规范可以确保代码的质量、可维护性和可扩展性，提高团队开发效率。 