Reputation: 868
Is there a way to run a controller for initializing some data before Spring Boot starts the Tomcat?
My current code looks like that:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
AbstractApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
Controller controller = (Controller) context.getBean("controller");
controller.start();
context.close();
SpringApplication.run(Application.class, args);
}
}
@Controller
@Component("controller")
public class Controller {
@Autowired
private Runner runner;
public void start() {
runner.test();
}
}
@Configuration
@PropertySource("classpath:config.properties")
@Component("runner")
public class Runner {
@Value("${name}")
private String name;
public void test() {
System.out.println("hello " + name)
}
public String getName() {
return name;
}
}
@Controller
public class HelloController {
@Autowired
private Runner runner;
@RequestMapping("/hello")
public CalenderCollection data(@PathVariable("name")String name, Model model) {
model.addAttribute("name", runner.getName());
return "hello";
}
}
@Configuration
@ComponentScan(basePackages = "com.test")
public class AppConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
This prints the correct name into the console. But when I visit the url then runner
is null. Then I thought about to change the Application and Controller class to this:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@Controller
@Component("controller")
public class Controller {
@Autowired
private Runner runner;
public Controller() {
runner.test();
}
}
But now I have the problem that runner
is null right in the beginning. What would be a right way to collect some data in the beginning and then continue with the process?
Upvotes: 2
Views: 3807
Reputation: 562
If this is something that affects only that class you can use
@PostConstruct
on a method of your controller class.
If this is something that is linked to the whole application, you should consider
creating an application listener on ApplicationReadyEvent
Upvotes: 2
Reputation: 4691
If you want to initialize some values you can do something like this :
@SpringBootApplication
public class Application implements CommandLineRunner {
@Override
public void run( String... args ) throws Exception {
//initialise your value here
}
}
Upvotes: 1
Reputation: 576
Usually you use ApplicationRunner
or CommandLineRunner
to run some code before application started.
From documentation
If you need to run some specific code once the SpringApplication has started, you can implement the ApplicationRunner or CommandLineRunner interfaces. Both interfaces work in the same way and offer a single run method which will be called just before SpringApplication.run(…) completes.
The CommandLineRunner interfaces provides access to application arguments as a simple string array, whereas the ApplicationRunner uses the ApplicationArguments interface discussed above.
import org.springframework.boot.*
import org.springframework.stereotype.*
@Component
public class MyBean implements CommandLineRunner {
public void run(String... args) {
// Do something...
}
}
Upvotes: 3
Reputation: 64099
If you are just trying to run some code when the application has started, then there is no need to use Controller. Spring provides various application lifecycle hooks for such use cases.
The code would most likely look like this
@Component
public class MyListener
implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
private Runner runner;
public void onApplicationEvent(ContextRefreshedEvent event) {
runner.test();
}
}
Check out this blog post and this part of the documentation for more information
Upvotes: 3