繁体   English   中英

没有请求的Spring Boot运行控制器

[英]Spring Boot run controller without request

有没有办法在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();
    }
}

这会将正确的名称打印到控制台中。 但是,当我访问url时, runner为null。 然后我考虑将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在一开始就为空。 在开始时收集一些数据然后继续该过程的正确方法是什么?

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

该代码很可能看起来像这样

@Component
public class MyListener 
        implements ApplicationListener<ContextRefreshedEvent> {

    @Autowired
    private Runner runner;

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

查看博客文章和文档的部分以获取更多信息

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

文档

如果SpringApplication启动后需要运行一些特定的代码,则可以实现ApplicationRunner或CommandLineRunner接口。 两个接口都以相同的方式工作,并提供一个单一的运行方法,该方法将在SpringApplication.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...
    }

}

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

@SpringBootApplication
public class Application implements CommandLineRunner {

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

如果这仅影响该类,则可以使用

@PostConstruct 

在您的控制器类的方法上。

如果这是链接到整个应用程序的内容,则应考虑在ApplicationReadyEvent上创建应用程序侦听器

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM