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

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

问题描述

这是我的应用程序:

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();
}

这是我的配置:

@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();
    }

这是我的课...

@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;

最后是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.

更新

@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();
    }
}

推荐答案

您的属性文件被您的 @Configuration 找到,并且由于 @ 而将该文件用于该类中的数据库属性属性源.但是 @Value 字段和 ${} 评估需要的不止这些.

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.

来自 Javadoc对于 @PropertySource

为了解决定义中的 ${...} 占位符或使用来自 PropertySource 的属性的 @Value 注释,必须注册一个 PropertySourcesPlaceholderConfigurer.有时候是这样的在 XML 中使用时自动,但使用时必须使用静态@Bean 方法显式注册@配置类.请参阅使用外化值"@Configuration Javadoc 的部分和关于BeanFactoryPostProcessor-returning @Bean 方法"的@Bean Javadoc for详细信息和示例.

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.

所以声明一个

@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
    PropertySourcesPlaceholderConfigurer p = new PropertySourcesPlaceholderConfigurer();
    p.setLocation(new ClassPathResource("your properties path"));
    // other properties
    return p;
}

在您的配置类中,或者如 ach 在评论中恰当地提到,如果您使用 @PropertySource 您可以完全省略 setLocation:

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;
    }
}

当您拥有 PropertySourcesPlaceholderConfigurer

然而,在大多数情况下,应用程序级 bean 不需要>直接与环境交互,但可能必须有${...} 属性值被属性占位符配置器替换比如 PropertySourcesPlaceholderConfigurer,它本身就是EnvironmentAware 和 Spring 3.1 是在默认情况下注册的使用 <上下文:属性占位符/>.

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天全站免登陆