springboot 获取enviroment.Properties的几种方式

摘要:
@Value是一个spring原生函数,支持通过PropertyPlaceholderHelper替换EL表达式。replacePlaceholder()方法@ConfigurationProperties通过自动配置由spring引导实现,最后通过JavaBeanBinder实现松散绑定以获得资源1.1,@Value标记获取@Component@Setter@GetterpublicclassSysValue{@ValueprivateStringdefaultPW;}1.2,@ConfigurationProperties标记获取@Component@ConfigurationProperties @ Setter@GetterpublicclassSysConfig{privateStringdefaultPW;}1.3。直接获取@ComponentpublicclassEnvironmentValue{@AutowiredEnvironmentenvironment;privateStringdefaultPW;@PostConstruction//初始化调用publicvoid init(){defaultPW=environment.getProperty;}}PropertyResolver初始化和方法。环境:环境对象也继承解析器。Java语言lang.StringgetProperty:从键中获取值。PublicabstractclassAbstractEnvironmentImplementationsConfigurationEnvironment{//初始化环境抽象类时,将初始化PropertySourcesPropertyResolver,//并传入propertySource。privatefinalConfigurablePropertyResolverpropertyResolver=newPropertySourcesPproperty Resolver;}@Value获取资源源代码分析=Null){ReflectionUtils.makeAccessible;field.set;}PropertySourcesPlaceholderConfigurer:PropertySourcesPropertyResolver:(根据键获取值。

springboot获取配置资源,主要分3种方式:@Value、 @ConfigurationProperties、Enviroment对象直接调用。
前2种底层实现原理,都是通过第三种方式实现。

@Value 是spring原生功能,通过PropertyPlaceholderHelper.replacePlaceholders()方法,支持EL表达式的替换。

@ConfigurationProperties则是springboot 通过自动配置实现,并且最后通过JavaBeanBinder 来实现松绑定

获取资源的方式

1.1、@Value标签获取

@Component
@Setter@Getter
public class SysValue {
    @Value("${sys.defaultPW}")
    private String defaultPW;
}

1.2、@ConfigurationProperties标签获取

@Component
@ConfigurationProperties(prefix = "sys")
@Setter@Getter
public class SysConfig {
    private String defaultPW;
}

1.3、直接Enviroment对象获取回去

@Component
public class EnvironmentValue {
    @Autowired
    Environment environment;
    private String defaultPW;
    @PostConstruct//初始化调用
    public  void init(){
        defaultPW=environment.getProperty("sys.defaultPW");
    }

}

PropertyResolver初始化与方法。

2.1、api解释:

Interface for resolving properties against any underlying source.
(解析properties针对于任何底层资源的接口)

2.2、常用实现类

PropertySourcesPropertyResolver:配置源解析器。
Environment:environment对象也继承了解析器。

2.3、常用方法。

java.lang.String getProperty(java.lang.String key):根绝 Key获取值。
java.lang.String resolvePlaceholders(java.lang.String text)
:替换$(....)占位符,并赋予值。(@Value 底层通过该方法实现)。

2.4、springboot中environment初始化过程初始化PropertySourcesPropertyResolver代码。

public abstract class AbstractEnvironment implements ConfigurableEnvironment {
//初始化environment抽象类是,会初始化PropertySourcesPropertyResolver,
//并将propertySources传入。
//获取逻辑猜想:propertySources是一个List<>。
//getProperty方法会遍历List根据key获取到value
//一旦获取到value则跳出循环,从而实现优先级问题。
private final ConfigurablePropertyResolver propertyResolver =
            new PropertySourcesPropertyResolver(this.propertySources);
}

@Value获取资源源码分析。

解析过程涉及到(MMP看了一晚上看不懂,补贴代码了,贴个过程):
AutowiredAnnotationBeanPostProcessor:(@Value注解解析,赋值)

//赋值代码Autowired AnnotationBeanPostProcessor.AutowiredFieldElement.inject
if (value != null) {
                ReflectionUtils.makeAccessible(field);
                field.set(bean, value);
}

PropertySourcesPlaceholderConfigurer:(通过配置资源替换表达式)
PropertySourcesPropertyResolver:(根据key获取value。)

Enviroment 对象源码解析。

同上第三步,直接通过PropertySourcesPropertyResolver获取值。

2.4也能发现Enviroment new的PropertyResolver是PropertySourcesPropertyResolver

@ConfigurationProperties实现原理

核心类:
ConfigurationPropertiesBindingPostProcessor

//通过自动配置,@EnableConfigurationProperties注入
//ConfigurationPropertiesBindingPostProcessor
@Configuration
@EnableConfigurationProperties
public class ConfigurationPropertiesAutoConfiguration {

}

ConfigurationPropertiesBindingPostProcessor 类解析

//绑定数据
private void bind(Object bean, String beanName, ConfigurationProperties annotation) {
        ResolvableType type = getBeanType(bean, beanName);
        Validated validated = getAnnotation(bean, beanName, Validated.class);
        Annotation[] annotations = (validated != null)
                ? new Annotation[] { annotation, validated }
                : new Annotation[] { annotation };
        Bindable<?> target = Bindable.of(type).withExistingValue(bean)
                .withAnnotations(annotations);
        try {
            //绑定方法
            this.configurationPropertiesBinder.bind(target);
        }
        catch (Exception ex) {
            throw new ConfigurationPropertiesBindException(beanName, bean, annotation,
                    ex);
        }
}

//调用ConfigurationPropertiesBinder .bind方法。
class ConfigurationPropertiesBinder {
  public void bind(Bindable<?> target) {
        ConfigurationProperties annotation = target
                .getAnnotation(ConfigurationProperties.class);
        Assert.state(annotation != null,
                () -> "Missing @ConfigurationProperties on " + target);
        List<Validator> validators = getValidators(target);
        BindHandler bindHandler = getBindHandler(annotation, validators);
        //调用getBinder方法
        getBinder().bind(annotation.prefix(), target, bindHandler);
    }

   //getBinder方法初始化Binder对象
   // 传入熟悉的PropertySources:也来自PropertySourcesPlaceholderConfigurer对象同@Value
   //PropertySourcesPlaceholdersResolver
   private Binder getBinder() {
        if (this.binder == null) {
            this.binder = new Binder(getConfigurationPropertySources(),
                    getPropertySourcesPlaceholdersResolver(), getConversionService(),
                    getPropertyEditorInitializer());
        }
        return this.binder;
    }
}

Binder.bind()方法解析

//很深,最后通过JavaBeanBinder 来绑定数据
//为何ConfigurationProperties无法绑定静态对象:
//JavaBeanBinder会过滤掉静态方法
private boolean isCandidate(Method method) {
            int modifiers = method.getModifiers();
            return Modifier.isPublic(modifiers) && !Modifier.isAbstract(modifiers)
                    && !Modifier.isStatic(modifiers)//非静态方法
                    && !Object.class.equals(method.getDeclaringClass())
                    && !Class.class.equals(method.getDeclaringClass());
}

本文转自:https://www.jianshu.com/p/62f0cdc435c8

免责声明:文章转载自《springboot 获取enviroment.Properties的几种方式》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇doc命令操作数据库(下)Maven常用命令的使用下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

element ui设置表格表头高度和每一行的高度

.el-table__headertr,.el-table__headerth{padding:0;height:30px;line-height:30px;}.el-table__bodytr,.el-table__bodytd{padding:0;height:30px;line-height:30px;}...

Python之路

Python之路引子与其感慨路难行,不如马上出发PythonPython之路(一):初识Python之路(二):基本数据类型(上)Python之路(三):基本数据类型(下)Python之路(四):函数介绍及使用Python之路(五):内置函数Python之路(六):迭代器,装饰器,生成器Python之路(七):字符串处理Python之路(八):基础模块(一)...

CSS躬行记(8)——裁剪和遮罩

裁剪最早是在CSS2.1时代由clip属性引入,但该属性只能应用于绝对定位的元素,并且只能裁剪成矩形。CSS3提供了强大的clip-path属性,突破了clip属性的众多限制,接下来将围绕clip-path属性展开讲解。3)裁剪路径对于复杂的形状,可以采用SVG来创建裁剪路径,实现自定义。2)替换元素的填充和定位CSS3引入了两个新属性,用于遮罩替换元素。...

谷歌浏览器插件安装、VIP看视频、解除百度网盘限速

谷歌浏览器的插件主要由石油猴子获得。为了安装油猴,您需要先安装Google Access Assistant。utm_Source=chrome ntp图标建议使用几个视频下载插件https://jingyan.baidu.com/article/49711c61b19dd5fa441b7ccd.html两个插件“百度通用网盘助手”、“网盘直链下载助手”和一...

fiddler抓包+雷电模拟器 完成手机app抓包的配置

找到系统应用,点击设置,点击无线网络WLAN—˃左键常按点击已连接网络—˃修改网络鼠标左键长按在桌面找到下面这个文件之后双击打开上面证书弄完之后。可以说本机已经安装过证书了,如果你能在模拟器上找到这个证书就不用将这个证书再拉入模拟器了在模拟器中打开系统应用—˃设置—˃安全—˃从SD卡安装。找到FiddlerRoot.cer文件,按提示导入即可,注意在此过程需...

PNETLab模拟器部署及使用配置

为了提高虚拟网络的仿真程度,您可以运行IOL(Cisco IOSonLinux)、Dynamips、Quem和其他图像来支持在线实验拓扑下载。...