I need to set some system properties programmatically and I figured that the best way would be doing it in the event listener once ApplicationEnvironmentPreparedEvent
was intercepted.
But the problem is that I am not able to catch that event in my listener.
@Component
public class AppListener {
@EventListener
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ApplicationEnvironmentPreparedEvent) {
System.setProperty("java.util.concurrent.ForkJoinPool.common.threadFactory", MyThreadFactory.class.getName());
}
}
}
What am I doing wrong and why I cannot catch that event?
In the index. html file we have a link that invokes a response from the web application. The file is located in the src/main/resources/static directory, which is a default directory where Spring looks for static content.
This is a very basic Web Application using Spring Boot that serves a “Hello World” static HTML web page. This will start the embedded Tomcat server at port 8080. The web server is available out of the box with Spring Boot.
Spring Boot Starters are dependency descriptors that can be added under the <dependencies> section in pom. xml. There are around 50+ Spring Boot Starters for different Spring and related technologies. These starters give all the dependencies under a single name.
The fastest and easiest way to customize Spring Boot is by overriding the values of the default properties. For the server port, the property we want to change is server. port. By default, the embedded server starts on port 8080.
From the Spring Boot documentation:
Some events are actually triggered before the ApplicationContext is created, so you cannot register a listener on those as a @Bean. You can register them with the SpringApplication.addListeners(…) method or the SpringApplicationBuilder.listeners(…) method.
And from the Spring documentation (this for version 5.1.7):
Processing of @EventListener annotations is performed via the internal EventListenerMethodProcessor bean which gets registered automatically when using Java config or manually via the or element when using XML config.
So ApplicationEnvironmentPreparedEvent (and all of the Spring Boot application events) occur before context and bean creation, and @EventListener is controlled by a bean, so the @EventListener annotation cannot be picked up at this point. You will have to specifically create a listener class and add it explicitly to capture this event (or any event that occurs before bean creation).
Your class:
public class AppListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent>
{
@Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event)
{
System.setProperty("java.util.concurrent.ForkJoinPool.common.threadFactory",
MyThreadFactory.class.getName());
}
}
...and the relevant SpringApplicationBuilder code:
ConfigurableApplicationContext context = new SpringApplicationBuilder(Launcher.class)
.listeners(new AppListener()).run();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With