In my Spring Boot application, I want to access my class's member variable (annotated as @Value
, since it's a property being read from a properties file) from the main
method. Since the static main
method cannot read non-static variables, I made the variable static as well.
Edit : I also need to close the ApplicationContext
returned by SpringApplication.run()
based on the value of this property. I am updating the code below to reflect this.
My code looks something like this:
@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)
}
}
Edit : There are two issues here:
property
can't be static (as opposed to the code above), or the @Value
annotation won't work with it. And I can't make it non-static, since then it won't be accessible from main
.
I have been suggested a couple different approaches, which I'm considering for shutting down the ApplicationContext, but they might not work for me:
- Using a @PostConstruct
annotated init()
method. Trouble is, I don't think the ConfigurableApplicationContext returned by main()
can be accessed here.
- Using CommandLineRuuner.run()
or ApplicationRunner.run()
. These run()
methods seem to be executing before my Spring Batch job even starts, so I can't use these to shut down the ApplicationContext, or the application would be shut down even before my jobs execute.
You cannot inject value expression in a static field (as well as for Spring components).
So the @Value
field should be an instance field. In order to be able to access to it, you should do that from an instance method as you guessed.
Note that to be able to manipulate the running ApplicationContext
instance, the Spring context has to be completely initialized.
To achieve it, you should invoke the instance method that manipulates the ApplicationContext
only after SpringApplication.run()
is returned.
You should first retrieve the bean corresponding to the current application class by using the BeanFactory.getBean()
method.
Then, you could invoke the instance method that needs the 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
}
}
}
Injection into static variables doesn't work with Spring. There would be workarounds, but in your case they also wouldn't work. If you want to execute code after the startup of your application, create a new class which implements the ApplicationRunner
interface ( https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-spring-application.html#boot-features-command-line-runner ). That exists for exactly your usecase.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.