이 방식은 앞서 설명한 방식처럼 특정 Bean 과 관련된 것이 아니라 Spring 컨텍스트의 초기화가 완료된 후, 즉 모든 Bean 의 초기화가 완료된 후에 실행되도록 하는 방식이다. ApplicationListener 인터페이스를 구현하는 Bean 을 정의하고 onApplicationEvent() 메소드를 Override 하여, 그 안에 원하는 로직을 작성하면 된다.
사실 생성자를 통해 의존성을 주입하는 경우에는 그냥 생성자에 원하는 로직을 넣으면 된다.
Field injection 의 경우 Bean 객체를 생성한 뒤에 나중에 의존성을 주입하기 때문에, 주입하기 이전에는 null 인 상태지만
Constructor Injection 의 경우에는 생성과 동시에 주입을 하기 때문에 문제가 없는것이다.
이것이 Field Injection 보다 Constructor Injection 이 더 권장되는 여러가지 이유 중 하나다.
생성자 주입이 더 권장되는 여러가지 이유에 대해서는 추후 다른 포스팅에서 다룰 것이다.
스프링 부트는 run() 이라는 콜백 메소드를 가진 CommandLineRunner 라는 인터페이스를 제공한다. run() 메소드는 Spring application context 의 초기화가 완료된(모든 Bean 이 초기화된) 후에 실행되므로
이 안에 원하는 로직을 작성하면 된다.
참고로 CommandLineRunner Bean 은 같은 애플리케이션 컨텍스트 내에 여러개를 정의할 수 있으며, Ordered 인터페이스, 혹은 @Order 어노테이션으로 실행 순서를 정해줄 수도 있다.
@Component 가 아니라 다음과 같이 @Configuration 과 @Bean 을 사용한 방식으로도 정의할 수 있다.
@SpringBootApplication publicclassApplication{ publicstaticvoidmain(String[] args){ SpringApplication.run(Application.class, args); } @Bean public CommandLineRunner run(UserRepository userRepository)throws Exception { return (String[] args) -> { User user1 = new User("John", "john@domain.com"); User user2 = new User("Julie", "julie@domain.com"); userRepository.save(user1); userRepository.save(user2); userRepository.findAll().forEach(user -> System.out.println(user)); }; } }
자바에서 하나의 메소드를 가지는 인터페이스의 경우에는 기존의 익명 클래스 방식대신 위와같이 람다식으로 작성할 수 있다.
Spring Boot 의 ApplicationRunner
스프링 부트는 앞서 언급한 CommandLineRunner 인터페이스 외에 ApplicationRunner 인터페이스도 제공한다.
동일하게 run() 이라는 콜백 메소드를 가지고 있어 이 안에 원하는 로직을 작성하면 된다.
참고로 run() 메소드로 들어오는 문자열들은 커맨드 라인으로 앱을 실행할 때 들어온 명령행 인자들이다.
CommandLineRunner 와 차이가 있다면, run() 메소드의 인자가 String 가 아니라 ApplicationArguments 인데 ApplicationArguments 인터페이스는 보통의 커맨드라인 인자 뿐만 아니라,
옵션 읽어 들일 수 있는 getOptionNames(), getOptionValues() 등의 메소드도 가지고 있다.
[main] INFO o.b.startup.AllStrategiesExampleBean - Constructor [main] INFO o.b.startup.AllStrategiesExampleBean - PostConstruct [main] INFO o.b.startup.AllStrategiesExampleBean - InitializingBean [main] INFO o.b.startup.AllStrategiesExampleBean - init-method