在我的Spring Boot应用程序中,我希望从@Value
方法访问我的类的成员变量(注释为main
,因为它是从属性文件中读取的属性)。由于静态main
方法无法读取非静态变量,因此我也将变量设为静态。
修改:我还需要根据此属性的值关闭ApplicationContext
返回的SpringApplication.run()
。我正在更新下面的代码以反映这一点。
我的代码看起来像这样:
@SpringBootApplication
public class Application {
// the variable I want to access in main
@Value("{property:}")
protected static String property;
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(AccountApiApplication.class, args);
if(new String("true").equals(property)) {
SpringApplication.exit(context)
}
}
修改:这里有两个问题:
property
不能是静态的(与上面的代码相反),或@Value
注释不能使用它。我无法使其成为非静态的,因为从main
无法访问它。
我被建议了几种不同的方法,我正在考虑关闭ApplicationContext,但它们可能不适合我:
- 使用@PostConstruct
带注释的init()
方法。麻烦的是,我不认为main()
返回的ConfigurableApplicationContext可以在这里访问。
- 使用CommandLineRuuner.run()
或ApplicationRunner.run()
。这些run()
方法似乎在我的Spring Batch作业开始之前执行,所以我不能使用它们来关闭ApplicationContext,或者甚至在我的作业执行之前应用程序就会关闭。
答案 0 :(得分:3)
您不能在静态字段(以及Spring组件)中注入值表达式。
因此@Value
字段应该是一个实例字段。为了能够访问它,您应该从您猜到的实例方法中执行此操作。
请注意,为了能够操作正在运行的ApplicationContext
实例,必须完全初始化Spring上下文。
要实现它,您应该仅在返回ApplicationContext
后调用操作SpringApplication.run()
的实例方法。
您应该首先使用BeanFactory.getBean()
方法检索与当前应用程序类对应的bean
然后,您可以调用需要ApplicationContext
的实例方法:
@SpringBootApplication
public class Application {
@Value("{property:}")
protected String property;
public static void main(String[] args) throws IOException {
ConfigurableApplicationContext context = SpringApplication.run(AccountApiApplication.class, args);
AccountApiApplication app = context.getBean(AccountApiApplication.class);
app.doMyTask(context);
}
public void doMyTask(ConfigurableApplicationContext context) {
if(property) {
context.close();
}
else {
// do something else
}
}
}
答案 1 :(得分:1)
注入静态变量并不适用于Spring。会有解决方法,但在你的情况下,他们也不会工作。如果要在应用程序启动后执行代码,请创建一个实现ApplicationRunner
接口(https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-spring-application.html#boot-features-command-line-runner)的新类。这完全是您的用例。