Issue
My SpringMVC application runs in Tomcat. I have a Spring-enabled @Component
with a method that needs to execute just once on Tomcat startup. It's a method to go into the Service/DAO layer and send an email.
Normally, the way to do a Tomcat Startup Java class call is in web.xml
as a Servlet with load-on-startup
(link).
<servlet>
<servlet-name>StartupEmail</servlet-name>
<servlet-class>com.app.StartupEmail</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
But that Servlet won't have access to my Spring layer with dependencies.
public class StartupEmail extends HttpServlet {
..
}
I can also have Cron-based Scheduled Jobs in SpringMVC, but they are time-based rather than on Tomcat Startup.
@Component
public class StatusScheduleJob {
@Autowired
private MyService myService;
@Scheduled(cron = "${statusjob.cron.expression}")
public void changeStatuses() {
myService.execute(); //...
}
}
statusjob.cron.expression=0 0 * * * *
So is there a good solution here?
Solution
If I understand the problem, there are several options depending on when exactly the startup code needs to be executed:
- Javax @PostConstruct annotation on a bean
- Implementing the InitializingBean interface
- Implementing the ApplicationListener interface for ContextRefreshedEvent
- Implementing the Spring CommandLineRunner interface
Here are a few references to learn about these options and more:
- https://www.baeldung.com/running-setup-logic-on-startup-in-spring
- https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/CommandLineRunner.html
- https://docs.oracle.com/javaee/7/api/javax/annotation/PostConstruct.html
Answered By - Thomas Portwood