SpringBoot 2.7 企业级项目结构详解

Ubanillx 发布于 25 天前 53 次阅读


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 企业级项目结构和核心代码示例。这种分层架构使得代码组织清晰,便于团队协作和系统维护。

此作者没有提供个人介绍
最后更新于 2025-05-27