20 Февраля 2016

Использование CommandLineRunner в Spring.io

Для запуска одного из помпонентов, к примеру socket-сервера, в Spring.io обычно создают реализацию интерфейса CommandLineRunner. Часто возникает проблема, когда при сборке и упаковке проекта, сервер также начинает запускаться.


Допустим, нам требуется собственный websocket-сервер. Сам проект собирается с использованием spring-boot и стартует стандартным способом.

@SpringBootApplication
public class SomeSpringApplication {
// ...
    public static void main(String[] args) {
        SpringApplication.run(SomeSpringApplication.class, args);
    }
}

Мы реализовали CommandLineRunner чтобы сервер успешно запускался.

@Component
public class SrvRunner implements CommandLineRunner {

    private final SocketIOServer server;

    @Autowired
    public SrvRunner(SocketIOServer server) {
        this.server = server;
    }

    @Override
    public void run(String... args) throws Exception {
        server.start();
        Thread.sleep(Integer.MAX_VALUE);
        server.stop();
    }

}

При вызове mvn package, если у вас есть хотя бы модульные тесты, сервер начнет запускаться. Дело в том, что перед файзой package запускается фаза test. Если вы в тестовой конфигурации забыли исключить компонент, реализующий CommandLineRunner, Spring его запустит.

Все компоненты, реализующие CommandLineRunner можно исключить из тестовой конфигурации следующим образом.

@Configuration
@ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = CommandLineRunner.class))
@EnableAutoConfiguration
public class TestApplicationConfiguration {
}