Backend Development 8 min read

5 Must‑Know Spring Boot 3.2.5 Features You Can Start Using Today

This article walks through five practical Spring Boot 3.2.5 enhancements—including collection‑parameter validation, wildcard @PropertySource loading, improved method injection, custom thread‑pool scheduling, and robust Number‑type request handling—showing code examples, console output, and migration tips from older versions.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
5 Must‑Know Spring Boot 3.2.5 Features You Can Start Using Today

1. Collection Parameter Validation

Since Spring 6.1, controller method parameters of collection types can be validated with annotations. Example:

<code>public class Foo {
    @NotEmpty(message = "name is required")
    private String name;
    // getters, setters
}

@PostMapping("/foo")
public Object foo(@Valid @RequestBody List<Foo> foos, BindingResult error) {
    error.getFieldErrors().forEach(err -> {
        System.err.printf("字段【%s】, %s%n", err.getField(), err.getDefaultMessage());
    });
    return foos;
}
</code>

Each Foo element is validated; the console output is shown in the following screenshots.

2. @PropertySource Supports Wildcards

Previously you had to list each configuration file explicitly:

<code>@Configuration
@PropertySource("classpath:com/pack/app.properties")
public class AppConfig {}
</code>

Or list several files manually:

<code>@Configuration
@PropertySource({
    "classpath:com/pack/a.properties",
    "classpath:com/pack/b.properties"
})
public class AppConfig {}
</code>

Now a wildcard pattern can load all .properties files in a directory:

<code>@Configuration
@PropertySource("classpath:com/pack/ioc/property_source/*.properties")
public class AppConfig {}
</code>

3. Method Injection Issue

In Spring Boot 2.7.18 (Spring 5.3.31) the following example injects A and B via a method with @Autowired(required = false) :

<code>@Component
public static class A {}
public static class B {}

@Component
public class MethodInectTest implements InitializingBean {
    // via method injection
    @Autowired(required = false)
    public void setProp(A a, @Nullable B b) {
        this.a = a;
        this.b = b;
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.err.println(this);
    }
    @Override
    public String toString() {
        return "MethodInectTest [a=" + a + ", b=" + b + "]";
    }
}
</code>

Running on the older version prints MethodInectTest [a=null, b=null] . After removing required=false , A is injected correctly. On Spring 6.1.x the same code prints MethodInectTest [a=com.pack.MethodInectTest$A@..., b=null] , which is the expected behavior.

4. @Scheduled Supports Custom Thread Pools

Enable scheduling and define a task:

<code>@Component
@EnableScheduling
public class TaskComponent {
    @Scheduled(cron = "*/3 * * * * *")
    public void task() {
        System.err.printf("%s - 执行任务%n", Thread.currentThread().getName());
    }
}
</code>

By default it runs in the framework’s thread pool. To use a custom pool, define a TaskScheduler bean:

<code>@Bean
TaskScheduler packTaskScheduler() {
    ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
    taskScheduler.setPoolSize(2);
    taskScheduler.setThreadNamePrefix("pack-task1-");
    return taskScheduler;
}
</code>

From Spring 6.1 onward the scheduler attribute can be set on @Scheduled to bind a specific bean:

<code>@Configuration
public class TaskConfig {
    @Bean
    public TaskScheduler packTaskScheduler() { /* … */ }
    @Bean
    public TaskScheduler taskScheduler222() { /* … */ }
}

public class TaskComponent {
    @Scheduled(cron = "*/3 * * * * *", scheduler = "packTaskScheduler")
    public void task() { /* … */ }

    @Scheduled(cron = "*/7 * * * * *", scheduler = "taskScheduler222")
    public void task7() { /* … */ }
}
</code>

Each scheduled method now runs in its designated thread pool.

5. Controller Receiving Number Parameters

Define a controller with a default value for an Integer request parameter:

<code>@RestController
@RequestMapping("/integers")
public class IntegerParamSpaceController {
    @GetMapping("index")
    public Object index(@RequestParam(defaultValue = "666") Integer id) {
        System.out.println(id + "=====");
        return id;
    }
}
</code>

Behavior on Spring Boot 2.7.18:

Non‑numeric value → binding error, no output.

Empty value → prints the default 666 .

Value %20 (space) → prints null and may cause NPE.

On Spring Boot 3.2.5 the handling is improved: non‑numeric values still cause a binding error, empty values use the default, and %20 is now treated as an empty string, resulting in the default 666 rather than null . This change was introduced in Spring 6.1.

Overall, these five enhancements simplify validation, configuration loading, method injection, task scheduling, and request‑parameter handling in modern Spring Boot applications.

backendJavaConfigurationValidationschedulingSpring Bootparameter-binding
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

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.