springboot-init
11
总安装量
11
周安装量
#27888
全站排名
安装命令
npx skills add https://github.com/wardbit/springboot-init-skills --skill springboot-init
Agent 安装分布
opencode
7
codex
7
gemini-cli
6
claude-code
6
amp
5
github-copilot
5
Skill 文档
springboot-init
0. ææ¯æ é ç½®
ä½¿ç¨æ¬è§èåï¼è¯·ç¡®è®¤é¡¹ç®çææ¯éåï¼
0.1 æ ¸å¿æ¡æ¶çæ¬
| é 置项 | å¯éå¼ | 说æ |
|---|---|---|
| Spring Boot | 2.x / 3.x / 4.x | 2.x æ¯æ Java 8+ï¼3.x/4.x éè¦ Java 17+ |
| JDK | 8 / 11 / 17 / 21 / 25 | æ ¹æ® Spring Boot çæ¬éæ© |
çæ¬å ¼å®¹ç©éµï¼
| Spring Boot | æä½ JDK | æ¨è JDK | Jakarta EE |
|---|---|---|---|
| 2.x | 8 | 11 | javax.* |
| 3.x | 17 | 17 | jakarta.* |
| 4.x | 17 | 21 | jakarta.* |
0.2 ORM æ¡æ¶
| æ¡æ¶ | ç¹ç¹ | éç¨åºæ¯ |
|---|---|---|
| MyBatis-Plus | å¢å¼º MyBatisï¼ç®å CRUD | ä¼ ç»é¡¹ç®ãå¿«éå¼å |
| MyBatis-Flex | è½»é级ã髿§è½ãé¾å¼æ¥è¯¢ | è¿½æ±æ§è½ãçµæ´»æ¥è¯¢ |
| Jimmer | ä¸å¯å对象ã强类å DSL | 夿é¢å模åãDDD é¡¹ç® |
0.3 å·¥å ·åº
| åº | 说æ | 建议 |
|---|---|---|
| Hutool | å ¨è½å·¥å ·åºï¼æ¥æãå å¯ãHTTPãJSON çï¼ | æ¨èï¼åå°éå¤ä»£ç |
| Apache Commons | ç»å ¸å·¥å ·åºéå | è½»ééæ±å¯é |
| Guava | Google å·¥å ·åº | éåå¤çãç¼åéæ± |
0.4 è®¿é®æ§å¶æ¡æ¶
| æ¡æ¶ | ç¹ç¹ | éç¨åºæ¯ |
|---|---|---|
| Sa-Token | è½»é级ãå¼ç®±å³ç¨ãåè½å ¨é¢ | å¿«éå¼åãä¸å°é¡¹ç® |
| Spring Security | Spring 宿¹ãåè½å¼ºå¤§ãé«åº¦å¯å®å¶ | ä¼ä¸çº§é¡¹ç®ã夿æé |
| Shiro | Apache 项ç®ãç®åæç¨ | ä¼ ç»é¡¹ç®ãç®åæéãè±ç¦»Spring Boot |
| Casbin | 强大ãçµæ´»ã坿©å± | 夿卿æéæ§å¶ï¼å¯¹æ§è½ä¸ææ |
| Keycloak | ç¬ç«çèº«ä»½è®¤è¯æå¡ | å®ç° SSO (åç¹ç»å½) å IAM (身份è¯å«ä¸è®¿é®ç®¡ç) |
| èªå®ä¹ AOP | 注解 + æ¦æªå¨ | è½»ééæ±ãå®å ¨å¯æ§ |
1. 项ç®ç»æ
1.1 å å½å
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 åå±èè´£
| å±çº§ | èè´£ | ç¦æ¢äºé¡¹ |
|---|---|---|
| Controller | æ¥æ¶è¯·æ±ãåæ°æ ¡éªãæéæ§å¶ãè°ç¨ Serviceãè¿åç»ä¸ååº | ç¦æ¢å å«ä¸å¡é»è¾ |
| Service | ä¸å¡é»è¾å¤çãäºå¡ç®¡ç | ç¦æ¢ç´æ¥æä½ HttpServletRequest |
| Mapper/Repository | æ°æ®åºæä½ | ç¦æ¢å å«ä¸å¡é»è¾ |
| Manager | 夿ä¸å¡åè°ãå¤é¨ API è°ç¨å°è£ | ä» ç¨äºè·¨æå¡åè° |
2. ç¼ç è§è
2.1 Controller å±
@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);
}
}
强å¶è§èï¼
- ææ Controller å¿
须使ç¨
@Tag注解ï¼OpenAPI 3.0ï¼ - æææ¹æ³å¿
须使ç¨
@Operation+@ApiResponses注解 - è¿åç±»åå¿
须为
BaseResponse<T> - å¤åæ°å¿
é¡»å°è£
为 Request 对象ï¼ç¦æ¢å¤ä¸ª
@RequestParamï¼
2.2 Service å±
MyBatis-Plus 飿 ¼
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 飿 ¼
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 飿 ¼
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();
}
}
强å¶è§èï¼
- 使ç¨
@Slf4j注解 - æ¶åå¤è¡¨æä½å¿
须使ç¨
@Transactional
2.3 Mapper/Repository å±
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 å±
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;
// ååºå段
}
强å¶è§èï¼
- ææ Request/VO å¿
é¡»å®ç°
Serializable - å¿
须声æ
serialVersionUID - 使ç¨
@Data注解ï¼Jimmer Entity é¤å¤ï¼
3. ç»ä¸ååºè§è
3.1 BaseResponse ç»æ
public class BaseResponse<T> implements Serializable {
private int code; // ç¶æç
private T data; // ååºæ°æ®
private String message; // ååºæ¶æ¯
}
3.2 ResultUtils 使ç¨
// æåååº
return ResultUtils.success(data);
// 失败ååº
return ResultUtils.error(ErrorCode.PARAMS_ERROR);
return ResultUtils.error(ErrorCode.PARAMS_ERROR, "èªå®ä¹æ¶æ¯");
3.3 ErrorCode æä¸¾
| é误ç | 常é | 说æ |
|---|---|---|
| 0 | SUCCESS | æå |
| 40000 | PARAMS_ERROR | 请æ±åæ°é误 |
| 40100 | NOT_LOGIN_ERROR | æªç»å½ |
| 40101 | NO_AUTH_ERROR | æ æé |
| 40300 | FORBIDDEN_ERROR | ç¦æ¢è®¿é® |
| 40400 | NOT_FOUND_ERROR | æ°æ®ä¸åå¨ |
| 50000 | SYSTEM_ERROR | ç³»ç»å é¨å¼å¸¸ |
| 50001 | OPERATION_ERROR | æä½å¤±è´¥ |
4. å¼å¸¸å¤çè§è
4.1 ThrowUtils 使ç¨
// æ¡ä»¶æåº
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 使ç¨
// ç´æ¥æåº
throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
throw new BusinessException(ErrorCode.OPERATION_ERROR, "æä½å¤±è´¥åå ");
5. è®¿é®æ§å¶è§è
5.1 Sa-Token æ¹æ¡
// é
置类
@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 æ¹æ¡
// é
置类
@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 æ¹æ¡
// é
置类
@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 èªå®ä¹ AOP æ¹æ¡
// 注解å®ä¹
@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 è§è²å¸¸é
public interface UserConstant {
String DEFAULT_ROLE = "user"; // æ®éç¨æ·
String ADMIN_ROLE = "admin"; // 管çå
String VIP_ROLE = "vip"; // VIP ç¨æ·
}
6. å·¥å ·åºä½¿ç¨è§è
6.1 Hutool 使ç¨
// å符串å¤ç
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 åç Java æ¿ä»£ï¼ä¸ä½¿ç¨ 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. å½åè§è
7.1 ç±»å½å
| ç±»å | å½åæ¨¡å¼ | ç¤ºä¾ |
|---|---|---|
| Controller | XxxController | UserController, PictureController |
| Service æ¥å£ | XxxService | UserService, PictureService |
| Service å®ç° | XxxServiceImpl | UserServiceImpl, PictureServiceImpl |
| Mapper | XxxMapper | UserMapper, PictureMapper |
| Repository | XxxRepository | UserRepository (Jimmer) |
| Entity | Xxx | User, Picture |
| VO | XxxVO | UserVO, PictureVO |
7.2 DTO å½å
| æä½ç±»å | å½åæ¨¡å¼ | ç¤ºä¾ |
|---|---|---|
| éç¨è¯·æ± | XxxRequest | UserRequest |
| å建/æ·»å | XxxAddRequest / XxxCreateRequest | PictureAddRequest |
| æ´æ° | XxxUpdateRequest | UserUpdateRequest |
| ç¼è¾ | XxxEditRequest | PictureEditRequest |
| æ¥è¯¢ | XxxQueryRequest | PictureQueryRequest |
| ç»å½ | XxxLoginRequest | UserLoginRequest |
| 注å | XxxRegisterRequest | UserRegisterRequest |
7.3 æ¹æ³å½å
| æä½ | å½åæ¨¡å¼ | ç¤ºä¾ |
|---|---|---|
| æ¥è¯¢å个 | getXxx / getXxxById | getUser, getPictureById |
| æ¥è¯¢å表 | listXxx | listPictures |
| å页æ¥è¯¢ | listXxxByPage | listPictureByPage |
| æ·»å | addXxx / createXxx | addPicture |
| æ´æ° | updateXxx | updateUser |
| å é¤ | deleteXxx | deletePicture |
8. ä¾èµæ³¨å ¥è§è
8.1 æ¨èæ¹å¼
| æ¹å¼ | 说æ | éç¨åºæ¯ |
|---|---|---|
@Resource |
JSR-250 æ åï¼æåç§°æ³¨å ¥ | æ¨èï¼æç¡®æ§å¼º |
@Autowired |
Spring åçï¼æç±»åæ³¨å ¥ | Spring 项ç®éç¨ |
| æé 卿³¨å ¥ | ä¸å¯åãå©äºæµè¯ | Lombok @RequiredArgsConstructor |
// @Resourceï¼æ¨èï¼
@Resource
private UserService userService;
// @Autowired
@Autowired
private UserService userService;
// æé 卿³¨å
¥ï¼Lombokï¼
@RequiredArgsConstructor
@Service
public class XxxServiceImpl {
private final UserService userService;
}
9. æ¥å¿è§è
9.1 ä½¿ç¨æ¹å¼
@Slf4j
@Service
public class XxxServiceImpl {
public void doSomething() {
log.info("æä½æè¿°, param={}", param);
log.error("é误æè¿°", exception);
}
}
9.2 æ¥å¿çº§å«
| çº§å« | åºæ¯ |
|---|---|
| ERROR | ç³»ç»å¼å¸¸ãä¸å¡å ³é®é误 |
| WARN | æ½å¨é®é¢ãé级å¤ç |
| INFO | éè¦ä¸å¡æä½ãç¶æåæ´ |
| DEBUG | å¼åè°è¯ä¿¡æ¯ |
10. å页è§è
10.1 å页请æ±
@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 å页è¿å
Page<XxxVO> page = xxxService.listByPage(request);
return ResultUtils.success(page);
11. Spring Boot çæ¬å·®å¼
11.1 å å¯¼å ¥å·®å¼
| åè½ | 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 é 置差å¼
# Spring Boot 2.x
spring:
redis:
host: localhost
port: 6379
# Spring Boot 3.x+
spring:
data:
redis:
host: localhost
port: 6379
12. ç¦æ¢äºé¡¹
- ç¦æ¢ å¨ Controller ä¸ç¼åä¸å¡é»è¾
- ç¦æ¢ 使ç¨å¤ä¸ª
@RequestParamæ¥æ¶åæ°ï¼å°è£ 为 Request å¯¹è±¡ï¼ - ç¦æ¢ è¿åé
BaseResponse<T>ç±»å - ç¦æ¢ Request/VO ä¸å®ç°
Serializable - ç¦æ¢ å¨ Service ä¸ç´æ¥æä½
HttpServletRequest - ç¦æ¢ 硬ç¼ç è§è²å符串ï¼ä½¿ç¨å¸¸éï¼
- ç¦æ¢ æ··ç¨ä¸å ORM æ¡æ¶çåæ³
- ç¦æ¢ å¨ç产ç¯å¢ä½¿ç¨ DEBUG çº§å«æ¥å¿
éå½ï¼å½å项ç®é ç½®
æ¬é¡¹ç®ï¼yun-picture-backendï¼ä½¿ç¨çææ¯æ ï¼
| é 置项 | éæ© |
|---|---|
| Spring Boot | 3.5.7 |
| JDK | 17 |
| ORM | MyBatis-Plus 3.5.14 |
| å·¥å ·åº | Hutool 5.8.40 |
| è®¿é®æ§å¶ | èªå®ä¹ AOPï¼@AuthCheckï¼ |
| ä¾èµæ³¨å ¥ | @Resource |
| API ææ¡£ | SpringDoc OpenAPI 3.0 |
13. ä»£ç æ¨¡æ¿
宿´å¯å¤å¶çä»£ç æ¨¡æ¿è§ references/code-templates.mdï¼å å«ï¼
| å | ç±» |
|---|---|
| common | BaseResponse, PageRequest, DeleteRequest |
| controller | MainController |
| exception | ErrorCode, BusinessException, GlobalExceptionHandler |
| utils | ResultUtils, ThrowUtils |
| config | MybatisPlusConfig, JsonConfig, OpenApiConfig |