Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to intercept ApplicationEnvironmentPreparedEvent in Spring Boot

Tags:

spring-boot

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?

like image 479
Ihor M. Avatar asked Feb 17 '18 01:02

Ihor M.


People also ask

Where should I put HTML file in spring boot?

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.

Can we use HTML with spring boot?

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.

What is spring boot starter dependency?

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.

Which of the following property you need to set to run spring boot application on the custom port?

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.


1 Answers

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();
like image 111
Jason Avatar answered Oct 21 '22 04:10

Jason