【问题标题】:@Value with SpEL not able to get values from properties带有 SpEL 的 @Value 无法从属性中获取值
【发布时间】:2017-10-18 02:02:38
【问题描述】:

我在示例 Spring Boot 应用程序中有以下代码

@Configuration
@PropertySource("classpath:second.properties")
public class PropertyConfig {

    @Value("#{guru.username}")
    String user;

    @Value("#{guru.password}")
    String password;

    @Value("#{guru.url}")
    String url;


    @Bean
    FakeDataSource getFakeDataSource() {
        FakeDataSource fk = new FakeDataSource();

        fk.setName(user);
        fk.setPassword(password);
        fk.setUrl(url);

        return fk;
    }

    @Bean
    PropertySourcesPlaceholderConfigurer getPropertySourcesPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer placeholderConfigurer= new PropertySourcesPlaceholderConfigurer();
        //placeholderConfigurer.setLocation(new ClassPathResource("second.properties"));

        return placeholderConfigurer;
    }
}

而 FakeDataSource 是一个简单的 pojo,具有 name、passowrd、url 属性。

然后是我的主应用程序

@SpringBootApplication
public class SpringGuru101DependencyInjectionApplication {
    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(SpringGuru101DependencyInjectionApplication.class, args);

        // Step 2: Make Class
        FakeDataSource fakeDataSource = ctx.getBean(FakeDataSource.class);

        System.out.println(fakeDataSource.getName());
    }
}

但是 sout 语句正在打印 null, 我的 second.properties 文件存在于我的资源目录中,内容如下

guru.username=Saurabh
guru.password=ido
guru.url=http://example.com

【问题讨论】:

  • 试试@ImportResource("classpath:second.properties")
  • 请尝试将井口符号 (#) 替换为美元符号 ($),以便从配置文件中读取值。例如:@Value("${guru.username}")
  • 如果我使用 @ImportSource(classpath) org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 1 in XML document from class path resource [second.properties] is invalid; nested exception is org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Content is not allowed in prolog. @ScaryWombat 应用程序无法编译
  • @LHCHIN 仍然为空
  • @Saurabh 我写了@ImportResource 不是 @ImportSource

标签: java spring spring-boot


【解决方案1】:

有两个地方需要更正:
(1) 正如我在您问题的评论中所说,您应该将井口符号 (#) 替换为美元符号 ($) 以从配置文件中读取值。例如:@Value("${guru.username}")

(2) 你在方法getPropertySourcesPlaceholderConfigurer前面漏掉了public static
而这个修改后的方法应该如下所示:

@Bean
public static PropertySourcesPlaceholderConfigurer getPropertySourcesPlaceholderConfigurer() {
    PropertySourcesPlaceholderConfigurer placeholderConfigurer= new PropertySourcesPlaceholderConfigurer();
    //placeholderConfigurer.setLocation(new ClassPathResource("second.properties"));

    return placeholderConfigurer;
}

【讨论】:

    【解决方案2】:

    如果您使用的是 Spring-boot,您可以使用 Spring boot 推荐的另一种读取配置的方法。这将帮助您摆脱所有 @Value 符号,允许 spring 注入属性而无需额外提示。

    你可以做类似的事情:

    @ConfigurationProperties("foo")
    public class FooProperties {
    
    private boolean enabled;
    
    private InetAddress remoteAddress;
    
    private final Security security = new Security();
    
    public boolean isEnabled() { ... }
    
    public void setEnabled(boolean enabled) { ... }
    
    public InetAddress getRemoteAddress() { ... }
    
    public void setRemoteAddress(InetAddress remoteAddress) { ... }
    
    public Security getSecurity() { ... }
    
    public static class Security {
    
        private String username;
    
        private String password;
    
        private List<String> roles = new ArrayList<>(Collections.singleton("USER"));
    
        public String getUsername() { ... }
    
        public void setUsername(String username) { ... }
    
        public String getPassword() { ... }
    
        public void setPassword(String password) { ... }
    
        public List<String> getRoles() { ... }
    
        public void setRoles(List<String> roles) { ... }
    
    }
    

    }

    上面的 POJO 定义了以下属性:

    foo.enabled,默认为 false foo.remote-address,具有可以从 String 强制转换的类型 foo.security.username,具有嵌套的“安全”,其名称由属性名称确定。特别是那里根本没有使用返回类型,可能是 SecurityProperties foo.security.password foo.security.roles,带有字符串的集合

    更多详情:https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

    【讨论】:

    • Afaik 如果您希望许多字段与“foo.xxx”的属性类匹配,建议使用此方法,但在使用 1 个特定属性时不推荐
    猜你喜欢
    • 2020-04-21
    • 2018-06-14
    • 2020-03-02
    • 1970-01-01
    • 2013-05-07
    • 1970-01-01
    • 1970-01-01
    • 2021-05-26
    • 2020-01-28
    相关资源
    最近更新 更多