Spring @Value注释没有取消引用值?

时间:2014-06-12 15:50:15

标签: java spring

我有一个从环境配置数据库特定属性的类。它看起来像

@Configuration
@Profile("default")
public class MySqlDatabaseConfig extends JpaCommonConfig {
    @Value("${database_url:jdbc:mysql://localhost:3306/pryme?createDatabaseIfNotExist=true }")
    private String databaseUrl;

    @Value("${database_user:root}")
    private String databaseUser;

    @Value("${database_password:\"\"}")
    private String databasePassword;

    @Value("${database_driverClassName:com.mysql.jdbc.Driver}")
    private String databaseDriverClass;


    private static final Logger LOGGER = LoggerFactory.getLogger(MySqlDatabaseConfig.class);

    @Override
    public DataSource dataSource() {
        final BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName(getDriverClassName());
        dataSource.setUrl(getUrl());
        dataSource.setUsername(getUser());
        if (!getPassword().trim().isEmpty()) {
            dataSource.setPassword(getPassword());
        }

        LOGGER.debug("DriverClass={}, URL={}, User={}", getDriverClassName(), getUrl(), getUser());
        return dataSource;
    }

    @Override
    public String getUrl() {
        return databaseUrl;
    }

    @Override
    public String getUser() {
        return databaseUser;
    }

    @Override
    public String getPassword() {
        return databasePassword;
    }

    @Override
    public String getDriverClassName() {
        return databaseDriverClass;
    }

    @Override
    protected Class<? extends Dialect> getDatabaseDialect() {
        return MySQL5InnoDBDialect.class;
    }
}

当我的测试运行时,我将失败视为

[INFO] [talledLocalContainer] Jun 12, 2014 8:47:45 AM org.apache.catalina.core.StandardContext listenerStart
[INFO] [talledLocalContainer]   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549) ~[spring-beans-4.0.3.RELEASE.jar:4.0.3.RELEASE]
[INFO] [talledLocalContainer]   ... 25 common frames omitted
[INFO] [talledLocalContainer] Caused by: org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class '${database_driverClassName:com.mysql.jdbc.Driver}'
[INFO] [talledLocalContainer] SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
[INFO] [talledLocalContainer]   at org.apache.commons.dbcp.BasicDataSource.createConnectionFactory(BasicDataSource.java:1429) ~[commons-dbcp-1.4.jar:1.4]
[INFO] [talledLocalContainer]   at org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1371) ~[commons-dbcp-1.4.jar:1.4]
[INFO] [talledLocalContainer] org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'liquibase' defined in class path resource [applicationContext.xml]: Invocation of init method failed; nested exception is liquibase.exception.DatabaseException: org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class '${database_driverClassName:com.mysql.jdbc.Driver}'
[INFO] [talledLocalContainer]   at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044) ~[commons-dbcp-1.4.jar:1.4]
[INFO] [talledLocalContainer]   at liquibase.integration.spring.SpringLiquibase.afterPropertiesSet(SpringLiquibase.java:296) ~[liquibase-core-3.1.1.jar:na]
[INFO] [talledLocalContainer]   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1553)
[INFO] [talledLocalContainer]   ... 27 common frames omitted
[INFO] [talledLocalContainer] Caused by: java.lang.ClassNotFoundException: ${database_driverClassName:com.mysql.jdbc.Driver}

好像@Value注释没有取消引用值

我想念的是什么?

3 个答案:

答案 0 :(得分:1)

您需要一个PropertySource和PropertySourcesPlaceholderConfigurer。

e.g:

@Configuration
@PropertySource(value = { "classpath:application.properties" })
...


@Bean
public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
    return new PropertySourcesPlaceholderConfigurer();
}

答案 1 :(得分:1)

您应该将值放在application.properties文件中,如:

database_url=jdbc:mysql://localhost:3306/pryme?createDatabaseIfNotExist=true
database_user=root
# more values...

现在,如果您可以创建一个从.properties文件中获取值的应用程序配置(只要该名称与上面的.properties文件匹配,该名称就不重要了。)

@Configuration
@PropertySource(value = "classpath:application.properties")
public class AppConfig{

@Bean
public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}

从这一点开始,如果在.properties文件中指定键,@Value注释将解析实际值:

@Value("${database_url}")
String databaseUrl;

@Value("${database_user}")
String databaseUser;

答案 2 :(得分:0)

你也可以像这样使用@Resource注释:

@Configuration
@PropertySource("classpath:application.properties")
...

@Resource
private Environment env;


dataSource.setUrl(env.getRequiredProperty("dataSource.url"));