在任何其他配置之前,如何首先加载Spring-MVC @PropertySources

时间:2015-10-13 15:12:20

标签: spring-mvc configuration autowired

我有一个使用java配置的spring-mvc应用程序,而不是xml。 @Configuration注释通过几个文件散布。特别是,在实现WebMvcConfigurerAdapter的类中的一个文件中有一个@PropertySources注释。有两个类包含@Autowired Environment变量。其中一个类本身就是一个@Configuration类,我希望它在运行时可以访问完全加载的环境。

这不会发生。执行此代码时,Environment仍为null。我尝试重新排序@ComponentScan包,尝试移动@PropertySources注释,没有任何东西帮助我及时加载属性源。

我希望在任何其他配置之前首先发生这种情况。

我该怎样做才能做到这一点?

更新:在尝试了许多事情之后,包括Order注释,我发现问题似乎并不是因为@PropertySources被加载太晚了,因为我从org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer派生的类是太快装了。我的代码中没有任何东西甚至引用了这个类,但是Spring以某种方式决定首先必须初始化它,尤其是其他类。 @Order没有任何麻烦似乎改变了这一点。尽管有javadocs,但这表明我想要的行为是默认行为:

  

注意事项

     

AbstractDispatcherServletInitializer的子类将注册它们   在任何其他过滤器之前过滤这意味着您通常会这样做   想要确保AbstractDispatcherServletInitializer的子类   先调用。这可以通过确保订单或订购来完成   AbstractDispatcherServletInitializer比子类更快   AbstractSecurityWebApplicationInitializer。

2 个答案:

答案 0 :(得分:0)

不是说我是Java配置的专家,但可能是:

  

Spring 4在其@PropertySource注释中使用了此功能。至   提醒你,@PropertySource注释提供了一种添加机制   Spring的环境和它的名称/值属性对的来源   与@Configuration类一起使用。

取自:http://blog.codeleak.pl/2013/11/how-to-propertysource-annotations-in.html

  1. 您使用的是@PropertySource还是@PropertySources?
  2. 您是否尝试过'bean'初始化的'order'属性?

答案 1 :(得分:0)

您可以使用ContextInitializer来捕捉Boot准备其环境的时刻,并根据需要以编程方式“注入”您的属性源。 如果您有ConfigurableApplicationContext,则它将提供ConfigurableEnvironment,其中包含propertySources作为列表。如果您希望PropertySource在其他所有规则之上进行统治,而不是将其添加为第一。如果要将其放置在特殊位置,则可以在其“名称”之前添加

public class ConfigInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext ctx) {

    // rule over all the others: 
    ctx.getEnvironment().getPropertySources().
      addFirst(new ResourcePropertySource("file:/etc/conf/your_custom.properties"));

    // rule over application.properties but not argument or systemproperties etc
    ctx.getEnvironment().getPropertySources().
      addBefore("applicationConfig: [classpath:/application.properties]",
      new ResourcePropertySource("classpath:your_custom.properties"));

    // names can be discovered by placing a breakpoint somewhere here and watch 
    // ctx.getEnvironment().getPropertySources().propertySourceList members,
    // each has a name ...
    }
}

您可以通过以下方式发挥课堂的作用:

  • application.properties 中注册它:
    context.initializer.classes=a.b.c.ConfigInitializer
  • 或从应用程序开始:
    new SpringApplicationBuilder(YourApplication.class).
      initializers(new ConfigInitializer()).
      run(args);

通过这种方式,这是注入更多自定义属性的正确方法,例如来自数据库或其他主机的属性等等。