@ConfigurationProperties的使用及与@Value的区别

@ConfigurationProperties

其主要作用是将配置文件中特定属性转换为Java对象,方便管理和使用。
其可以作为单独的Bean使用,也可以配合@Configuration使用(好像有点废话了)

@Configuration注解使用
SpringBoot 自定义starter组件
注:本文以将aliyun短信sdk中所需配置提升到Springboot配置文件中为例

与配置文件对应关系

application.yml配置文件

spring:  
  aliyun:
    domain: dysmsapi.aliyuncs.com
    regionid: cn-hangzhou
    accessKeyId: ********
    secret: ******************
    version: 2017-05-25

对应Class

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "spring.aliyun")
public class AliyunProperties {
    private String domain;
    private String version;
    private String regionid;
    private String accessKeyId;
    private String secret;

    public String getDomain() {
        return domain;
    }

    public void setDomain(String domain) {
        this.domain = domain;
    }

    public String getVersion() {
        return version;
    }

    public void setVersion(String version) {
        this.version = version;
    }

    public String getRegionid() {
        return regionid;
    }

    public void setRegionid(String regionid) {
        this.regionid = regionid;
    }

    public String getAccessKeyId() {
        return accessKeyId;
    }

    public void setAccessKeyId(String accessKeyId) {
        this.accessKeyId = accessKeyId;
    }

    public String getSecret() {
        return secret;
    }

    public void setSecret(String secret) {
        this.secret = secret;
    }
}

至此,当你的AliyunProperties.java在Spring的扫描路径(scanBasePackages)下时,配置文件到对象的配置就已经完成了(注意并不能直接使用)。

在SpringBoot项目中的使用

基于Spring的IOC的思想,此时AliyunProperties是不能被别的Bean所注入的,原因因为:

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ConfigurationProperties {
	@AliasFor("prefix")
	String value() default "";
	@AliasFor("value")
	String prefix() default "";
	boolean ignoreInvalidFields() default false;
	boolean ignoreUnknownFields() default true;

}

其并未声明未Spring的组件,如果想像其他Bean那样直接交由IOC容器进行实例化,声明此类时加上@Component注解标注其为Bean组件即可:

@ConfigurationProperties(prefix = "spring.aliyun")
@Component //将其声明为Bean组件,注入到IOC容器中
public class AliyunProperties {
//... 代码在上面
}

在@Configuration注解下使用实例:

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.profile.DefaultProfile;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;

/**
 * 阿里云服务客户端
 */
@Configuration
public class AcsClient {
    // 阿里云配置
    private static DefaultProfile profile = null;
    private static AcsSmsClient acsSmsClient = null;
    @Bean
    public IAcsClient client(AliyunProperties aliyunProperties){
    	// 省略具体实现,不影响解读
    }
 }

作为普通Bean组件使用

@RestController
@RequestMapping("/sms")
public class SmsController {
	@Autowired
    AliyunProperties aliyunProperties;
}

通过以上两种使用方式,可以看到,在AliyunProperties这个Bean使用的时候属性已经是配置文件里的内容,也就是说AliyunProperties实例化后的属性是经过修改的(默认全为空),那么是什么时候修改的呢?这就需要了解@ConfigurationProperties的实现原理(关键点:Spring的Bean后处理器)。

其实在SpringBoot中还有个注解与@ConfigurationProperties比较相近@EnableConfigurationProperties, 这两者是配合使用的,@EnableConfigurationProperties注解是将指定的@ConfigurationProperties标注的类Bean化,这种实现方式AliyunProperties.java就不需要再@Component去声明了。

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.profile.DefaultProfile;
import org.springframework.context.annotation.Bean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;

/**
 * 阿里云服务客户端
 */
@Configuration
@EnableConfigurationProperties({AliyunProperties.class})
public class AcsClient {
    // 阿里云配置
    private static DefaultProfile profile = null;
    private static AcsSmsClient acsSmsClient = null;
    @Bean
    public IAcsClient client(AliyunProperties aliyunProperties){
    	// 省略具体实现,不影响解读
    }
 }

@Value的使用

首先说明一点,@Value是spring-bean内提供的属性装配注解;
其使用方式有两种:
${ property : default_value } // 读取配置文件内属性(无需默认值的时候请连“:”一并省略,参见下面代码)
#{ obj.property? :default_value } // 读取对象属性(Bean)或者方法返回值(需要在前面增加@,如#{@obj.getValue()})

使用方式较为简单,在需要的Bean内直接使用注解即可

import org.springframework.beans.factory.annotation.Value;
@Service
public class DemoServiceImpl implements DemoService {
	@Value("${base.server.serverurl}")
    public String serverurl;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章