1.Spring环境抽象的概念

2.怎么配置属性。在application.yml举例一些常用的配置

3.自定义配置属性@ConfigurationProperties(prefix = "xx.xxxx")

3.1在类上使用

3.2在方法上使用

  1. 配置属性元数据-即给配置属性加注释说明
  2. 使用profile配置多套配置属性,在不同的环境下根据需要切换配置属性
    1. 怎么定义多个profile
    2. 激活profile 设定配置类下哪些bean在特定的profile生效时才去创建(不设置是不论什么profile生效都自动创建)

一:Spring环境抽象

Spring环境抽象:它时各种配置属性的一站式服务。它抽取了原始的属性,这样需要这些属性的bean就可以从spring本身获取了。配置属性也就是bean的属性值

Spring环境会拉取多个属性源:

  1. JVM系统属性
  2. 操作系统环境变量
  3. 命令行参数
  4. 应用属性配置文件(比如说:application.yml文件)

Spring环境抽象:我的理解,他会去读取上述的配置保存起来,在spring需要这些相关配置的时候取出来使用。

二:配置属性

以下例举了几个配置(在application.yml文件中)

 1.几个常见配置实例

  1)数据源

spring:

  datasource:

    url: jdbc:mysql://localhost:3306/text?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=UTC

    username: root

    password: 573875306

    driver-class-name: com.mysql.jdbc.Driver

2)嵌入式服务,下面例举的是配置HTTPS

  #端口号

  server.port: 8443

  #你生成的证书名字

  server.ssl.key-store: E:\work\rave\tomcat.keystore

  #密钥库密码

  server.ssl.key-store-password: duan123

  server.ssl.keyStoreType: JKS

  server.ssl.keyAlias: tomcat

  3)配置日志

  默认情况下springbot通过logback配置日期,日志会议INFO级别写入控制台,在此基础上,我们可以做一些配置

  logging:

  path:/var/logs         //path 和 file 属性组成日志文件

  file:TacoCioud.log

  level: //配置级别 ,不如说想把root配置为WARN,把security配置为DEBUG(可以分区块来定义不同的级别)

  root:WARN

  org.springframework.security:DEBUG

 2.使用特定的属性值,相当于调用其他属性值

  比如我们想设置一个 greeting.welcom的属性,而这个属性的值是另一个属性spring.application.name的值

  Greeting:

  welcom: ${spring.application.name}

 3.创建自己的配置属性@ConfigurationProperties

  正如上面所说的,配置属性也就是bean的属性值。我们在spring的抽象环境中配置这些属性。spring上下文会在创建bean是自动装配。但是还没有讲我们自己如果想要消费配置属性,即手动给bean赋值配置属性,应该怎么操作。

  为了支持配置属性注入,springboot提供了注解@ConfigurationProperties

  Spring源码中大量使用了ConfigurationProperties注解,比如server.port就是由该注解获取到的,通过与其他注解配合使用,能够实现Bean的按需配置。该注解有一个prefix属性,通过指定的前缀,绑定配置文件中的配置,该注解可以放在类上,也可以放在方法上

  3.1@ConfigurationProperties作用与方法。比较常见的就是配置读写分离的场景。

  当将该注解作用于方法上时,如果想要有效的绑定配置,那么该方法需要有@Bean注解,且方法所属Class需要有@Configuration注解。

  简单一句话概括就是:Sring的有效运行是通过上下文(Bean容器)中Bean的配合完成的,Bean可以简单理解成对象,有些对象需要指定字段内容,那么这些内容我们可以通过配置文件进行绑定,然后将此Bean归还给容器

    1)配置文件内容

#数据源

spring.datasource.druid.write.url=jdbc:mysql://localhost:3306/jpa

spring.datasource.druid.write.username=root

spring.datasource.druid.write.password=1

spring.datasource.druid.write.driver-class-name=com.mysql.jdbc.Driver

spring.datasource.druid.read.url=jdbc:mysql://localhost:3306/jpa

spring.datasource.druid.read.username=root

spring.datasource.druid.read.password=1

spring.datasource.druid.read.driver-class-name=com.mysql.jdbc.Driver

    2)java代码

@Configuration

public class DruidDataSourceConfig {

    /**

     * DataSource 配置

     * @return

     */

    @ConfigurationProperties(prefix = "spring.datasource.druid.read")

    @Bean(name = "readDruidDataSource")

    public DataSource readDruidDataSource() {

        return new DruidDataSource();

    }

    /**

     * DataSource 配置

     * @return

     */

    @ConfigurationProperties(prefix = "spring.datasource.druid.write")

    @Bean(name = "writeDruidDataSource")

    @Primary

    public DataSource writeDruidDataSource() {

        return new DruidDataSource();

    }

}

  prefix 属性指定了配置属性,如spring.datasource.druid.write,配置文件中spring.datasource.druid.write下有四个属性,然后会自动和方法下的对应的bean进行绑定。这里绑定的就是DataSource类型的对象,这个绑定是隐式的,意味着配置文件编写的属性名和要绑定的对象的属性名要一致

  3.2@ConfigurationProperties作用于类

    1)配置文件

spring.datasource.url=jdbc:mysql://127.0.0.1:8888/test?useUnicode=false&autoReconnect=true&characterEncoding=utf-8

spring.datasource.username=root

spring.datasource.password=root

spring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.type=com.alibaba.druid.pool.DruidDataSource

    2)java代码

@ConfigurationProperties(prefix = "spring.datasource")

@Component

public class DatasourcePro {

    private String url;

    private String username;

    private String password;

    // 配置文件中是driver-class-name, 转驼峰命名便可以绑定成

    private String driverClassName;

    private String type;

    public String getUrl() {

        return url;

    }

    public void setUrl(String url) {

        this.url = url;

    }

    public String getUsername() {

        return username;

    }

    public void setUsername(String username) {

        this.username = username;

    }

    public String getPassword() {

        return password;

    }

    public void setPassword(String password) {

        this.password = password;

    }

    public String getDriverClassName() {

        return driverClassName;

    }

    public void setDriverClassName(String driverClassName) {

        this.driverClassName = driverClassName;

    }

    public String getType() {

        return type;

    }

    public void setType(String type) {

        this.type = type;

    }

}

@Controller

@RequestMapping(value = "/config")

public class ConfigurationPropertiesController {

    @Autowired

    private DatasourcePro datasourcePro;

    @RequestMapping("/test")

    @ResponseBody

    public Map<String, Object> test(){

        Map<String, Object> map = new HashMap<>();

        map.put("url", datasourcePro.getUrl());

        map.put("userName", datasourcePro.getUsername());

        map.put("password", datasourcePro.getPassword());

        map.put("className", datasourcePro.getDriverClassName());

        map.put("type", datasourcePro.getType());

        return map;

    }

}

  @ConfigurationProperties 和 @value 有着相同的功能,但是 @ConfigurationProperties的写法更为方便

  @ConfigurationProperties 的 POJO类的命名比较严格,因为它必须和prefix的后缀名要一致, 不然值会绑定不上, 特殊的后缀名是“driver-class-name”这种带横杠的情况,在POJO里面的命名规则是 下划线转驼峰就可以绑定成功,所以就是 “driverClassName”

通过上面的例子我们知道了,自己创建配置属性。它还有很多其他的用途。比如分页查询。我们可以自定义每页的数量作为一个配置属性来使用。

   3.3@ConfigurationProperties实例分页配置

      1)配置

mytxt:

    myconfig:

      page: 10

     size: asd

注意:配置的时候mytxt一定要和其它的配置竖向对齐,属性名和值之前要有空格

    2)代码

package tacos;

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

import org.springframework.stereotype.Component;

@ConfigurationProperties(prefix = "mytxt.myconfig")

@Component

public class PagePro {

private Integer page;

private String size ;

public Integer getPage() {

return page;

}

public void setPage(Integer page) {

this.page = page;

}

public String getSize() {

return size;

}

public void setSize(String size) {

this.size = size;

}

}

@Controller

public class pageController {

    private PagePro pp;

    public pageController(PagePro pp) {

super();

this.pp = pp;

}

@RequestMapping("/config/pagetest")

    @ResponseBody

    public Integer test(){

        System.out.println(pp.getPage());

        System.out.println(pp.getSize());

        return pp.getPage();
}
}

 4.申明配置属性元数据-即配置属性的注释

    在META-INF文件夹下创建一个文件additional-spring-cinfiguration-medadata.json 文件。在里面输入下面格式

{

"properties":[
  {
  "name":"mytxt.myconfig.page"   "type":"java.lang.Integer"   "description":"描述"   }
] }

  5.Profile配置

  它是一种条件化配置,在运行时,根据哪些Profile处于激活状态,相对于的使用配置属性。

  比如,在测试阶段,我么使用嵌入式数据库H2,日志采用debug。生产环境,数据库采用mysql,日志采用WARN

  那么怎么创建一个个的profile配置呢?

  5.1创建多个profile配置

    5.1.1第一种方法-创建多个文件

      例子:构建生产环境的配置

      1)新建一个yaml或properties文件,文件名要按照application-名字.yaml或者application-名字.properties。还是使用yaml文件比较好。这里我们创建一个application-sc.yaml文件

      2)里面配置生产环境的属性

spring:

  datasource:

    url: jdbc:mysql://localhost:3306/text?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=UTC

    username: root

    password: 573875306

    driver-class-name: com.mysql.jdbc.Driver

logging:

  level:

    tacos:WARN

    -在一个application.yaml这一个文件中写

    多个profile主键用三个横线隔开,且使用spring.profiles属性来为profile命名。如下:

    三个横线上面有配置,这个配置没有使用spring.profiles属性来命名。这些属性就是通用属性,对每个profile都有效,当通用属性和profile的属性重复时,以profile为准。这里只配置了通用属性和一个名为sc的profile,若还需要配置其它的,在下面加三条横线继续配置即可

logging:

  level:

    tacos:DEBUG

---

spring:

profiles:sc

  datasource:

    url: jdbc:mysql://localhost:3306/text?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=UTC

    username: root

    password: 573875306

    driver-class-name: com.mysql.jdbc.Driver

logging:

  level:

    tacos:WARN

  5.2Profile激活

  上面讲了账目配置多个profile配置,却没有说怎么激活。

  在application.yaml中配置,指定默认激活的profile

spring:

  profiles:

    active: sc

  当需要变的时候: % export SPRING_PROFILES_ACTIVE_sc,sc指要使用的profile的名字

  如果是以jar文件运行的,在启动的时候可以使用命令行参数

  java -jar taco-cloud.jar --spring.profiles.active=sc

  补充说明:profile可以同时激活多个

  % export SPRING_PROFILES_ACTIVE_sc1,sc2,sc3

  java -jar taco-cloud.jar --spring.profiles.active=sc1,sc2,sc3

  spring:

   profiles:

   active:

    -sc1

    -sc2

    -sc3

  5.3使用profile条件化的创建bean

  正常情况下,不管哪个profile被激活,JAVA配置类中声明的所有bean都会被创建。我们可以通过配置使某个bean在特定的profile被激活的时候才会被创建

  @Profile:指定组件在哪个环境的情况下才能被注册到容器中,不指定,任何环境下都能注册这个组件

  使用@profile(“profile的名称”),多个用逗号隔开,还可以使用”!profile的名称”,感叹号表示”非”

package com.spring.config;

import java.beans.PropertyVetoException;

import javax.sql.DataSource;

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

import org.springframework.context.EmbeddedValueResolverAware;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.Profile;

import org.springframework.context.annotation.PropertySource;

import org.springframework.util.StringValueResolver;

import com.mchange.v2.c3p0.ComboPooledDataSource;

@Configuration

public class MainConfigOfProfile implements EmbeddedValueResolverAware{

@Value("${db.user}")

private String user;

private String driverClass;

@Profile("default")

@Bean("test")

public DataSource testDataSource(@Value("${db.password}")String password) throws PropertyVetoException {

ComboPooledDataSource dataSource = new ComboPooledDataSource();

dataSource.setUser(user);

dataSource.setPassword(password);

dataSource.setDriverClass(driverClass);

return dataSource;

}

}

spring-in-action-day04-配置属性 @ConfigurationProperties的更多相关文章

  1. spring boot下为配置属性值加密的正确姿势

    最近做电商系统,安全性要求比较高,针对配置属性值的加密自然也是需要增强的点之一,那么如何加密呢? 网上搜索了些,有jasypt加密mysql密码的最为普遍,可惜问题就在于只能加密mysql信息,其他的 ...

  2. Spring cloud Hystrix的配置属性优先级和详解

    Hystrix配置属性详解 Hystrix可以配置属性的有以下类型: Execution:控制HystrixCommand.run() 的如何执行 Fallback: 控制HystrixCommand ...

  3. Spring p名称空间配置属性

    1.p 名称空间介绍 从 2.0开始,Spring支持使用名称空间的可扩展配置格式.这些名称空间都是基于一种XML Schema定义.事实上,我们所看到的所有bean的配置格式都是基于一个 XML S ...

  4. Spring Cloud Config(配置中心)

    每天学习一点点 编程PDF电子书.视频教程免费下载:http://www.shitanlife.com/code 一.简介 Spring Cloud Config为分布式系统中的外部配置提供服务器和客 ...

  5. Spring Boot 2 实践记录之 使用 ConfigurationProperties 注解将配置属性匹配至配置类的属性

    在 Spring Boot 2 实践记录之 条件装配 一文中,曾经使用 Condition 类的 ConditionContext 参数获取了配置文件中的配置属性.但那是因为 Spring 提供了将上 ...

  6. struts2与spring集成时action的class属性值意义

    struts2单独使用时action由struts2自己负责创建:与spring集成时,action实例由spring负责创建(依赖注入).这导致在两种情况下struts.xml配置文件的略微差异. ...

  7. Spring boot将配置属性注入到bean类中

    一.@ConfigurationProperties注解的使用 看配置文件,我的是yaml格式的配置: // file application.yml my: servers: - dev.bar.c ...

  8. Java框架spring Boot学习笔记(二):Hello Spring Boot、以及项目属性配置

    新建一个新建一个SpringBootTest工程 新建一个HelloController.java文件 package com.example.demo; import org.springframe ...

  9. Spring学习笔记(二)——Spring相关配置&属性注入&Junit整合

    一.Spring的相关配置 1.1 Bean元素 class属性:被管理对象的完整类名 name属性:给Bean起个名字,能重复,能使用特殊字符.后来属性 id属性:给Bean起个名字,不能重复,不能 ...

  10. Spring boot将配置属性注入到bean 专题

    https://blog.csdn.net/wangmx1993328/article/details/81002901 Error starting ApplicationContext. To d ...

随机推荐

  1. 【题解】[ARC113C] String Invasion

    题面传送门 解决思路 题目大意是给你一个字符串 \(s\) ,定义一次操作为对于长度为 \(3\) 的一个子段,满足 \(s_i=s_{i+1}\ne s_{i+2}\),则可以将 \(s_{i+2} ...

  2. 【题解】CF919D Substring

    题面传送门 解决思路: DP 与拓扑结合.\(f_{i,j}\) 表示到 \(i\) 位置 \(j\) 的最大次数. 将 \(a \sim z\) 转成数字 \(0\sim 25\) ,方便存储. 考 ...

  3. eBPF 实践 -- 网络可观测

    简介 观测云采集器,是一款开源.一体式的数据采集 Agent,它提供全平台操作系统支持,拥有全面数据采集能力,涵盖基础设施.指标.日志.应用性能.用户访问以及安全巡检等各种场景.通过 eBPF 技术的 ...

  4. java中的自动拆装箱

    一:是什么 java的自动拆装箱,是从jdk1.5之后被引入的,java中的类型分为基本类型和引用类型,而自动拆装箱,可以让基本类型和对应的包装类,无缝转换.先拿最基本的来看. public clas ...

  5. services资源+pod详解

    services资源+pod详解 一.Service 虽然每个Pod都会分配一个单独的Pod IP,然而却存在如下两问题: Pod IP 会随着Pod的重建产生变化 Pod IP 仅仅是集群内可见的虚 ...

  6. day33 过滤器filter & 监听器listener & 利用反射创建BaseServlet实现调用自定义业务方法

    Filter过滤器 Fileter可以实现: 1)客户端的请求访问servlet之前拦截这些请求,对用户请求进行预处理 2)对HttpServletResponse进行后处理: 注意 多个Filter ...

  7. 【Java SE进阶】Day07 等待与唤醒案例、线程池、Lamdba表达式

    一.等待唤醒机制 1.线程间通信 多个线程处理同一个资源,就存在线程通信问题(线程间存在竞争与协作机制) 为什么处理:为了 保证多个线程有规律地完成同一任务 如何处理:避免对共享变量争夺,需要等待唤醒 ...

  8. 当我们的执行 java -jar xxx.jar 的时候底层到底做了什么?

    大家都知道我们常用的 SpringBoot 项目最终在线上运行的时候都是通过启动 java -jar xxx.jar 命令来运行的. 那你有没有想过一个问题,那就是当我们执行 java -jar 命令 ...

  9. Redis 如何批量设置过期时间?PIPLINE的使用

    合理的使用缓存策略对开发同学来讲,就好像孙悟空习得自在极意功一般~ 抛出问题 Redis如何批量设置过期时间呢? 不要说在foreach中通过set()函数批量设置过期时间 给出方案 我们引入redi ...

  10. Coolify系列01- 从0到1超详细手把手教你上手Heroku 和 Netlify 的开源替代方案

    什么是Coolify 一款超强大的开源自托管 Heroku / Netlify 替代方案 coolLabs是开源.自托管和以隐私为中心的应用程序和服务的统称 为什么使用Coolify 只需单击几下即可 ...