Spring Boot Project Initialization, Version Management, and Common Backend Tools
This article walks through setting up a Spring Boot project, handling version compatibility with Spring Cloud, Kafka, and Maven, demonstrates global exception handling, logging, CORS and Swagger configurations, and recommends useful backend utilities such as embedded Redis, MyBatis Plus, and Redisson.
When starting a new backend project, developers often struggle with environment setup, especially downloading and licensing IDEs like JetBrains; the article suggests using the community edition or proper licensing to avoid wasted time.
It then shows how to create a Spring Boot project and presents version compatibility tables for Spring Cloud, Spring Boot, and Kafka, highlighting common pitfalls when the server and client versions differ, illustrated by a real error message:
?,?:Exception thrown when sending a message with key='null' and payload='byte[205]' to topic notify org.apache.kafka.common.errors.UnsupportedVersionException: Attempting to use idempotence with a broker which does not support the required message format (v2). The broker must be version 0.11
The article emphasizes using Maven to manage dependencies and explains Spring Boot's auto‑configuration ( autoconfiguration ) that simplifies dependency handling.
Key code examples are provided:
@RestControllerAdvice @ResponseBody @Slf4j public class GlobalExceptionHandler { @ExceptionHandler(value = {MethodArgumentNotValidException.class}) public ResponseResult handleValidException(MethodArgumentNotValidException ex, HttpServletResponse httpServletResponse) { log.error("[GlobalExceptionHandler][handleValidException] 参数校验exception", ex); return wrapperBindingResult(ex.getBindingResult(), httpServletResponse); } private ResponseResult wrapperBindingResult(BindingResult bindingResult, HttpServletResponse httpServletResponse) { StringBuilder errorMsg = new StringBuilder(); for (ObjectError error : bindingResult.getAllErrors()) { if (error instanceof FieldError) { errorMsg.append(((FieldError) error).getField()).append(": "); } errorMsg.append(error.getDefaultMessage() == null ? "" : error.getDefaultMessage()); } httpServletResponse.setStatus(HttpStatus.BAD_REQUEST.value()); return ResponseResult.failed(ResultCode.FAILED.getCode(), null); } }
@Aspect @Slf4j @Component public class WebLogAspect { @Pointcut("@within(org.springframework.stereotype.Controller) || @within(org.springframework.web.bind.annotation.RestController)") public void cutController() {} @Before("cutController()") public void doBefore(JoinPoint point) { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String url = request.getRequestURL().toString(); List list = Lists.newArrayList(); for (Object object : point.getArgs()) { if (object instanceof MultipartFile || object instanceof HttpServletRequest || object instanceof HttpServletResponse || object instanceof BindingResult) { continue; } list.add(object); } log.info("请求 uri:[{}],params:[{}]", url, StringUtils.join(list, ",")); } @AfterReturning(returning = "response", pointcut = "cutController()") public void doAfterReturning(Object response) { if (response != null) { log.info("请求返回result:[{}]", JSONUtil.toJsonStr(response)); } } }
@Configuration public class GlobalCorsConfig { @Bean public CorsFilter corsFilter() { CorsConfiguration config = new CorsConfiguration(); config.setAllowedOrigins(Lists.newArrayList("*")); config.setAllowCredentials(true); config.addAllowedHeader("*"); config.addAllowedMethod("*"); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); return new CorsFilter(source); } }
@Configuration @EnableOpenApi public class SwaggerConfig { @Bean public Docket docket() { return new Docket(DocumentationType.OAS_30) .apiInfo(apiInfo()) .enable(true) .select() .apis(RequestHandlerSelectors.basePackage("com.vines.controller")) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("项目描述") .description("基础服务项目描述") .contact(new Contact("作者", "作者URL", "作者Email")) .version("1.0") .build(); } }
It also defines a generic response wrapper:
@Data public class ResponseResult { private int code; private String message; private T data; public static ResponseResult success(T data) { ... } public static ResponseResult success() { ... } public static ResponseResult failed(int code, String message) { ... } public static boolean isSucceed(ResponseResult responseResult) { ... } }
Finally, the article lists useful tools for backend development, such as embedded Redis ( https://github.com/kstyrc/embedded-redis ), embedded MariaDB ( https://github.com/mariadb ), embedded Kafka via Spring Kafka starter, Hutool ( https://hutool.cn/ ), MyBatis‑Plus ( https://baomidou.com/ ), MapStruct ( https://mapstruct.org/ ), and Redisson ( https://github.com/redisson/redisson ).
The conclusion reminds readers that beyond IDE setup, version mismatches and environment inconsistencies are the biggest time‑wasters in real projects.
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.