我有一个使用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的子类将在任何其他Filter之前注册其过滤器。这意味着您通常希望首先调用AbstractDispatcherServletInitializer的子类。这可以通过确保AbstractDispatcherServletInitializer的Order或Ordered比AbstractSecurityWebApplicationInitializer的子类更快来完成。
不是说我是Java配置的专家,但可能:
Spring 4在其@PropertySource注释中使用了此功能。为了提醒您,@ PropertyTource注释提供了一种向Spring的环境添加名称/值属性对的机制,它与@Configuration类一起使用。
取自:http://blog.codeleak.pl/2013/11/how-to-propertysource-annotations-in.html
您可以使用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 ...
}
}
你可以通过以下方式发挥这个课程:
context.initializer.classes=a.b.c.ConfigInitializer
new SpringApplicationBuilder(YourApplication.class).
initializers(new ConfigInitializer()).
run(args);
顺便说一下,这是一种注入更多自定义属性的正确方法,例如来自数据库或不同主机的属性等...