springboot-init
0. Technology Stack Configuration
Before using this specification, please confirm the project's technology selection:
0.1 Core Framework Versions
| Configuration Item |
Available Values |
Description |
| Spring Boot |
2.x / 3.x / 4.x |
2.x supports Java 8+, 3.x/4.x requires Java 17+ |
| JDK |
8 / 11 / 17 / 21 / 25 |
Choose based on the Spring Boot version |
Version Compatibility Matrix:
| Spring Boot |
Minimum JDK |
Recommended JDK |
Jakarta EE |
| 2.x |
8 |
11 |
javax.* |
| 3.x |
17 |
17 |
jakarta.* |
| 4.x |
17 |
21 |
jakarta.* |
0.2 ORM Frameworks
| Framework |
Features |
Applicable Scenarios |
| MyBatis-Plus |
Enhanced MyBatis, simplifies CRUD |
Traditional projects, rapid development |
| MyBatis-Flex |
Lightweight, high performance, chain-style queries |
Pursuing performance, flexible queries |
| Jimmer |
Immutable objects, strongly typed DSL |
Complex domain models, DDD projects |
0.3 Utility Libraries
| Library |
Description |
Recommendation |
| Hutool |
All-purpose utility library (dates, encryption, HTTP, JSON, etc.) |
Recommended, reduces duplicate code |
| Apache Commons |
Collection of classic utility libraries |
Optional for lightweight needs |
| Guava |
Google utility library |
Collection handling, caching needs |
0.4 Access Control Frameworks
| Framework |
Features |
Applicable Scenarios |
| Sa-Token |
Lightweight, out-of-the-box, comprehensive features |
Rapid development, small and medium-sized projects |
| Spring Security |
Spring official, powerful features, highly customizable |
Enterprise-level projects, complex permissions |
| Shiro |
Apache project, simple and easy to use |
Traditional projects, simple permissions, independent of Spring Boot |
| Casbin |
Powerful, flexible, extensible |
Complex dynamic permission control, not sensitive to performance |
| Keycloak |
Independent identity authentication service |
Implement SSO (Single Sign-On) and IAM (Identity and Access Management) |
| Custom AOP |
Annotations + interceptors |
Lightweight needs, fully controllable |
1. Project Structure
1.1 Package Naming
com.{company}.{project}
├── controller # REST API 端点
├── service # 业务逻辑接口
│ └── impl # 业务逻辑实现
├── mapper # 数据访问层 (MyBatis-Plus/Flex)
├── repository # 数据访问层 (Jimmer)
├── model
│ ├── entity # 数据库实体
│ ├── dto # 请求数据传输对象
│ ├── vo # 响应值对象
│ └── enums # 枚举类
├── api # 外部 API 集成门面
├── manager # 业务协调层
├── config # Spring 配置类
├── annotation # 自定义注解
├── aop # AOP 拦截器
├── exception # 异常类
├── utils # 工具类
├── constant # 常量定义
└── common # 通用基类
1.2 Layered Responsibilities
| Layer |
Responsibilities |
Prohibitions |
| Controller |
Receive requests, parameter validation, permission control, call Service, return unified response |
Business logic must not be included |
| Service |
Business logic processing, transaction management |
Must not directly operate on HttpServletRequest |
| Mapper/Repository |
Database operations |
Business logic must not be included |
| Manager |
Complex business coordination, external API call encapsulation |
Only used for cross-service coordination |
2. Coding Standards
2.1 Controller Layer
@Tag(name = "XxxController", description = "模块描述")
@RestController
@RequestMapping("/xxx")
public class XxxController {
@Resource // 或 @Autowired(根据团队规范)
private XxxService xxxService;
@PostMapping("/action")
@Operation(summary = "操作摘要", description = "操作描述")
@ApiResponses(value = {
@ApiResponse(responseCode = "0", description = "ok"),
@ApiResponse(responseCode = "40000", description = "参数错误"),
})
public BaseResponse<XxxVO> doAction(
@RequestBody XxxRequest request,
HttpServletRequest httpServletRequest) {
ThrowUtils.throwIf(request == null, ErrorCode.PARAMS_ERROR);
// 调用 Service
return ResultUtils.success(result);
}
}
Mandatory Standards:
- All Controllers must use the
@Tag annotation (OpenAPI 3.0)
- All methods must use the
@Operation + @ApiResponses annotation
- The return type must be
BaseResponse<T>
- Multiple parameters must be encapsulated into a Request object (multiple
@RequestParam)
2.2 Service Layer
MyBatis-Plus style
public interface XxxService extends IService<Xxx> {
XxxVO doSomething(XxxRequest request);
}
@Slf4j
@Service
public class XxxServiceImpl extends ServiceImpl<XxxMapper, Xxx>
implements XxxService {
@Override
@Transactional(rollbackFor = Exception.class)
public XxxVO doSomething(XxxRequest request) {
// 业务逻辑
}
}
MyBatis-Flex style
public interface XxxService extends IService<Xxx> {
XxxVO doSomething(XxxRequest request);
}
@Slf4j
@Service
public class XxxServiceImpl extends ServiceImpl<XxxMapper, Xxx>
implements XxxService {
@Override
public XxxVO doSomething(XxxRequest request) {
// 使用 QueryWrapper 链式查询
QueryWrapper query = QueryWrapper.create()
.where(XXX.ID.eq(request.getId()));
return mapper.selectOneByQuery(query);
}
}
Jimmer style
public interface XxxService {
XxxVO doSomething(XxxRequest request);
}
@Slf4j
@Service
@RequiredArgsConstructor
public class XxxServiceImpl implements XxxService {
private final JSqlClient sqlClient;
@Override
public XxxVO doSomething(XxxRequest request) {
// 使用 Jimmer DSL
return sqlClient.createQuery(XxxTable.$)
.where(XxxTable.$.id().eq(request.getId()))
.select(XxxTable.$)
.fetchOne();
}
}
Mandatory Standards:
- Use
@Slf4j annotation
- Operations involving multiple tables must use
@Transactional
2.3 Mapper/Repository Layer
MyBatis-Plus
@Mapper
public interface XxxMapper extends BaseMapper<Xxx> {
// 复杂查询使用 @Select 或 XML
}
MyBatis-Flex
@Mapper
public interface XxxMapper extends BaseMapper<Xxx> {
// 支持链式查询,无需 XML
}
Jimmer
public interface XxxRepository extends JRepository<Xxx, Long> {
// Jimmer 自动生成实现
}
2.4 Model Layer
Entity:
// MyBatis-Plus / MyBatis-Flex
@Data
@TableName("table_name")
public class Xxx implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_ID)
private Long id;
@TableLogic
private Integer isDelete;
}
// Jimmer(不可变对象)
@Entity
public interface Xxx {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
long id();
String name();
@LogicalDeleted("1")
int isDelete();
}
Request DTO:
@Data
public class XxxRequest implements Serializable {
private static final long serialVersionUID = 1L;
// 请求字段
}
VO:
@Data
public class XxxVO implements Serializable {
private static final long serialVersionUID = 1L;
// 响应字段
}
Mandatory Specifications:
- All Request/VO must implement
Serializable
- must declare
serialVersionUID
- use
@Data annotation (except Jimmer Entity)
3. Unified Response Specification
3.1 BaseResponse Structure
public class BaseResponse<T> implements Serializable {
private int code; // 状态码
private T data; // 响应数据
private String message; // 响应消息
}
3.2 ResultUtils Usage
// 成功响应
return ResultUtils.success(data);
// 失败响应
return ResultUtils.error(ErrorCode.PARAMS_ERROR);
return ResultUtils.error(ErrorCode.PARAMS_ERROR, "自定义消息");
3.3 ErrorCode Enum
| Error Code |
Constant |
Description |
| 0 |
SUCCESS |
Success |
| 40000 |
PARAMS_ERROR |
Request parameter error |
| 40100 |
NOT_LOGIN_ERROR |
Not logged in |
| 40101 |
NO_AUTH_ERROR |
No permission |
| 40300 |
FORBIDDEN_ERROR |
Access forbidden |
| 40400 |
NOT_FOUND_ERROR |
Data does not exist |
| 50000 |
SYSTEM_ERROR |
Internal system exception |
| 50001 |
OPERATION_ERROR |
Operation failed |
4. Exception Handling Specification
4.1 ThrowUtils Usage
// 条件抛出
ThrowUtils.throwIf(condition, ErrorCode.PARAMS_ERROR);
ThrowUtils.throwIf(condition, ErrorCode.PARAMS_ERROR, "自定义消息");
// 示例
ThrowUtils.throwIf(request == null, ErrorCode.PARAMS_ERROR);
ThrowUtils.throwIf(user == null, ErrorCode.NOT_FOUND_ERROR, "用户不存在");
4.2 BusinessException Usage
// 直接抛出
throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
throw new BusinessException(ErrorCode.OPERATION_ERROR, "操作失败原因");
5. Access Control Specification
5.1 Sa-Token Solution
// 配置类
@Configuration
public class SaTokenConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new SaInterceptor(handle -> {
SaRouter.match("/**").check(r -> StpUtil.checkLogin());
SaRouter.match("/admin/**").check(r -> StpUtil.checkRole("admin"));
})).addPathPatterns("/**").excludePathPatterns("/user/login");
}
}
// Controller 使用
@SaCheckLogin
@SaCheckRole("admin")
@PostMapping("/admin/action")
public BaseResponse<Boolean> adminAction(...) { }
5.2 Spring Security Solution
// 配置类
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(auth -> auth
.requestMatchers("/user/login").permitAll()
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
);
return http.build();
}
}
// Controller 使用
@PreAuthorize("hasRole('ADMIN')")
@PostMapping("/admin/action")
public BaseResponse<Boolean> adminAction(...) { }
5.3 Shiro Solution
// 配置类
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager manager) {
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(manager);
Map<String, String> map = new LinkedHashMap<>();
map.put("/user/login", "anon");
map.put("/admin/**", "roles[admin]");
map.put("/**", "authc");
bean.setFilterChainDefinitionMap(map);
return bean;
}
}
// Controller 使用
@RequiresRoles("admin")
@PostMapping("/admin/action")
public BaseResponse<Boolean> adminAction(...) { }
5.4 Custom AOP Solution
// 注解定义
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthCheck {
String mustRole() default "";
}
// AOP 拦截器
@Aspect
@Component
public class AuthInterceptor {
@Around("@annotation(authCheck)")
public Object doAuth(ProceedingJoinPoint joinPoint, AuthCheck authCheck) throws Throwable {
String mustRole = authCheck.mustRole();
// 权限校验逻辑
return joinPoint.proceed();
}
}
// Controller 使用
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
@PostMapping("/admin/action")
public BaseResponse<Boolean> adminAction(...) { }
5.5 Role Constants
public interface UserConstant {
String DEFAULT_ROLE = "user"; // 普通用户
String ADMIN_ROLE = "admin"; // 管理员
String VIP_ROLE = "vip"; // VIP 用户
}
6. Utility Library Usage Specification
6.1 Hutool Usage
// 字符串处理
StrUtil.isBlank(str);
StrUtil.format("Hello, {}", name);
// 日期处理
DateUtil.format(date, "yyyy-MM-dd");
DateUtil.parse("2024-01-01");
// 对象拷贝
BeanUtil.copyProperties(source, target);
// JSON 处理
JSONUtil.toJsonStr(object);
JSONUtil.toBean(jsonStr, Xxx.class);
// 加密
SecureUtil.md5(password);
SecureUtil.sha256(password);
// 随机数
RandomUtil.randomNumbers(6); // 6位数字验证码
RandomUtil.randomString(32); // 32位随机字符串
6.2 Native Java Alternatives (without Hutool)
// 字符串处理
str == null || str.isBlank();
String.format("Hello, %s", name);
// 日期处理
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
// 对象拷贝
BeanUtils.copyProperties(source, target); // Spring
// JSON 处理
objectMapper.writeValueAsString(object); // Jackson
objectMapper.readValue(jsonStr, Xxx.class);
// 加密
MessageDigest.getInstance("MD5").digest(password.getBytes());
// 随机数
new Random().nextInt(1000000);
UUID.randomUUID().toString().replace("-", "");
7. Naming Specification
7.1 Class Naming
| Type |
Naming Pattern |
Example |
| Controller |
XxxController |
UserController, PictureController |
| Service Interface |
XxxService |
UserService, PictureService |
| Service Implementation |
XxxServiceImpl |
UserServiceImpl, PictureServiceImpl |
| Mapper |
XxxMapper |
UserMapper, PictureMapper |
| Repository |
XxxRepository |
UserRepository (Jimmer) |
| Entity |
Xxx |
User, Picture |
| VO |
XxxVO |
UserVO, PictureVO |
7.2 DTO Naming
| Operation Type |
Naming Pattern |
Example |
| General Request |
XxxRequest |
UserRequest |
| Create/Add |
XxxAddRequest / XxxCreateRequest |
PictureAddRequest |
| Update |
XxxUpdateRequest |
UserUpdateRequest |
| Edit |
XxxEditRequest |
PictureEditRequest |
| Query |
XxxQueryRequest |
PictureQueryRequest |
| Login |
XxxLoginRequest |
UserLoginRequest |
| Register |
XxxRegisterRequest |
UserRegisterRequest |
7.3 Method Naming
| Operation |
Naming Pattern |
Example |
| Query single |
getXxx / getXxxById |
getUser, getPictureById |
| Query list |
listXxx |
listPictures |
| Paginated query |
listXxxByPage |
listPictureByPage |
| Add |
addXxx / createXxx |
addPicture |
| Update |
updateXxx |
updateUser |
| Delete |
deleteXxx |
deletePicture |
8. Dependency Injection Specification
8.1 Recommended Approaches
| Approach |
Description |
Applicable Scenario |
@Resource |
JSR-250 standard, injection by name |
Recommended, strong explicitness |
@Autowired |
Spring native, injection by type |
Common in Spring projects |
| Constructor injection |
Immutable, conducive to testing |
Lombok @RequiredArgsConstructor |
// @Resource(推荐)
@Resource
private UserService userService;
// @Autowired
@Autowired
private UserService userService;
// 构造器注入(Lombok)
@RequiredArgsConstructor
@Service
public class XxxServiceImpl {
private final UserService userService;
}
9. Logging Specification
9.1 Usage
@Slf4j
@Service
public class XxxServiceImpl {
public void doSomething() {
log.info("操作描述, param={}", param);
log.error("错误描述", exception);
}
}
9.2 Log Levels
| Level |
Scenario |
| ERROR |
System exceptions, critical business errors |
| WARN |
Potential issues, degradation handling |
| INFO |
Important business operations, state changes |
| DEBUG |
Development and debugging information |
10. Pagination Specification
10.1 Pagination Request
@Data
@EqualsAndHashCode(callSuper = true)
public class XxxQueryRequest extends PageRequest {
// 查询字段
}
// PageRequest 基类
@Data
public class PageRequest implements Serializable {
private int current = 1;
private int pageSize = 10;
private String sortField;
private String sortOrder = "descend"; // ascend / descend
}
10.2 Pagination Return
Page<XxxVO> page = xxxService.listByPage(request);
return ResultUtils.success(page);
11. Spring Boot Version Differences
11.1 Package Import Differences
| Feature |
Spring Boot 2.x |
Spring Boot 3.x+ |
| Servlet |
javax.servlet.* |
jakarta.servlet.* |
| Validation |
javax.validation.* |
jakarta.validation.* |
| Persistence |
javax.persistence.* |
jakarta.persistence.* |
11.2 Configuration Differences
# Spring Boot 2.x
spring:
redis:
host: localhost
port: 6379
# Spring Boot 3.x+
spring:
data:
redis:
host: localhost
port: 6379
12. Prohibited Items
- Prohibited Write business logic in the Controller
- Prohibited Use multiple
@RequestParam to receive parameters (encapsulate as a Request object)
- Prohibited Return a non-
BaseResponse<T> type
- Prohibited Request/VO does not implement
Serializable
- Prohibited Directly operate on
HttpServletRequest
- Prohibited Hardcode role strings (use constants)
- Prohibited Mix the usage styles of different ORM frameworks
- Prohibited Use DEBUG-level logs in the production environment
Appendix: Current Project Configuration
The technology stack used by this project (yun-picture-backend):
| Configuration Item |
Choice |
| Spring Boot |
3.5.7 |
| JDK |
17 |
| ORM |
MyBatis-Plus 3.5.14 |
| Utility Library |
Hutool 5.8.40 |
| Access Control |
Custom AOP (@AuthCheck) |
| Dependency Injection |
@Resource |
| API Documentation |
SpringDoc OpenAPI 3.0 |
13. Code Templates
For complete copyable code templates, see references/code-templates.md, including:
| Package |
Class |
| common |
BaseResponse, PageRequest, DeleteRequest |
| controller |
MainController |
| exception |
ErrorCode, BusinessException, GlobalExceptionHandler |
| utils |
ResultUtils, ThrowUtils |
| config |
MybatisPlusConfig, JsonConfig, OpenApiConfig |