我有一个使用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。
答案 0 :(得分:0)
不是说我是Java配置的专家,但可能是:
Spring 4在其@PropertySource注释中使用了此功能。至 提醒你,@PropertySource注释提供了一种添加机制 Spring的环境和它的名称/值属性对的来源 与@Configuration类一起使用。
取自:http://blog.codeleak.pl/2013/11/how-to-propertysource-annotations-in.html
答案 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 ...
}
}
您可以通过以下方式发挥课堂的作用:
context.initializer.classes=a.b.c.ConfigInitializer
new SpringApplicationBuilder(YourApplication.class).
initializers(new ConfigInitializer()).
run(args);
通过这种方式,这是注入更多自定义属性的正确方法,例如来自数据库或其他主机的属性等等。