SpringBoot_配置-@ConfigurationProperties与@Value区别

以前配bean标签的时候,我们要为哪一个组件配置对象,2我写一个person类型,包括配置的属性值是多少,

<bean class="person">
	<property name="lastName" value="字面量/${key}从环境变量、配置文件中获取值/#{SpEL}"></property>
</bean>
我写一个property这个标签,我们用name属性来赋值lastName,value就是指定值了,而这一块的value,和我们的@Value注解

是一样的,@Component注解的作用,也是把Person加入到容器中,bean标签也是加入到容器中,而这是一个value赋值,而这里

是使用@Value注解来赋值,比如我们写字面量,以前写字符串数字,布尔值都能写,包括还能写,${key},他的作用呢,是从环境变量,

或者我们也叫配置文件,获取值,这是他的第二种写法,第三种它还支持#{SpEL},Spring的表达式语言,他支持这几个,那我们@Value

里面也是支持这几个,比如我要获取配置文件中lastName,

//@Value("${person.last-name}")
private String lastName;

@Value("#{10*2}")
private Integer age;

这是我们Spring的表达式

然后还有布尔值,我就那这三个属性来测一测

@Value("true")
private Boolean boss;
package com.learn.bean;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * 将配置文件中配置的每一个属性的值,映射到这个组件
 * @ConfigurationProperties:告诉SpringBoot将本类中的所有属性和配置文件中的相关的配置进行绑定
 * 	 prefix="person":配置文件中哪个下面的所有属性进行映射
 * 
 * 只有这个组件是容器中的组件,才能容器提供的@ConfigurationProperties功能;
 * 默认从全局配置文件中获取值;
 */
//@PropertySource(value= {"classpath:person.properties"})
@Component
//@ConfigurationProperties(prefix="person")
//@Validated
public class Person {

	/**
	 * <bean class="person">
	 *    <property name="lastName" value="字面量/${key}从环境变量、配置文件中获取值/#{SpEL}"></property>
	 * </bean>
	 */
	// lastName必须是邮箱格式
	//@Email
	@Value("${person.last-name}")
	private String lastName;
	@Value("#{10*2}")
	private Integer age;
	@Value("true")
	private Boolean boss;
	
	private Date birth;
	//@Value("${person.maps}")
	private Map<String,Object> maps;
	
	private List<Object> lists;
	
	private Dog dog;

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public Boolean getBoss() {
		return boss;
	}

	public void setBoss(Boolean boss) {
		this.boss = boss;
	}

	public Date getBirth() {
		return birth;
	}

	public void setBirth(Date birth) {
		this.birth = birth;
	}

	public Map<String, Object> getMaps() {
		return maps;
	}

	public void setMaps(Map<String, Object> maps) {
		this.maps = maps;
	}

	public List<Object> getLists() {
		return lists;
	}

	public void setLists(List<Object> lists) {
		this.lists = lists;
	}

	public Dog getDog() {
		return dog;
	}

	public void setDog(Dog dog) {
		this.dog = dog;
	}

	@Override
	public String toString() {
		return "Person [lastName=" + lastName + ", age=" + age + ", boss=" + boss + ", birth=" + birth + ", maps="
				+ maps + ", lists=" + lists + ", dog=" + dog + "]";
	}
	
}
package com.learn.springboot;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import com.learn.bean.Person;

/**
 * SpringBoot单元测试
 *
 * 可以在测试期间很方便的类似编码一样进行自动注入等容器的功能
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBoot02ConfigurationTests {
	
	@Autowired
	Person person;
	
	@Test
	public void contextLoads() {
		System.out.println(person);
	}
	
	
}
Person [lastName=张三, age=20, boss=true, birth=null, maps=null, lists=null, dog=null]
22是算出来没问题,true也没问题,但是跟ConfigurationProperties,有没有区别,首先我们ConfigurationProperties只需要

一个注解,批量给我们注入,@Value要一个一个来注入,那我们把这些区别都放到这,一个是@ConfigurationProperties,

这个注解和@Value,他来获取值的区别,首先我们在功能上,@ConfigurationProperties(他可以批量注入我们的配置文件中的

属性,我们只需要指定一个properties就行了,@Value需要一个一个指定,@ConfigurationProperties他还支持一个松散绑定,

也就是松散语法,这个松散语法的意思就是说,特别是last-name,我们有一个属性名叫lastName,驼峰命名法的,那你用中间的

杠,大小写不区分,下划线,都是可以的,这是我们松散绑定

但是只有@ConfigurationProperties能够支持,如果我们把Value指成lastName

@Value("${person.lastName}")

由于我们配置文件里面是

person.last-name=\u5F20\u4E09

我们来看能不能支持,我们发现就启动报错了,说我们peron.last-name获取值有问题,所以我们必须是last-name,

他不支持松散语法绑定,而我们这个@ConfigurationProperties呢,他支持,用@ConfigurationProperties获取值,我们lastName

是能获取到值的,我们这一块你写last-name,还是lastName,这都没问题,人家支持松散语法绑定,这就是我们第二个松散语法绑定,

只有@ConfigurationProperties支持
@Value他也有他的好处,他还支持SPEL,Spring的表达式语言,SPEL支持方面,@ConfigurationProperties他就不支持了,

而我们的@Value它是支持的,我们在@Value上写一个东西,我们之前看过,他能帮我们算出来,

person.age=#{11*2}

我们发现就错了,错的原因他说,这是age,你要注入这个值的时候,typeMisMatch,类型转换异常,所以这一块他不支持Spring

表达式,这是我们的第二个区别
第三个区别呢,@ConfigurationProperties支持JSR303校验,我们给他里面再扩展一个,

JSR303数据校验,数据校验@ConfigurationProperties,他能支持,我们@Value他就不支持,

我们给配置文件注入值的时候,我们还可以校验一下,我们可以这样,用@Validated,我们这个JAVABEAN

里面的属性,要校验,比如我们加上第一个校验,我来给一个校验规则,比如@Email,就是lastName你要填成邮箱格式,

lastName必须是邮箱格式,我们是@ConfigurationProperties的情况下,我来运行,这一块就报错了,在注入lastName的时候,

错误代码email的,他还有错误的提示消息,不是一个合法的电子邮件地址,说明他启动了校验,但是如果我们换成@Value,

让他来给我们注入值,来看一下这个校验还能不能生效呢,发现这个校验是无效的,发现照样是取到值了,这是他们的这个区别,

JSR303是@ConfigurationProperties支持,@Value不支持,我们无论是配置文件,你写什么都行,不管是yml,还是properties,

他们都能获取到值,只是每一个获取值的区别,包括JSR303数据校验的时候,记录一下数据校验,配置文件注入值数据校验,

数据校验必须使用@ConfigurationProperties才可以
到底我们使用哪个比较合适呢,我们再来看一个最大的不同,我们来到@ConfigurationProperties,我们把它注掉,

他获取值一切都是正常的,而且还能做校验,校验我也注释掉,我不要校验功能了,现在这些值我不以他们为例,我用

@Value来获取Map的值,

@Value("${person.maps}")

我们看他能不能获取到,现在用的是@Value注解,我们启动的时候发现报错了,就是解析这个map,最大的在这,我们这个

@Value注解,在复杂类型封装,我们这个@ConfigurationProperties,它是能支持的,而我们的@Value它是不能,他只能取出

一些基本类型的数据,我们什么时候用@ConfigurationProperties,什么时候用@Value,如果说我们只是在某个业务逻辑中

需要获取一下配置文件中的某项值,那就使用@Value,那举一个例子

除了用@ConfigurationProperties,从person里面读取所有的属性,我们还有一种方式,我们有一个注解是@Value,

这是我们Spring的一个底层注解,以前我们都是用配置的方式

<bean class="person">

我写一个Controller,就叫HelloController,我用@RestController标注上来,他就一个方法,这个hello给谁说呢,

我想Hello加上一个人名字,这个人名在配置文件中,我可以给他里面写一个name,而这个name从配置文件中@Value,

来获取就行了,

@Value("${person.last-name}")
private String name;

然后就给这个人打招呼,我们来访问一些这个请求,我们来访问这个sayHello请求

http://localhost:8080/sayHello
package com.learn.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
	
	@Value("${person.last-name}")
	private String name;

	@ResponseBody
	@RequestMapping("/sayHello")
	public String sayHello() {
		return "Hello" + name;
	}
}
package com.learn;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @SpringBootApplication 来标注一个主程序类,说明这是一个Sprint Boot应用
 * @author Leon.Sun
 *
 */
@SpringBootApplication
public class SpringBoot02ConfigApplication {

	public static void main(String[] args) {
		// Spring应用启动起来
		SpringApplication.run(SpringBoot02ConfigApplication.class,args);
	}
}
我们只是从配置文件中获取一下这个值,就使用@Value,如果说我们专门写了一个JAVABEAN来和配置文件来进行映射,

这就类似于我们和数据库里的记录,我们专门来写一个POJO一样,一个javaBean来映射配置文件中的值,我们就直接

使用@ConfigurationProperties,他就一次性把配置文件中相关的属性,都注入进来了,那就使用他,这是他们的区别,

当然在合适的时候,你如果需要用到其他的注解,那你就两个结合来用,他们的区别

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值