SpringBoot 2.7 的企业级项目通常采用模块化分层架构,以提高代码的可维护性和可扩展性。下面是一个典型的项目结构示例:
plaintext
src/main/java/com/example/demo
├── config
│ ├── SecurityConfig.java # 安全配置
│ └── SwaggerConfig.java # API文档配置
├── controller
│ ├── AuthController.java # 认证控制器
│ ├── UserController.java # 用户控制器
│ └── BaseController.java # 基础控制器(抽象类)
├── domain
│ ├── entity
│ │ ├── User.java # 用户实体
│ │ └── Role.java # 角色实体
│ └── dto
│ ├── UserDTO.java # 用户数据传输对象
│ └── ResponseDTO.java # 统一响应对象
├── repository
│ ├── UserRepository.java # 用户数据访问接口
│ └── RoleRepository.java # 角色数据访问接口
├── service
│ ├── impl
│ │ ├── UserServiceImpl.java # 用户服务实现
│ │ └── AuthServiceImpl.java # 认证服务实现
│ ├── UserService.java # 用户服务接口
│ └── AuthService.java # 认证服务接口
├── utils
│ ├── DateUtils.java # 日期工具类
│ └── JwtUtils.java # JWT工具类
├── exception
│ ├── GlobalExceptionHandler.java # 全局异常处理器
│ └── BusinessException.java # 业务异常类
└── DemoApplication.java # 应用入口类
src/main/resources
├── application.yml # 主配置文件
├── application-dev.yml # 开发环境配置
├── application-prod.yml # 生产环境配置
├── static # 静态资源目录
├── templates # 模板文件目录
└── db/migration # Liquibase/Flyway数据库脚本
src/test/java/com/example/demo
├── controller
│ └── UserControllerTest.java # 控制器测试
├── service
│ └── UserServiceTest.java # 服务测试
└── repository
└── UserRepositoryTest.java # 数据访问测试
核心模块功能说明
1. 配置层 (config)
这一层负责应用的各种配置,包括安全、数据库连接、WebMvc 等配置类。
示例代码 - SecurityConfig.java
java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.antMatchers("/api/test/**").permitAll()
.anyRequest().authenticated();
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}
@Bean
public JwtAuthenticationFilter authenticationJwtTokenFilter() {
return new JwtAuthenticationFilter();
}
// 其他配置...
}
2. 控制层 (controller)
负责接收 HTTP 请求,处理参数并返回响应。通常使用@RestController
注解。
示例代码 - UserController.java
java
@RestController
@RequestMapping("/api/users")
@CrossOrigin(origins = "*", maxAge = 3600)
public class UserController extends BaseController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public ResponseEntity<?> getUserById(@PathVariable("id") Long id) {
try {
UserDTO user = userService.getUserById(id);
return success(user);
} catch (BusinessException e) {
return error(e.getErrorCode(), e.getMessage());
}
}
@PostMapping("/")
public ResponseEntity<?> createUser(@Valid @RequestBody UserDTO userDTO) {
UserDTO createdUser = userService.createUser(userDTO);
return success(createdUser);
}
// 其他接口...
}
3. 领域层 (domain)
包含实体类 (Entity) 和数据传输对象 (DTO),用于数据建模和传输。
示例代码 - User.java (Entity)
java
@Entity
@Table(name = "users")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank
@Size(max = 20)
private String username;
@NotBlank
@Size(max = 50)
@Email
private String email;
@NotBlank
@Size(max = 120)
private String password;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "user_roles",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles = new HashSet<>();
// 构造函数、getter和setter...
}
4. 数据访问层 (repository)
负责与数据库交互,通常使用 Spring Data JPA 的JpaRepository
接口。
示例代码 - UserRepository.java
java
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(String username);
Boolean existsByUsername(String username);
Boolean existsByEmail(String email);
}
5. 服务层 (service)
实现业务逻辑,协调领域对象完成业务操作。
示例代码 - UserServiceImpl.java
java
@Service
@Transactional
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private ModelMapper modelMapper;
@Override
public UserDTO getUserById(Long id) {
User user = userRepository.findById(id)
.orElseThrow(() -> new BusinessException(ErrorCode.USER_NOT_FOUND, "User not found"));
return modelMapper.map(user, UserDTO.class);
}
@Override
public UserDTO createUser(UserDTO userDTO) {
if (userRepository.existsByUsername(userDTO.getUsername())) {
throw new BusinessException(ErrorCode.USERNAME_EXIST, "Username already exists");
}
if (userRepository.existsByEmail(userDTO.getEmail())) {
throw new BusinessException(ErrorCode.EMAIL_EXIST, "Email already exists");
}
User user = modelMapper.map(userDTO, User.class);
user.setPassword(passwordEncoder.encode(user.getPassword()));
User savedUser = userRepository.save(user);
return modelMapper.map(savedUser, UserDTO.class);
}
// 其他业务方法...
}
6. 工具类 (utils)
提供通用功能,如日期处理、加密、文件操作等。
示例代码 - JwtUtils.java
java
@Component
public class JwtUtils {
private static final Logger logger = LoggerFactory.getLogger(JwtUtils.class);
@Value("${demo.app.jwtSecret}")
private String jwtSecret;
@Value("${demo.app.jwtExpirationMs}")
private int jwtExpirationMs;
public String generateJwtToken(Authentication authentication) {
UserDetailsImpl userPrincipal = (UserDetailsImpl) authentication.getPrincipal();
return Jwts.builder()
.setSubject((userPrincipal.getUsername()))
.setIssuedAt(new Date())
.setExpiration(new Date((new Date()).getTime() + jwtExpirationMs))
.signWith(SignatureAlgorithm.HS512, jwtSecret)
.compact();
}
public String getUserNameFromJwtToken(String token) {
return Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).getBody().getSubject();
}
public boolean validateJwtToken(String authToken) {
try {
Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
return true;
} catch (SignatureException e) {
logger.error("Invalid JWT signature: {}", e.getMessage());
} catch (MalformedJwtException e) {
logger.error("Invalid JWT token: {}", e.getMessage());
} catch (ExpiredJwtException e) {
logger.error("JWT token is expired: {}", e.getMessage());
} catch (UnsupportedJwtException e) {
logger.error("JWT token is unsupported: {}", e.getMessage());
} catch (IllegalArgumentException e) {
logger.error("JWT claims string is empty: {}", e.getMessage());
}
return false;
}
}
7. 异常处理 (exception)
统一处理应用中的异常,提供友好的错误信息。
示例代码 - GlobalExceptionHandler.java
java
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResponseDTO<?> handleBusinessException(BusinessException ex) {
return ResponseDTO.error(ex.getErrorCode(), ex.getMessage());
}
@ExceptionHandler(Exception.class)
@ResponseBody
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseDTO<?> handleGeneralException(Exception ex) {
return ResponseDTO.error(ErrorCode.INTERNAL_SERVER_ERROR, "Internal server error");
}
}
配置文件示例
application.yml
yaml
spring:
datasource:
url: jdbc:mysql://localhost:3306/demo?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
username: root
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: update
show-sql: true
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL8Dialect
security:
user:
name: admin
password: admin
roles: ADMIN
server:
port: 8080
servlet:
context-path: /api
jwt:
secret: yourSecretKey
expirationMs: 86400000 # 24小时
以上就是一个典型的 SpringBoot 2.7 企业级项目结构和核心代码示例。这种分层架构使得代码组织清晰,便于团队协作和系统维护。
Comments NOTHING