spring@value取不到值的几种情况

一,spring组件重写构造方法,在构造方法中引用@value为null

由于spring实例化顺序为先执行构造方法,再注入成员变量,所以序为先执行构造方法,再注入成员变量,所以ing实例化顺取值为null
解决办法为:再写一个常量类,在常量类中引用@value,再在构造方法中引用常量类的变量即可。

二,调用spring组件时使用new对象,而不是@Autowired

三,使用final或static修饰成员变量

四,spring mvc中引用@value为null

spring mvc是spring的子容器,需要在两个配置文件中都导入配置文件
<context:property-placeholder location="classpath:jdbc.properties" ignore-unresolvable="true"/>

http://blog.51cto.com/jtech/2114686

springboot @ConfigurationProperties @EnableConfigurationProperties 自动配置

通过redis自动配置过程看这两个注解的联合使用,达到自动配置
springboot项目,maven

application.properties
配置redis

...
spring.redis.port=7379
...

需要获取配置的类,比如@Configuration注解的配置类,需要获取redis配置的其他类,redisProperties.getHost() 就可以取到配置

import org.springframework.boot.autoconfigure.data.redis.RedisProperties

@EnableConfigurationProperties(RedisProperties.class)
class JedisMy{
@Autowired
private RedisProperties redisProperties
}

获取使用内置的Environment获取配置,需要指定配置的key,上面的自动配置,key就是类的属性,redis的配置都是RedisProperties的属性

import org.springframework.core.env.Environment

class ddd{
@Autowired
private Environment env;

public void dd(){
env.getProperty("spring.redis.port");
}
}
---------------------
作者:qianggetaba
来源:CSDN
原文:https://blog.csdn.net/c5113620/article/details/81383297
版权声明:本文为博主原创文章,转载请附上博文链接!

关与 @EnableConfigurationProperties 注解

@EnableConfigurationProperties
测试发现 @ConfigurationProperties@EnableConfigurationProperties 关系特别大。

@EnableConfigurationProperties 文档中解释:
@EnableConfigurationProperties注解应用到你的@Configuration时, 任何被@ConfigurationProperties注解的beans将自动被Environment属性配置。 这种风格的配置特别适合与SpringApplication的外部YAML配置进行配合使用。

测试发现:
1.使用 @EnableConfigurationProperties 进行注册

@ConfigurationProperties(prefix = "service.properties")
public class HelloServiceProperties {
    private static final String SERVICE_NAME = "test-service";

    private String msg = SERVICE_NAME;
       set/get
}


@Configuration
@EnableConfigurationProperties(HelloServiceProperties.class)
@ConditionalOnClass(HelloService.class)
@ConditionalOnProperty(prefix = "hello", value = "enable", matchIfMissing = true)
public class HelloServiceAutoConfiguration {

}

@RestController
public class ConfigurationPropertiesController {

    @Autowired
    private HelloServiceProperties helloServiceProperties;

    @RequestMapping("/getObjectProperties")
    public Object getObjectProperties () {
        System.out.println(helloServiceProperties.getMsg());
        return myConfigTest.getProperties();
    }
}

自动配置设置

service.properties.name=my-test-name
service.properties.ip=192.168.1.1
service.user=kayle
service.port=8080

一切正常,但是 HelloServiceAutoConfiguration 头部不使用 @EnableConfigurationProperties,测访问报错。

2.不使用 @EnableConfigurationProperties 进行注册,使用 @Component 注册

@ConfigurationProperties(prefix = "service.properties")
@Component
public class HelloServiceProperties {
    private static final String SERVICE_NAME = "test-service";

    private String msg = SERVICE_NAME;

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

}

Controller 不变,一切正常,如果注释掉 @Component 测启动报错。
由此证明,两种方式都是将被 @ConfigurationProperties 修饰的类,加载到 Spring Env 中。



作者:咪雅先森
链接:https://www.jianshu.com/p/7f54da1cb2eb
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

Spring @Value 设置默认值

1. 概述
在 Spring 组件中使用 @Value 注解的方式,很方便的读取 properties 文件的配置值。

2.使用场景
声明的变量中使用。

public static class FieldValueTestBean {
 
    @Value("#{ systemProperties['user.region'] }")
    private String defaultLocale;
 
}

setter 方法中

public static class PropertyValueTestBean {
 
    private String defaultLocale;
 
    @Value("#{ systemProperties['user.region'] }")
    public void setDefaultLocale(String defaultLocale) {
        this.defaultLocale = defaultLocale;
    }
 
}

方法中

public class SimpleMovieLister {
 
    private MovieFinder movieFinder;
    private String defaultLocale;
 
    @Autowired
    public void configure(MovieFinder movieFinder,
            @Value("#{ systemProperties['user.region'] }") String defaultLocale) {
        this.movieFinder = movieFinder;
        this.defaultLocale = defaultLocale;
    }
 
    // ...
}

构造方法

public class MovieRecommender {
 
    private String defaultLocale;
 
    private CustomerPreferenceDao customerPreferenceDao;
 
    @Autowired
    public MovieRecommender(CustomerPreferenceDao customerPreferenceDao,
            @Value("#{systemProperties['user.country']}") String defaultLocale) {
        this.customerPreferenceDao = customerPreferenceDao;
        this.defaultLocale = defaultLocale;
    }
 
    // ...
}

3. 字符串
字符串类型的属性设置默认值

@Value("${some.key:my default value}")
private String stringWithDefaultValue;

some.key 没有设置值,stringWithDefaultValue 变量值将会被设置成 my default value 。
如果默认值设为空,也将会被设置成默认值。

@Value("${some.key:}")
private String stringWithBlankDefaultValue;


4. 基本类型
基本类型设置默认值。

@Value("${some.key:true}")
private boolean booleanWithDefaultValue;
 
@Value("${some.key:42}")
private int intWithDefaultValue;

包装类型设置默认值。

@Value("${some.key:true}")
private Boolean booleanWithDefaultValue;
 
@Value("${some.key:42}")
private Integer intWithDefaultValue;

5. 数组
数组的默认值可以使用逗号分割。

@Value("${some.key:one,two,three}")
private String[] stringArrayWithDefaults;
 
@Value("${some.key:1,2,3}")
private int[] intArrayWithDefaults;

6. SpEL
使用 Spring Expression Language (SpEL) 设置默认值。

下面的代码标示在systemProperties属性文件中,如果没有设置 some.key 的值,my default system property value 会被设置成默认值。

@Value("#{systemProperties['some.key'] ?: 'my default system property value'}")
private String spelWithDefaultValue;

7.结语
上面讲解使用 Spring @Value 为属性设置默认值。在项目中,提供合理的默认值,在大多情况下不用任何配置,就能直接使用。达到零配置的效果,降低被人使用的门槛。简化新Spring应用的搭建、开发、部署过程。

8.参考链接

Using Spring @Value with Defaults

Annotation-based configuration

https://blog.csdn.net/vcfriend/article/details/79700048

import org.apache.commons.io.IOUtils;
import org.hamcrest.Matchers;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.io.Resource;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.IOException;
import java.util.List;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.arrayContaining;
import static org.hamcrest.Matchers.arrayWithSize;
import static org.hamcrest.Matchers.emptyArray;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.core.IsNull.notNullValue;

/**
 * Created by tangcheng on 10/15/2017.
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class InjectTest {

    @Value("classpath:sourceData.txt")
    private Resource resource;

    @Value("${list.items:1,2,3}")
    private String[] items;

    @Value("${list.items:1,2,3}")
    private Long[] longItems;

    @Value("${list.items:}")
    private String[] itemsWithDefaultBlankValue;

    //@Value("${list.items}")
    private String[] itemsWithoutDefault;

    @Value("${str.value:}")
    private String strWithDefault;

    @Test
    public void injectFileTest() throws IOException {
        assertThat(resource, notNullValue());
        String canonicalPath = resource.getFile().getCanonicalPath();
        System.out.println(canonicalPath);
        List<String> list = IOUtils.readLines(resource.getInputStream(), "utf-8");
        assertThat(list, Matchers.hasItems("123", "456"));
        for (String s : list) {
            System.out.println(s);
        }
    }

    /**
     * 使用英文逗点分隔的字符串会被按 英文逗点 进行分隔成 一个数组
     */
    @Test
    public void valueAnnotation_Given_String_Separate_With_Comma_Then_Return_Array() {
        assertThat(items, notNullValue());
        assertThat(items, arrayWithSize(3));
        for (String item : items) {
            System.out.println(item);
        }
        assertThat(items, arrayWithSize(3));
    }

    /**
     * 使用:后,没有给默认值,则只会初始化数组。里面没有东西。
     * 即仅仅 不为null
     */
    @Test
    public void valueAnnotation_Given_Default_With_StringNum_Then_Return_Long_Type_Array() {
        assertThat(longItems, notNullValue());
        assertThat(longItems.length, is(3));
        assertThat(longItems, arrayContaining((long) 1, (long) 2, (long) 3));
    }

    /**
     * 使用:后,没有给默认值,则只会初始化数组。里面没有东西。
     * 即仅仅 不为null
     */
    @Test
    public void valueAnnotation_Given_Default_Is_Nothing_Then_Return_Empty_Array() {
        assertThat(itemsWithDefaultBlankValue, notNullValue());
        assertThat(itemsWithDefaultBlankValue, emptyArray());
        assertThat(itemsWithDefaultBlankValue.length, is(0));
    }


    /**
     * 使用 : 后,会有默认值 空字符串
     */
    @Test
    public void valueAnnotation_String() {
        assertThat(strWithDefault, is(""));
        assertThat(strWithDefault, Matchers.notNullValue());
        System.out.println("strWithDefault:" + strWithDefault + ";");
    }


}

https://github.com/helloworldtang/spring-boot-cookbook/blob/master/learning-demo/src/test/java/com/tangcheng/learning/inject/InjectTest.java

原文地址:https://www.cnblogs.com/softidea/p/10336661.html