@Value注释没有正确设置 [英] @Value annotation not being properly set
问题描述
下面是我的应用程序:
公共静态无效的主要(字串[] args){
AnnotationConfigApplicationContext CTX =新AnnotationConfigApplicationContext(Config.class); //运行进口商
最后ImportNewOrders进口商=(ImportNewOrders)ApplicationContextProvider.getApplicationContext()的getBean(importNewOrders);
importer.run();
//importer.runInBackground();
}
下面是我的配置:
@Configuration
@ComponentScan(basePackages = {
com.production
})
@PropertySource(值= {
类路径:/application.properties
类路径:/环境 - $ {} MY_ENVIRONMENT的.properties
})
@EnableJpaRepositories(com.fettergroup.production.repositories)
@EnableTransactionManagement
公共类配置{ ....跳过的东西都是不相关 @豆
公共ImportNewOrders importNewOrders(){
返回新ImportNewOrders();
}
下面是我的课...
@Component
公共类ImportNewOrders实现任务{ 私人最终静态记录器记录= Logger.getLogger(ImportNewOrders.class.getName()); @Autowired
私人OrderService orderService; @Autowired
私人ImportOrderRequest importOrderRequest; @Value($ {api.user})
私人字符串apiUser; @Value($ {api.password})
私人字符串apiPassword; @Value($ {api.orders.pingFrequency})
私人字符串pingFrequency;
和最后的 application.properties
:
#-------------------应用程序设置---------------- ---#Base URL的API应用
api.baseUrl = HTTP://本地主机:9998#Unique令牌用于该供应商认证
api.vendor.token = ASDF#API凭据
api.user = myuser的
api.password =输入mypassword常常#如何检查是否有新订单;频率以秒为单位
api.orders.pingFrequency = 60
这工作一两个小时前,现在它决定了它不喜欢这些值。我不知所措,为什么。一切看起来正确的给我。
更新
@Configuration
@ComponentScan(basePackages = {
com.production
})
@PropertySource(值= {
类路径:/application.properties
类路径:/环境 - $ {} MY_ENVIRONMENT的.properties
})
@EnableJpaRepositories(com.production.repositories)
@EnableTransactionManagement
公共类配置{
@Value($ {} db.url配置参数)
私人静态字符串PROPERTY_DATABASE_URL; @豆
公共数据源数据源(){
MysqlDataSource数据源=新MysqlDataSource(); dataSource.setUrl(PROPERTY_DATABASE_URL); //为null
/*dataSource.setUser(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_USER));
dataSource.setPassword(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD)); * / 返回数据源;
} @豆
公共PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(){
返回新PropertySourcesPlaceholderConfigurer();
}
}
您的属性文件被发现了你的 @Configuration
,并使用它的类中的数据库属性因为 @PropertySource
。但 @Value
字段和 $ {}
评估需要更多的。
从<一个href=\"http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/context/annotation/PropertySource.html\"相对=nofollow> Javadoc文档 @PropertySource
为了解决$ {...}中定义的占位符或
使用来自PropertySource,必须性质@Value注解
注册PropertySourcesPlaceholderConfigurer。出现这种情况
时自动使用XML,但是
必须在使用时使用静态@Bean方法来明确地注册
@Configuration类。请参阅与外部化价值的工作
@Configuration的Javadoc的部分和记
BeanFactoryPostProcessor时,返回的@Bean的Javadoc @Bean方法
细节和例子。
块引用>所以声明
@Bean
公共静态PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(){
PropertySourcesPlaceholderConfigurer P =新PropertySourcesPlaceholderConfigurer();
p.setLocation(新使用ClassPathResource(你的属性路径));
//其他属性
回磷;
}在你的配置类,或ACH已经在评论中提到贴切如果你使用
@PropertySource
您可以省略的setLocation
干脆:@Configuration
@PropertySource(值=类路径:your_file.properties)
公共类MyConfiguration { @豆
公共静态PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(){
PropertySourcesPlaceholderConfigurer P =新PropertySourcesPlaceholderConfigurer();
回磷;
}
}当你有你不必环境的
PropertySourcesPlaceholderConfigurer
在大多数情况下,但是,应用程序级豆应该不需要>
直接与环境相互作用,而是可能必须有
$ {...}属性值换成一个属性占位符配置器
如PropertySourcesPlaceholderConfigurer,它本身是
EnvironmentAware和春天3.1默认情况下,当注册
使用&LT;背景:物业占位符/>.
块引用>Here's my app:
public static void main( String[] args ) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class); //run the importer final ImportNewOrders importer = (ImportNewOrders) ApplicationContextProvider.getApplicationContext().getBean("importNewOrders"); importer.run(); //importer.runInBackground(); }
Here's my config:
@Configuration @ComponentScan(basePackages = { "com.production" }) @PropertySource(value = { "classpath:/application.properties", "classpath:/environment-${MY_ENVIRONMENT}.properties" }) @EnableJpaRepositories("com.fettergroup.production.repositories") @EnableTransactionManagement public class Config { .... skipping things that aren't relevant @Bean public ImportNewOrders importNewOrders() { return new ImportNewOrders(); }
Here's my class...
@Component public class ImportNewOrders implements Task { private final static Logger logger = Logger.getLogger(ImportNewOrders.class.getName()); @Autowired private OrderService orderService; @Autowired private ImportOrderRequest importOrderRequest; @Value("${api.user}") private String apiUser; @Value("${api.password}") private String apiPassword; @Value("${api.orders.pingFrequency}") private String pingFrequency;
And finally the
application.properties
:# ------------------- Application settings ------------------- #Base URL to the API application api.baseUrl=http://localhost:9998 #Unique token used to authenticate this vendor api.vendor.token=asdf #API credentials api.user=myuser api.password=mypassword #How often to check for new orders; frequency is in seconds api.orders.pingFrequency=60
This worked an hour or two ago, now it's decided it doesn't like these values. I'm at a loss as to why. Everything looks correct to me.
Update
@Configuration @ComponentScan(basePackages = { "com.production" }) @PropertySource(value = { "classpath:/application.properties", "classpath:/environment-${MY_ENVIRONMENT}.properties" }) @EnableJpaRepositories("com.production.repositories") @EnableTransactionManagement public class Config { @Value("${db.url}") private static String PROPERTY_DATABASE_URL; @Bean public DataSource dataSource() { MysqlDataSource dataSource = new MysqlDataSource(); dataSource.setUrl(PROPERTY_DATABASE_URL); //is null /*dataSource.setUser(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_USER)); dataSource.setPassword(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));*/ return dataSource; } @Bean public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer () { return new PropertySourcesPlaceholderConfigurer(); } }
解决方案Your properties file is found by your
@Configuration
and is using it for your database properties within that class because of@PropertySource
. But@Value
fields and${}
evaluation need more than that.From Javadoc for
@PropertySource
In order to resolve ${...} placeholders in definitions or @Value annotations using properties from a PropertySource, one must register a PropertySourcesPlaceholderConfigurer. This happens automatically when using in XML, but must be explicitly registered using a static @Bean method when using @Configuration classes. See the "Working with externalized values" section of @Configuration Javadoc and "a note on BeanFactoryPostProcessor-returning @Bean methods" of @Bean Javadoc for details and examples.
So declare a
@Bean public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { PropertySourcesPlaceholderConfigurer p = new PropertySourcesPlaceholderConfigurer(); p.setLocation(new ClassPathResource("your properties path")); // other properties return p; }
in your config class, or as ach has aptly mentioned in the comments if you use
@PropertySource
your can omitsetLocation
altogether:@Configuration @PropertySource(value="classpath:your_file.properties") public class MyConfiguration{ @Bean public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { PropertySourcesPlaceholderConfigurer p = new PropertySourcesPlaceholderConfigurer(); return p; } }
You shouldn't need the environment when you have the
PropertySourcesPlaceholderConfigurer
In most cases, however, application-level beans should not need to> interact with the Environment directly but instead may have to have ${...} property values replaced by a property placeholder configurer such as PropertySourcesPlaceholderConfigurer, which itself is EnvironmentAware and as of Spring 3.1 is registered by default when using < context:property-placeholder/>.
这篇关于@Value注释没有正确设置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!