@Value注释没有正确设置 [英] @Value annotation not being properly set

查看:808
本文介绍了@Value注释没有正确设置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是我的应用程序:

 公共静态无效的主要(字串[] 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 omit setLocation 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆