Backend Development 11 min read

Spring Boot Project Initialization, Version Management, and Common Development Tools Guide

This article walks through the challenges of setting up a Java development environment, demonstrates how to create a Spring Boot project, explains version compatibility between Spring Cloud, Spring Boot, and Kafka, showcases essential Maven configurations and code snippets for global exception handling, logging, CORS, Swagger, and recommends useful in‑memory tools such as embedded Redis, DB, Kafka, Hutool, MyBatis‑Plus, MapStruct, and Redisson.

Architecture Digest
Architecture Digest
Architecture Digest
Spring Boot Project Initialization, Version Management, and Common Development Tools Guide

The article begins with a promotional note about a free programmer book, then dives into the common pain points developers face when setting up their IDEs, especially the licensing issues of JetBrains products and the temptation to use cracked versions.

It proceeds to demonstrate how to initialize a new Spring Boot project using an IDE, showing screenshots of the generated project structure containing the main class, configuration files, and test classes.

Next, it discusses version management, highlighting the compatibility matrix between Spring Cloud, Spring Boot, and Kafka. It provides the official URLs for the version tables:

https://spring.io/projects/spring-cloud

https://spring.io/projects/spring-kafka

An example error is shown when the Kafka client version (3.0.4) does not match the server version (0.11), illustrating the importance of aligning versions across environments.

The article then emphasizes Maven as the tool to manage dependencies, linking to the Maven homepage:

https://maven.apache.org/index.html

Key code snippets are provided for common backend concerns:

Global Exception Handler

@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);
    }
}

Web Logging Aspect

@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));
        }
    }
}

CORS Configuration

@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);
    }
}

Swagger Configuration

@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();
    }
}

Standard Response Wrapper

@Data
public class ResponseResult
{
    private int code;
    private String message;
    private T data;
    public static
ResponseResult
success(T data){
        ResponseResult
r = new ResponseResult<>();
        r.setCode(ResultCode.SUCCESS.getCode());
        r.setMessage(ResultCode.SUCCESS.getMessage());
        r.setData(data);
        return r;
    }
    public static
ResponseResult
success(){
        ResponseResult
r = new ResponseResult<>();
        r.setCode(ResultCode.SUCCESS.getCode());
        r.setMessage(ResultCode.SUCCESS.getMessage());
        return r;
    }
    public static
ResponseResult
failed(int code, String message){
        ResponseResult
r = new ResponseResult<>();
        r.setCode(code);
        r.setMessage(message);
        return r;
    }
    public static boolean isSucceed(ResponseResult responseResult){
        return responseResult.getCode() == ResultCode.SUCCESS.getCode();
    }
}

Beyond these core snippets, the article recommends several in‑memory utilities to simplify testing and development:

Embedded Redis: https://github.com/kstyrc/embedded-redis

Embedded DB (MariaDB): https://github.com/mariadb

In‑memory Kafka via Spring Boot starter (dependency coordinates shown as XML snippet).

Hutool utility library: https://hutool.cn/

MyBatis‑Plus: https://baomidou.com/

MapStruct: https://mapstruct.org/

Redisson client: https://github.com/redisson/redisson

The article concludes with a rhetorical question about the most time‑consuming task in real work, hinting at issues beyond IDE setup, and ends with a promotional QR‑code section offering free access to a book management system.

Javabackend developmentconfigurationMavenSpring Boottesting toolsVersion Management
Architecture Digest
Written by

Architecture Digest

Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.