Unlock Spring Boot’s Hidden Power: 9 Built‑In Features Every Backend Dev Needs

This article walks through nine essential Spring Boot built‑in capabilities—including request logging, content caching, filter execution control, AOP utilities, starter auto‑configuration, flexible property binding, async/scheduled tasks, Actuator monitoring, and SpEL expressions—showing how they boost backend development productivity without extra dependencies.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Unlock Spring Boot’s Hidden Power: 9 Built‑In Features Every Backend Dev Needs

Spring Boot provides many built‑in utilities that act like ready‑made tools, allowing developers to boost productivity without adding extra dependencies.

1. Full‑chain request logging: CommonsRequestLoggingFilter

During debugging and monitoring, recording complete request information is crucial. Spring Boot’s CommonsRequestLoggingFilter enables detailed logging of query strings, payloads, headers, and client IP.

Core capabilities

Multi‑dimensional data collection: Supports includeQueryString, includePayload, includeHeaders, and client IP.

Flexible log format: Use setAfterMessagePrefix to customize log prefixes for easier classification.

Quick enable

Configure the filter:

@Configuration
public class RequestLoggingConfig {
    @Bean
    public CommonsRequestLoggingFilter logFilter() {
        CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter();
        filter.setIncludeQueryString(true);
        filter.setIncludePayload(true);
        filter.setMaxPayloadLength(1024);
        filter.setAfterMessagePrefix("[REQUEST DATA] ");
        return filter;
    }
}

Set log level in application.properties:

logging.level.org.springframework.web.filter.CommonsRequestLoggingFilter=DEBUG

Log example:

[REQUEST DATA] POST /api/user, client=192.168.1.1, headers=[Content-Type:application/json], payload={"username":"test","email":"[email protected]"}

2. Flexible request/response handling: ContentCaching wrappers

The native HttpServletRequest and

HttpServletResponse> streams can be read only once, limiting scenarios such as logging plus business logic. Spring’s <code>ContentCachingRequestWrapper

and ContentCachingResponseWrapper cache the streams, enabling multiple reads.

Core wrappers

Request wrapper ( ContentCachingRequestWrapper ) : Caches request body bytes, allowing downstream controllers to read the body after logging.

Response wrapper ( ContentCachingResponseWrapper ) : Caches response output, permitting modifications (e.g., adding signatures) before the response is committed.

Practical filter implementation

// Request wrapper filter
@Component
public class RequestLogFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(request);
        byte[] requestBody = wrappedRequest.getContentAsByteArray();
        log.debug("Received request body: {}", new String(requestBody));
        chain.doFilter(wrappedRequest, response);
    }
}

// Response wrapper filter
@Component
public class ResponseSignFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        ContentCachingResponseWrapper wrappedResponse = new ContentCachingResponseWrapper(response);
        chain.doFilter(request, wrappedResponse);
        byte[] responseBody = wrappedResponse.getContentAsByteArray();
        String signature = generateSignature(responseBody);
        wrappedResponse.setHeader("X-Response-Signature", signature);
        wrappedResponse.copyBodyToResponse();
    }
    private String generateSignature(byte[] body) {
        return Base64.getEncoder().encodeToString(body);
    }
}

3. Single‑execution guarantee: OncePerRequestFilter base class

In forward or include scenarios, ordinary filters may execute multiple times, causing duplicated logic. Extending OncePerRequestFilter ensures the filter runs only once per request lifecycle.

Core advantages

Avoid duplicate processing: Override doFilterInternal and rely on internal shouldNotFilter checks.

Simplify development: Only need to implement doFilterInternal without manual request‑identification logic.

Applicable scenarios

Logging – prevent repeated logs on forwards.

Security checks – ensure JWT validation runs once.

Performance monitoring – record accurate processing time.

4. AOP development aid: three utility classes

1. AopContext – proxy accessor

When a method call within the same class bypasses the proxy (e.g., @Transactional), AopContext.currentProxy() retrieves the current proxy to trigger aspect logic.

public class ServiceImpl {
    @Transactional
    public void innerMethod() { /* transaction logic */ }
    public void outerMethod() {
        ((ServiceImpl) AopContext.currentProxy()).innerMethod();
    }
}

2. AopUtils – proxy type checker

if (AopUtils.isJdkDynamicProxy(proxyObject)) {
    // handle JDK dynamic proxy
} else if (AopUtils.isCglibProxy(proxyObject)) {
    // handle CGLIB proxy
}

3. ReflectionUtils – reflection simplifier

// Access private field
Field field = ReflectionUtils.findField(MyClass.class, "privateField");
ReflectionUtils.makeAccessible(field);
Object value = ReflectionUtils.getField(field, instance);
// Invoke private method
Method method = ReflectionUtils.findMethod(MyClass.class, "privateMethod", String.class);
ReflectionUtils.invokeMethod(method, instance, "arg");

5. Dependency management magic: Starter auto‑configuration

Spring Boot’s starter system provides one‑stop dependency bundles. Adding spring-boot-starter-web automatically brings Tomcat, Spring MVC, Jackson, etc.

Version alignment is handled by the spring-boot-dependencies parent POM, preventing conflicts.

Common starter example

Starter examples
Starter examples

Custom starter

Create src/main/resources/META-INF/spring.factories:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.custom.MyCustomAutoConfiguration

Implement auto‑configuration with conditional annotations such as @ConditionalOnClass and @ConditionalOnMissingBean.

6. Configuration simplification: auto‑configuration & placeholders

Spring Boot scans for @EnableAutoConfiguration and auto‑creates beans (e.g., DataSource when spring-boot-starter-jdbc is present). It also binds external properties to POJOs via @ConfigurationProperties, eliminating hard‑coded values.

@Configuration
@ConfigurationProperties(prefix = "app")
public class AppConfig {
    private String env;
    private DatabaseConfig database;
    // getters & setters
    public static class DatabaseConfig {
        private String url;
        private String username;
        // ...
    }
}

YAML example:

app:
  env: production
  database:
    url: jdbc:mysql://localhost:3306/test
    username: root

Placeholders ${} and @Value allow dynamic injection with defaults.

@Value("${app.env:dev}")
private String environment;

7. Async & scheduled tasks: annotation‑driven concurrency

Async method call

@Service
public class AsyncService {
    @Async("customExecutor")
    public CompletableFuture<Void> processAsyncTask(String taskId) {
        // time‑consuming logic
        return CompletableFuture.completedFuture(null);
    }
}

@Configuration
@EnableAsync
public class AsyncConfig {
    @Bean("customExecutor")
    public Executor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(20);
        executor.initialize();
        return executor;
    }
}

Scheduled tasks

@Service
public class ScheduledService {
    // Daily at 1 AM
    @Scheduled(cron = "0 0 1 * * ?")
    public void dailyCleanup() { /* cleanup logic */ }

    // Every 5 seconds after previous execution
    @Scheduled(fixedDelay = 5000)
    public void periodicSync() { /* sync logic */ }
}

8. Monitoring & diagnostics: Actuator

Spring Boot Actuator exposes production‑ready endpoints (health, metrics, env, etc.) for observability and dynamic configuration.

Actuator endpoints
Actuator endpoints

Custom metrics

@Autowired
private MeterRegistry meterRegistry;

public void recordOrder(String status) {
    meterRegistry.counter("order.processed", "status", status).increment();
}

9. Power of expressions: SpEL

Spring Expression Language enables dynamic evaluation in configuration, annotations, and code.

Typical use cases

<!-- Bean definition with SpEL -->
<bean id="userService" class="com.example.UserService">
    <property name="defaultTimeout" value="#{T(java.lang.Integer).parseInt('1000')}"/>
</bean>
@ConditionalOnExpression("${app.env} == 'prod' && @environment.getProperty('server.port') == 8080")
public class ProdConfig { }
@PreAuthorize("hasRole('ADMIN') or @accessService.hasPermission(#userId)")
public void deleteUser(Long userId) { /* security logic */ }

Conclusion

Spring Boot’s built‑in features cover the entire development‑to‑operations lifecycle. By thoughtfully combining these tools, developers can eliminate boilerplate code, improve maintainability, and build robust backend services.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

aopBackend DevelopmentConfigurationSpring BootAsyncActuator
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

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.