Backend Development 12 min read

Spring Boot Project Setup: Initialization, Version Management, and Core Scaffold Code

This article walks through creating a Spring Boot project, handling IDE setup, managing Spring Cloud and Kafka version compatibility, using Maven for dependency management, and provides essential scaffold code such as global exception handling, logging aspects, CORS configuration, and Swagger integration.

Architect
Architect
Architect
Spring Boot Project Setup: Initialization, Version Management, and Core Scaffold Code

1. Project Initialization

If you ask developers what they hate most during development, most will answer "environment" – setting up the development environment is a painful task.

The article explains why downloading and activating IDEs (especially JetBrains products) can be time‑consuming, discusses the prevalence of cracked software, and encourages using the free community edition or legitimate licenses.

After setting up the IDE, it shows how to create a Spring Boot project, displaying the freshly generated project structure with a main class, configuration file, and test class.

The newly created project contains a startup class, configuration files, and a test startup class.

2. Version Management

Before starting development, the article warns about version mismatches between Spring Cloud, Spring Boot, and Kafka.

It provides the compatibility table for Spring Cloud and Spring Boot (link: https://spring.io/projects/spring-cloud ) and for Spring Boot and Kafka (link: https://spring.io/projects/spring-kafka ).

It shares a real‑world incident where a production Kafka broker (0.11) was incompatible with a client library (3.0.4) used by a Spring Boot 2.7.x application, leading to an UnsupportedVersionException error.

?,?: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* or later.

The root cause was the mismatch between the production server version and the test environment version. Maven is suggested to manage dependencies and resolve version conflicts.

Maven also provides automatic configuration for Spring Boot, reducing manual dependency handling.

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

Apache Maven is a software project management and comprehension tool

3. Scaffold Code (Core Classes)

The article presents several essential code snippets used in the project.

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

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) {
        // Get request parameters
        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 {
    /** Allow cross‑origin requests */
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowedOrigins(Lists.newArrayList("*")); // allow all origins
        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() { /* ... */ }
    public static
ResponseResult
failed(int code, String message) { /* ... */ }
    public static boolean isSucceed(ResponseResult responseResult) {
        return responseResult.getCode() == ResultCode.SUCCESS.getCode();
    }
}

The article also recommends several useful tools for development, such as embedded Redis ( https://github.com/kstyrc/embedded-redis ), embedded MariaDB, Spring Kafka test starter, Hutool ( https://hutool.cn/ ), MyBatis‑Plus ( https://baomidou.com/ ), MapStruct, and Redisson.

Summary

While IDE configuration can be tedious, the real time‑sink in real projects often comes from mismatched environment versions and dependency conflicts, which can be mitigated by proper version management, Maven dependency handling, and using the scaffold code provided above.

For more technical sharing, readers are encouraged to follow the author, join the community, and leave comments for future topics.

Exception HandlingMavenSpring BootCORSversion compatibilitySwagger
Architect
Written by

Architect

Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.

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.