Spring Boot运行控制器没有请求

时间:2017-10-05 13:05:18

标签: java spring-boot

有没有办法在Spring Boot启动Tomcat之前运行控制器来初始化某些数据?

我当前的代码如下:

@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();
    }
}

这会将正确的名称输出到控制台中。但是当我访问网址时,runner为空。然后我想把Application和Controller类更改为:

@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();
    }
}

但是现在我的问题是runner在开头就是空的。什么是在开始时收集一些数据然后继续该过程的正确方法?

4 个答案:

答案 0 :(得分:3)

如果您只是在应用程序启动时尝试运行某些代码,则无需使用Controller。 Spring为这种用例提供​​了各种应用程序生命周期钩子。

代码很可能看起来像这样

@Component
public class MyListener 
        implements ApplicationListener<ContextRefreshedEvent> {

    @Autowired
    private Runner runner;

    public void onApplicationEvent(ContextRefreshedEvent event) {
        runner.test();
    }
}

查看this博文和this部分文档以获取更多信息

答案 1 :(得分:2)

通常在应用程序启动之前使用ApplicationRunnerCommandLineRunner运行一些代码。

来自documentation

  

如果您需要在SpringApplication运行后运行某些特定代码   启动后,您可以实现ApplicationRunner或CommandLineRunner   接口。两个接口以相同的方式工作并提供单个接口   在SpringApplication.run(...)之前调用的run方法   完成。

     

CommandLineRunner接口提供对应用程序的访问   参数作为一个简单的字符串数组,而ApplicationRunner使用   上面讨论的ApplicationArguments接口。

import org.springframework.boot.*
import org.springframework.stereotype.*

@Component
public class MyBean implements CommandLineRunner {

    public void run(String... args) {
        // Do something...
    }

}

答案 2 :(得分:1)

如果要初始化某些值,可以执行以下操作:

@SpringBootApplication
public class Application implements CommandLineRunner {

  @Override
  public void run( String... args ) throws Exception {
    //initialise your value here
  }
}

答案 3 :(得分:1)

如果这只是影响那个类的东西,你可以使用

@PostConstruct 

关于控制器类的方法。

如果这是与整个应用程序相关联的内容,您应该考虑 在ApplicationReadyEvent

上创建应用程序侦听器