Log SpringBoot Controllers, Track Request Time, Dynamically Register Resources
This guide shows how to output all SpringBoot controller endpoints via logging configuration, measure complete request processing time by listening to ServletRequestHandledEvent, dynamically register and deregister static resources at runtime, and execute custom logic after the application context refreshes using ContextRefreshedEvent.
Environment: SpringBoot 3.2.5
1. Output All Controller Interface Information
Sometimes you want to print all controller endpoints when the application starts to get a clear overview and speed up troubleshooting.
Method 1
logging:
level:
web: traceResult:
This prints a lot of logs because it enables the entire web logging group, not just controller information.
Method 2
logging:
level:
'[_org.springframework.web.servlet.HandlerMapping.Mappings]': debugResult:
Only controller mappings are logged, while other logs keep their default level.
2. Measure Interface Call Duration
Without third‑party tools, a common approach is to record timestamps at the start and end of a handler:
@GetMapping("/time")
public Object time() throws Exception {
Instant startTime = Instant.now();
// TODO: business logic
System.err.printf("Interface duration: %d ms%n", Duration.between(startTime, Instant.now()).toMillis());
return "take time";
}For a more accurate measurement that includes the whole request lifecycle (handler mapping, interceptors, etc.), listen to ServletRequestHandledEvent:
@Component
public class TakeTimeCountListener implements ApplicationListener<ServletRequestHandledEvent> {
@Override
public void onApplicationEvent(ServletRequestHandledEvent event) {
Throwable failureCause = event.getFailureCause();
if (failureCause != null) {
System.err.printf("Error cause: %s%n", failureCause.getMessage());
}
System.err.printf("Client: %s, URL: %s, Method: %s, Duration: %d ms%n",
event.getClientAddress(),
event.getRequestUrl(),
event.getMethod(),
event.getProcessingTimeMillis());
}
}Listening to this event provides client address, request URL, HTTP method, and the exact processing time ( ProcessingTimeMillis).
3. Dynamically Register Static Resources
Static resources are usually configured in application.yml or via a WebMvcConfigurer implementation:
spring:
web:
resources:
static-locations: classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/You can add a file‑system directory:
spring:
web:
resources:
static-locations: ..., file:///d:/images/Or register them programmatically (requires a restart):
public class WebConfig implements WebMvcConfigurer {
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/images/**").addResourceLocations("file:///d:\\images\\");
}
}To make the registration effective at runtime without restarting, use a dynamic approach:
@RestController
public class RegController {
@Resource
private SimpleUrlHandlerMapping resourceHandlerMapping;
@Resource
private ApplicationContext context;
// Example: requestURI=/s/**, path=d:/images/
@GetMapping("")
public Object reg(String requestURI, String path) throws Throwable {
ResourceHttpRequestHandler handler = new ResourceHttpRequestHandler();
handler.setLocations(List.of(new FileSystemResource(path)));
handler.setApplicationContext(context);
handler.afterPropertiesSet();
resourceHandlerMapping.registerHandler(requestURI, handler);
return "register success";
}
}This method also allows you to deregister resources when needed.
4. Perform Actions After Container Startup
To run custom logic after the Spring context has fully refreshed, listen to ContextRefreshedEvent (triggered at the end of the refresh method):
@Component
public class ContextRefreshedListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
System.out.println("Context refresh completed...");
// TODO: custom logic here
}
}Implement your own processing inside the listener.
End of article.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
