11 Must‑Know Spring Boot 3.5 Features with Ready‑to‑Use Code Samples
This article walks through eleven notable Spring Boot 3.5 enhancements—including stricter .enabled flags, renamed TaskExecutor beans, Redis URL handling, annotation‑based servlet/filter registration, multi‑property environment loading, structured logging tweaks, WebClient connector settings, task decorators, custom executors, bootstrapExecutor auto‑configuration, and secured heapdump actuator endpoint—providing concise explanations and runnable code snippets.
Spring Boot 3.5 introduces many new features. Below are eleven of the most useful enhancements, each accompanied by a brief description and example code.
1. Strict .enabled configuration property
The .enabled property now only accepts true or false , making the behavior consistent across the framework.
2. Renamed TaskExecutor bean
Spring Boot no longer creates a taskExecutor bean; only applicationTaskExecutor is provided. If existing code references the old name, add an alias via a BeanFactoryPostProcessor :
<code>@Configuration
public class AppConfig {
@Bean
static BeanFactoryPostProcessor taskExecutorAlias() {
return beanFactory -> beanFactory.registerAlias(
"applicationTaskExecutor", "taskExecutor");
}
}
</code>3. Redis configuration
When spring.data.redis.url is set, the database is derived from the URL (default 0 if omitted). The separate spring.data.redis.database property is ignored.
<code>spring:
data:
redis:
url: redis://user:[email protected]:6379/8
# database: 2 <-- ignored, URL specifies 8
</code>4. Annotation‑based Servlet and Filter registration
Two new annotations replace the traditional ServletRegistrationBean and FilterRegistrationBean :
@ServletRegistration – registers a Servlet
@FilterRegistration – registers a Filter
<code>@Bean
@FilterRegistration(name = "my-filter", urlPatterns = "/api/*", order = 0)
MyFilter myFilter() {
return new MyFilter();
}
</code>5. Loading multiple properties from a single environment variable
Define a multi‑line variable in PowerShell and import it with the env: prefix:
<code>PS C:\Users\Administrator> $appsetting = @"
>> pack.title=Pack
>> pack.version=1.0.0
> "@
PS C:\Users\Administrator> [System.Environment]::SetEnvironmentVariable("APP_PACK", $appsetting, "User")
</code>In application.yml :
<code>spring:
config:
import:
- "env:APP_PACK"
</code>Access the values with @Value :
<code>@Component
public class EnvProperties implements CommandLineRunner {
@Value("${pack.title}")
private String title;
@Value("${pack.version}")
private String version;
@Override
public void run(String... args) {
System.err.printf("title = %s, version = %s%n", title, version);
}
}
</code>6. Customizable structured‑log stacktrace
Properties under logging.structured.json.stacktrace let you control stacktrace output, e.g. root order, max length, frame depth, inclusion of common frames, and hash inclusion.
root – first or last
max-length – maximum characters
max-throwable-depth – maximum frames per throwable
include-common-frames – true/false
include-hashes – true/false
<code>logging:
structured:
json:
stacktrace:
include-hashes: true
</code>7. ClientHttpConnector builder and properties
WebClient can now be globally configured via properties for connector type, timeouts, and redirect behavior:
<code>spring:
http:
reactiveclient:
settings:
connector: jetty
connect-timeout: 2s
read-timeout: 1s
redirects: dont-follow
</code>8. TaskDecorator for scheduled tasks
If a TaskDecorator bean exists, it is applied to the auto‑configured taskScheduler , ThreadPoolTaskSchedulerBuilder , and SimpleAsyncTaskSchedulerBuilder beans.
<code>@Configuration
@EnableScheduling
public class TaskConfig {
@Bean
TaskDecorator taskDecorator() {
return runnable -> () -> {
System.err.println("Task decorated");
runnable.run();
};
}
}
</code>9. Custom AsyncTaskExecutor bean
When an Executor bean is present, Spring Boot still auto‑configures an AsyncTaskExecutor . To force usage of a custom executor, set spring.task.execution.mode=force and define the bean:
<code>@Configuration
@EnableAsync
public class AsyncConfig {
@Bean
Executor executor() {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
5, 5, 60, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(100),
new ThreadFactory() {
private final AtomicInteger c = new AtomicInteger();
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "pack-" + c.incrementAndGet());
}
});
return executor;
}
}
</code> <code>spring:
task:
execution:
mode: force
</code>10. Automatic bootstrapExecutor configuration
If no bootstrapExecutor bean exists, Spring Boot creates one automatically, provided an applicationTaskExecutor bean is present. Example:
<code>@Bean(bootstrap = Bootstrap.BACKGROUND)
Person person() {
System.err.printf("%s - person bean create%n", Thread.currentThread().getName());
return new Person();
}
</code>11. Actuator "heapdump" endpoint security
The default access for the heapdump actuator endpoint is now NONE . To expose it, configure both exposure and access:
<code>management:
endpoints:
web:
exposure:
include: heapdump
endpoint:
heapdump:
access: unrestricted
</code>These changes help prevent accidental leakage of sensitive heap data while still allowing intentional use.
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.
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.