从main方法访问带注释的类成员

时间:2018-02-04 19:44:46

标签: java spring spring-boot static

在我的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)
    }
}

修改:这里有两个问题:

  1. property不能是静态的(与上面的代码相反),或@Value注释不能使用它。我无法使其成为非静态的,因为从main无法访问它。

  2. 我被建议了几种不同的方法,我正在考虑关闭ApplicationContext,但它们可能不适合我:

    - 使用@PostConstruct带注释的init()方法。麻烦的是,我不认为main()返回的ConfigurableApplicationContext可以在这里访问。

    - 使用CommandLineRuuner.run()ApplicationRunner.run()。这些run()方法似乎在我的Spring Batch作业开始之前执行,所以我不能使用它们来关闭ApplicationContext,或者甚至在我的作业执行之前应用程序就会关闭。

    < / LI>

2 个答案:

答案 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)的新类。这完全是您的用例。