spring @Value注解的使用


@Value注解谁都用过,但还是有点细节的。

注入配置文件里面的属性

@value("${name}")
private String name;

使用冒号可以设置默认值,当属性不存在时使用默认值:

@value("${name:zhangsan}")
private String name;
boolean类型设置默认值的注意点

boolean类型设置默认值会报错。

代码:

@Value("testFlag:false") 
private boolean testFlag ;

报错信息:
org.springframework.beans.TypeMismatchException: Failed to convert value of type ‘java.lang.String’ to required type ‘boolean’; nested exception is java.lang.IllegalArgumentException: Invalid boolean value [redIssueReasonFixFlag:false]

解决方案:
1、boolean的默认值是false。一般情况下干脆不用默认值就好。
2、如果要改的话涉及到spring源码了,需要修改PropertyPlaceholderHelper对象,略。

直接注入字符串

@value("zhangsan")
private String name;

注入数组

配置文件:

user.types=1,3,5

java代码为:

@Value("${user.types}")
private String[] types;

数组中可以设置默认值吗?当然可以。
注:冒号后面直接写1,2,3即可,不用加中括号。

@Value("${user.types:1,4,5,7,9,13}")
private String[] type;

注入集合(数组,list,set等)

注入set

java代码:

@Value("${urlList:'test/','api/'}")
private static Set<String> urlList = Sets.newHashSet("test/","api/");

application.yml:

urlList: test/,api/

注,以下写法错:
urlList: 'test/','api/'
所以带有空格的字符串是没法弄的,但是话又说回来,路径也不能含有空格啊。

注入map

首先确认一点,直接注入map是不支持的,会报错。 @Value只支持直接注入简单的类型。
那么可以注入map吗?
可以的。但是需要手法。

定义一个解析map类:

public class MapDecoder {
    public static HashMap<String, List> decodeMap(String value) {
        try {
            return JSONObject.parseObject(value, new TypeReference <HashMap<String, List>>(){});
        } catch (Exception e) {
            return null;
        }
    }
}

注入的代码:

@Value("#{T(com.utils.MapDecoder).decodeMap('${custommJson:}')}")
private HashMap<String,List<String>> custommMap;

custommJson 的值为: {"1":[],"2":["333","444","555","666"]}

静态注入

静态注入肯定是可以实现的,这里也一起说下。
@PostConstruct即可实现,原理就是@PostConstruct在@Value之后加载,因此可以在这里将值赋给静态变量。

加载顺序:
构造方法 >>>> @Autowired/@Value >>>> @PostConstruct

private static HashMap<String, List<String>> mapStatic=new HashMap<>();

@Value("#{T(com.utils.MapDecoder).decodeMap('${customJson:}')}")
private HashMap<String,List<String>> customMap;

@PostConstruct
public void init(){
    logger.info("开始,customMap={}", JSON.toJSONString(customMap));
    customMapStatic=customMap;
    logger.info("完成,customMapStatic={}",JSON.toJSONString(customMapStatic));
}

注入集合的问题

还有一个问题,

@Order(1)
@Component
@WebFilter(filterName = "MainFileter", urlPatterns = "/*")

在controller中是列表,在Filter中为什么是字符串呢?

使用SpEl表达式注入

SpEl表达式支持加减乘除,这里只举一例:

@Value("#{5*2}")
private Double number; 

注入操作系统属性

@Value("#{systemProperties['os.name']}")
private String osName; // 例如: Windows 7

注入容器中对象的属性

@Component
@Data
public class Student {
    @Value("yangyanzhao")
    private String name;
}
 
// =========== 另一个类中这么写
@Value("#{student.name}")
private String studentName;

基于对象注入

注入文件
@Value("classpath:aaa.txt")
private Resource file;  
注入网址内容
@Value("http://www.baidu.com")
private Resource baidu; 
可以注入到注解中吗

mq的@RabbitListener接收消息。
想做成可配置的形式,就不用来会注释代码了。

注:直接配置应该是不行的,但是可以通过自定义@Condition,里面注入配置,然后再把condition加到该类或方法上。

实测可行,但是绕一大圈子,还不如注释代码来的方便。
而且一个功能就需要一个condition,需要的condition太多了。

其他

记一次诡异事件

yml中配置的为:

httpDomain: www.test.com

service代码为:

@Value("${httpDomain}")
private String httpDomain;

启动项目报错:
Could not resolve placeholder ‘httpDomain’ in value “${httpDomain}”

真是怪了,我都开始怀疑我自己了。
难道是service中不能用@Value注入? 没道理啊。

左查右查,前查后查。 发现代码没问题啊,就是启动报错。
那是jdk的问题? idea的问题?

最后发现是yml中分为多profile。 配置写到其他profile中了。 找不到这个变量,当然报错。
那时正是开发的紧张期,时间很宝贵。 由于大意,白白浪费了一小时。 真恨不得抽自己几个耳光。

所以一定要细心,另: 这种注入错误一般是没找到配置。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值