@Apiimplicitparams là gì

目录

入门部分

1.Spring Boot 简介

2.微服务

3.环境准备

4.Maven配置

5.IDEA配置

6.修改Banner

7.使用IDEA创建一个项目

8.添加Banner文件

9.创建Controller类

10.一个方法映射多个URL地址

11.窄化请求

12.其他创建方式

13.其他运行方式

讲原理部分

1、从POM文件讲原理

2、启动器

3、主程序类,主入口类

4、自动配置原理

参数传递

1.get方式Url传参:

2.get方式Url传参:

3.get方式Url传参:

4.POST方式传递数据

5.POST传递字符串文本

6.@requestbody接收参数

SwaggerAPI框架

1.添加依赖

2.Swagger配置

3.使用注解

4.Webjars的使用

springboot-配置文件的使用

1、配置文件的使用

2、切换配置文件

1、多配置文件

2、单配置文件[分块]

3、激活指定profile

4、配置文件加载位置

springboot-配置文件详解

1.YML是什么

2.YML语法

字面量

对象、Map

数组

springboot-配置文件的注入

1、单值注入

2、批量注入

3、两种注入的区别

4、注入值的数据校验

springboot-其他配置文件

1、@PropertySource

2、@ImportResource

3、@Bean

4、配置文件占位符

入门部分

1.Spring Boot 简介

简化Spring应用开发的一个框架;

整个Spring技术栈的一个大整合;

J2EE开发的一站式解决方案;

spring官网

2.微服务

2014,martin fowler

微服务:架构风格(服务微化)

一个应用应该是一组小型服务;可以通过HTTP的方式进行互通;

单体应用:ALL IN ONE

微服务:每一个功能元素最终都是一个可独立替换和独立升级的软件单元;

3.环境准备

SpringBoot2.0环境约束

  • jdk1.8+;java version 1.8.0_112
  • maven 3.3+;Apache Maven 3.5.4
  • A favorite text editor or IDE:IntelliJ IDEA 2018.2.6
  • SpringBoot 2.1.1.RELEASE

4.Maven配置

给$M2_HOME\conf\settings.xml配置文件t添加如下内容

  • 在之间添加如下内容
  • 作用:国内maven仓库镜像[众所周知的原因国内不能很好的访问maven中央仓库]
alimaven aliyun maven //maven.aliyun.com/nexus/content/groups/public/ central
  • 在之间添加如下内容
  • 作用:指定项目编译运行使用的JDK版本
jdk-1.8 1.8 true 1.8 1.8 1.8 accp accp //192.168.1.48:8081/repository/accp/ true true

5.IDEA配置

整合Maven进来

6.修改Banner

1 2 3 4 5 6 7 8 9 10 ${AnsiColor.BLUE} _______ _______ ______ | || || | |____ || ___|| _ | ____| || |___ | | | | | ______|| ___|| |_| | | |_____ | |___ | | |_______||_______||______| -----版本号-----${spring-boot.version}

文字Banner可以从这个网站生成[有很多种字体样式可以选择]

//patorjk.com/software/taag

${AnsiColor.BLUE} 表示Banner文字的颜色

${spring-boot.version} 当前使用的SpringBoot版本

7.使用IDEA创建一个项目

  • 目录结构说明
    • src/main/java: Java代码的目录
    • src/main/resources: 资源目录
    • src/test/java: 测试代码的目录
    • src/test/resources: 测试资源目录
  • POM文件说明

8.添加Banner文件

在resources目录下创建banner.txt文件,添加以下内容

可以更换成你自己的banner

${AnsiColor.BLUE} _______ _______ ______ | || || | |____ || ___|| _ | ____| || |___ | | | | | ______|| ___|| |_| | | |_____ | |___ | | |_______||_______||______| -----版本号-----${spring-boot.version}

9.创建Controller类

  • 文件模板修改

package com.example.demo.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class HelloWorld { @RequestMapping[value = "/hello", method = RequestMethod.GET] @ResponseBody //不加这行注解返回的是字符串其实是一个逻辑的说明,拼接了前缀后缀去找真正的视图,要想返回文本就需要加上这个注解 public String hello[] { return "hello SpringBoot"; } }

直接右上角运行

访问//localhost:8080/hello

  • 注解的方式还有一种,和上面的效果一样

如果这个类下面的所有方法都是加了@ResponseBody注解,我们可以把@Controller@ResponseBody去掉,仅使用@RestController注解

package com.example.demo.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloWorld { @RequestMapping[value = "/hello", method = RequestMethod.GET] public String hello[] { return "hello SpringBoot"; } }
  • 还可以简化

如果我们使用的是@RequestMapping的GET请求可以简化使用@GetMapping注解

package com.example.demo.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloWorld { @GetMapping["/hello"] public String hello[] { return "hello SpringBoot"; } }

注解说明:

@RestController: 处理http请求:等同于@Controller+@ResponseBody @RequestMapping: value = "访问的路由" method = 请求方法 @GetMapping:以GET方式请求 相当于对@RequestMapping配置的缩写

10.一个方法映射多个URL地址

package com.example.demo.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloWorld { @GetMapping[{"/hello", "/hi"}] //注意这里的{} public String hello[] { return "hello SpringBoot"; } }

//localhost:8080/hello

//localhost:8080/hi

11.窄化请求

  • 类和方法都有value时,访问的地址是类上的地址拼接上方法上的地址。

package com.example.demo.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping["/user"]//这个地址就叫做窄化请求 public class HelloWorld { @GetMapping["/hello"] public String hello[] { return "hello SpringBoot"; } }

//localhost:8080/user/hello

12.其他创建方式

  • SPRING INITIALIZR:通过IDEA或者STS工具创建INITIALIZR项目(上面所写的项目创建就是这样)
  • 创建Maven项目手动添加依赖
  • 通过//start.spring.io/生成定制项目

下面我们演示,创建Maven项目手动添加依赖

手动添加依赖

启动类需要自己手动编写,类名叫什么无所谓,但是必须添加一个注解叫@SpringBootApplication,然后在写一个main方法,

然后再编写一下他的控制器类,跟之前我们写的一样

启动,启动完成后会扫描的类

下面我们演示,通过//start.spring.io/生成定制项目

最后会下载一个ZIP包,我们可以解压到桌面然后通过IDEA导入这个项目

选择刚才解压的文件夹,一直下一步就行了

然后跟之前一样分开写类也可以跟下面一样写一起。

13.其他运行方式

  • 在IDE中直接运行
  • 发布Jar包运行

在pom/xml文件引用插件

org.springframework.boot spring-boot-maven-plugin

导入这个maven插件,利用idea打包,

生成的jar包,可以使用java -jar xxx.jar启动

Spring Boot 使用嵌入式的Tomcat无需再配置Tomcat

讲原理部分

1、从POM文件讲原理

父项目

org.springframework.boot spring-boot-starter-parent 2.1.1.RELEASE

spring-boot-starter-parent他的父项目是:

org.springframework.boot spring-boot-dependencies 2.1.1.RELEASE ../../spring-boot-dependencies

这是真正管理Spring Boot应用里面所依赖的版本

Spring Boot的版本仲裁中心;

以后我们导入依赖默认是不需要写版本;

(没有在dependencies里面管理的依赖自然需要声明版本号)

太多了就放两张图感受一下就行啦。

2、启动器

org.springframework.boot spring-boot-starter-web

我们去他的官网看一下

spring-boot-starter-web

spring-boot-starter:spring-boot场景启动器,帮我们导入了web模块正常运行所依赖的组件;

点击进去可以看到帮我们引入很多web相关的依赖

Spring Boot将所有的功能场景都抽取出来,做成一个个的starters(启动器),只需要在项目里面引入这些starter相关场景的所有依赖都会导入进来,要用什么功能就导入什么场景的启动器

3、主程序类,主入口类

@SpringBootApplication public class DemoApplication { public static void main[String[] args] { SpringApplication.run[DemoApplication.class, args]; } }

@SpringBootApplication: Spring Boot应用标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot就应该运行这个类的main方法来启动SpringBoot应用;

点进去这个注解可以看到下面的源码

@Target[ElementType.TYPE] @Retention[RetentionPolicy.RUNTIME] @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan[excludeFilters = { @Filter[type = FilterType.CUSTOM, classes = TypeExcludeFilter.class], @Filter[type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class] }] public @interface SpringBootApplication {
  • @SpringBootConfiguration: Spring Boot的配置类,标注在某个类上,表示这是一个Spring Boot的配置类
  • @Configuration: 配置类上来标注这个注解,配置类也是容器中的一个组件@Component
  • @EnableAutoConfiguration:开启自动配置功能

点击@SpringBootConfiguration可以看到下面的源码,这是SpringBoot的底层的注解叫@Configuration,之前我们在使用Spring的时候会出现大量的XML文件,后来在使用SpringBoot之后推荐我们使用类+注解的形式来使用配置,就再也不会出现大量的XML文件了,所以某些类要是做配置类必须加上@Configuration来标注他是配置类

点击@EnableAutoConfiguration可以看到下面的源码

  • 将主配置类(@SpringBootApplication标注的类 )的所在包及下面所有子包里面的所有组件都可以扫描到Spring容器;

下面我们做个试验

可以看到在启动类和控制器类在不同的包下面,那么我们在访问控制器类发现找不到了

所以我们一般会把启动类放在外层

  • 调用了SpringFactoriesLoader.loadFactoryNames[EnableAutoConfiguration.class,classLoader];
  • Spring Boot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中,自动配置类就生效,帮我们进行自动配置工作;

  • 以前我们需要自己配置的东西,自动配置类都帮我们;
  • 有了自动配置类,免去了我们手动编写配置注入功能组件等的工作;
  • J2EE的整体整合解决方案和自动配置都在spring-boot-autoconfigure-1.5.9.RELEASE.jar;

4、自动配置原理

1)、SpringBoot启动的时候加载主配置类,开启了自动配置功能 @EnableAutoConfiguration

2)、@EnableAutoConfiguration 作用:

  • 利用EnableAutoConfigurationImportSelector给容器中导入一些组件?

  • 可以查看selectImports[]方法的内容;

  • List configurations = getCandidateConfigurations[annotationMetadata, attributes];获取候选的配置

SpringFactoriesLoader.loadFactoryNames[] 扫描所有jar包类路径下 META-INF/spring.factories 把扫描到的这些文件的内容包装成properties对象 从properties中获取到EnableAutoConfiguration.class类(类名)对应的值,然后把他们添加在容器中

将类路径下 META-INF/spring.factories 里面配置的所有EnableAutoConfiguration的值加入到了容器中

精髓:

1)、SpringBoot启动会加载大量的自动配置类

2)、我们看我们需要的功能有没有SpringBoot默认写好的自动配置类;

3)、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件有,我们就不需要再来配置了)

4)、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们就可以在配置文件中指定这些属性的值;

xxxxAutoConfigurartion:自动配置类[给容器中添加组件]; xxxxProperties:封装配置文件中相关属性;

参数传递

参数传递可以说是服务端和外界沟通的主要方式
本段内容包括:

通过url传参 |---get方式Url传参 |---@PathVariable 即:url/id/1994 形式 |---@RequestParam 即:url?username=zed形式 |---POST方式传参 |---@RequestParam |---请求体中加入文本 配置文件传参

1.get方式Url传参:

@PathVariable 路径传参,可以在路径上拼接参数的

package com.example.demo.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @GetMapping["/hello/{name}"] public String hello[@PathVariable["name"] String name] { // 最后一个name是形参name,名字可以随意,但是前两个要保持一致 return "hello " + name; } }

  • 访问://localhost:8080/hello/jenrey

2.get方式Url传参:

@RequestParam

如果请求参数的名字跟方法中的形参名字一致可以省略@RequestParam[name]

package com.example.demo.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @GetMapping["/hello"] public String hello[@RequestParam["name"] String name] { System.out.println["获取到的name是:" + name]; return "hello " + name; } }

  • 访问://localhost:8080/hello?name=jenrey

如果请求参数的名字跟方法中的形参名字一致可以省略@RequestParam[name],如下

package com.example.demo.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @GetMapping["/hello"] public String hello[String name] { System.out.println["获取到的name是:" + name]; return "hello " + name; } }

3.get方式Url传参:

@RequestParam+默认参数

package com.example.demo.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @GetMapping["/hello"] public String hello[@RequestParam[value = "name", defaultValue = "admin"] String n] { System.out.println["获取到的name是:" + n]; return "hello " + n; } }

注意:如果没有指定默认值,并且没有传递参数将会报错

Required String parameter 'name' is not present:name参数没有提供

  • 解决方案
    • 1.defaultValue = xxx:使用默认值
    • 2.required = false:标注参数是非必须的
package com.example.demo.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @GetMapping["/hello"] public String hello[@RequestParam[value = "name", required = false] String n] { System.out.println["获取到的name是:" + n]; return "hello " + n; } }

4.POST方式传递数据

package com.example.demo.controller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { Logger log = LoggerFactory.getLogger[HelloController.class]; @PostMapping["/hello"] public String add[@RequestParam["name"] String name, @RequestParam["age"] Integer age] { log.info[name + " " + age]; log.info[age.getClass[].getSimpleName[]]; //打印age的类型,可以自动帮我们转的 return "name:" + name + "\nage:" + age; } }

因为POST请求不好通过浏览器模拟,所以我们使用Postman软件来实现

5.POST传递字符串文本

通过HttpServletRequest获取输入流

package com.example.demo.controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import java.io.IOException; @RestController public class HelloController { @PostMapping["/postString"] public String postString[HttpServletRequest request] { ServletInputStream is = null; StringBuilder sb = null; try { is = request.getInputStream[]; //所有请求体中的内容会封装到request上。 sb = new StringBuilder[]; byte[] buf = new byte[1024]; int len = 0; while [[len = is.read[buf]] != -1] { sb.append[new String[buf, 0, len]]; } System.out.println[sb.toString[]]; return sb.toString[]; } catch [IOException e] { e.printStackTrace[]; } finally { try { if [is != null] { is.close[]; } } catch [IOException e] { e.printStackTrace[]; } } return sb.toString[]; } }

6.@requestbody接收参数

  • @requestbody可以接收GET或POST请求中的参数
  • 把json作为参数传递,要用【RequestBody】
  • 附带着说一下使用postman方式设置content-type为application/json方式测试后台接口

下面是User的pojo类

package com.example.demo.pojo; public class User { private String username; private String age; public String getUsername[] { return username; } public void setUsername[String username] { this.username = username; } public String getAge[] { return age; } public void setAge[String age] { this.age = age; } } package com.example.demo.controller; import com.example.demo.pojo.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { Logger log = LoggerFactory.getLogger[HelloController.class]; @PostMapping["/user"] public String user[@RequestBody User user] { log.info[user.toString[]]; return null; } }

SwaggerAPI框架

为了方便上面的API接口调试,我们可以使用:

  • Postman:模拟POST请求
  • Swagger:描述和测试API接口

1.添加依赖

io.springfox springfox-swagger2 2.9.2 io.springfox springfox-swagger-ui 2.9.2 org.projectlombok lombok 1.18.4 provided

2.Swagger配置

yml配置文件

swagger: title: SpringBoot学习 description: SpringBoot快速入门 version: 1.0.0 name: jenrey url: //jenrey.csdn.net email:

新建一个config包,下面新建一个SwaggerConfig.java文件,内容如下

package com.example.demo.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration //配置类必须要加这个注解 @EnableWebMvc //必须加上 @EnableSwagger2 //必须加上 @ConfigurationProperties[prefix = "swagger"] //把yml里面的基本信息导入到我们的配置类中,并制定前缀 @Data //因为我们是API接口文档它必须要扫描控制器层,而控制器这些类在哪个包下面我们必须指定一下,通过一个组件扫描指定一下控制器所在的包 @ComponentScan[basePackages = {"com.example.demo.controller"}] public class SwaggerConfig { private String title; //下面这些值我们直接在配置文件里面去写 private String description; private String version; private String name; private String url; private String email; @Bean //用注解的方式创建的Bean,生成的Bean是放到容器里面了,生成一个docker,docker要配置一个API的基本信息info public Docket customDocket[] { return new Docket[DocumentationType.SWAGGER_2].apiInfo[apiInfo[]]; } private ApiInfo apiInfo[] { Contact contact = new Contact[name, url, email]; //然后基本信息里面有个联系人,需要联系人的姓名,url地址,邮箱 return new ApiInfoBuilder[] //返回一个ApiInfoBuilder .title[title] .description[description] .contact[contact] .version[version] .build[]; //是用创建者方式调用build方法,帮我们返回一个ApiInfo给它放到容器里面 } }

新建一个WebMvcConfig.java文件,写入下面代码

package com.example.demo.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration class WebMvcConfig implements WebMvcConfigurer { public void addResourceHandlers[ResourceHandlerRegistry registry] { registry.addResourceHandler["swagger-ui.html"] .addResourceLocations["classpath:/META-INF/resources/"]; registry.addResourceHandler["/webjars/**"] .addResourceLocations["classpath:/META-INF/resources/webjars/"]; } }

上面两个写好了之后就可以使用Swagger注解了,比如我们写一个控制类,来测试一下Swagger

3.使用注解

在控制器API上添加接口描述的注解

package com.example.demo.controller; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController @Api[value = "用户模块的控制器"]//注释这个类是干嘛的,我们使用Swagger下面的@Api注解 public class HelloSwagger { Logger log = LoggerFactory.getLogger[HelloSwagger.class]; @GetMapping["/hello"] @ApiOperation[value = "测试Swagger"] //描述接口作用的 /* @ApiImplicitParams[ {@ApiImplicitParam[],@ApiImplicitParam[]} ] //有多参数用这个 */ public String hello[] { return "hello SpringBoot-Swagger"; } }

然后我们运行一下SpringBoot

输入上述的地址可以看到是Swagger的描述信息

//localhost:8080/v2/api-docs

//localhost:8080/swagger-ui.html

Swagger的具体用法,请参照B站Swagger视频

4.Webjars的使用

其实就是把我们常用的一些,像jquery,BootStrap等组件都有Webjars的引入方式

官网://www.webjars.org/

把下面的配置写的pom中其实就是在我们的项目中添加了jquery

org.webjars jquery 3.3.1-1

通过jar包的方式引入了jQuery

再浏览器中可以通过如下地址访问到

//localhost:8080/webjars/jquery/3.3.1-1/jquery.js

地址说明:/webjars/jquery/3.3.1-1/jquery.js

对应上面的 webjars/ artifactId/version/文件名

可以到项目中的jar包中具体查看。

所以我们通过这样的一个路径就可以请求到JQ了,是一种通过jar包来引入的方式,并不是向之前一样从官网或者其他地方下载一个JQ添加到我们的项目工程资源路径下。现在根本不需要了,直接引入jar包

springboot-配置文件的使用

1、配置文件的使用

修改配置方式1:src\main\resources\application.properties**

#修改端口号 server.port=8081 #端口号后需额外添加字符 server.servlet.context-path=/demo
  • 访问://localhost:8081/demo/hello
@RestController public class HelloWorld { @GetMapping["/hello"] public String say[] { return "HelloWorld!"; } }

修改配置方式2:src\main\resources\application.yml

server: port: 8081 servlet: context-path: /zed

个人比较喜欢yml

2、切换配置文件

1、多配置文件

src\main\resources\application-dev.yml

server: port: 8081

src\main\resources\application-prod.yml

server: port: 8080

src\main\resources\application.yml

  • 根据active:来切换配置文件
spring: profiles: active: prod

注意active后面写那个就是激活那个配置文件

2、单配置文件[分块]

  • 在单一文件中,可用连续三个连字号()区分多个文件。
  • 根据active:来切换配置文件
server: port: 8081 spring: profiles: prod --- server: port: 8080 spring: profiles: dev --- spring: profiles: active: prod

spring profiles是配置块的名称。

3、激活指定profile

​ 1、在配置文件中指定 spring.profiles.active=dev

​ 2、命令行:

​ java -jar ***.jar spring.profiles.active=dev

​ 可以直接在测试的时候,配置传入命令行参数

​ 3、虚拟机参数,在IDEA或Eclipse中的run configuration中可以进行配置

​ -Dspring.profiles.active=dev

4、配置文件加载位置

springboot 启动后扫描以下位置的application.properties或者application.yml文件,

作为Spring boot的默认配置文件

位置说明
file:./config/项目目录下的config
file:./项目目录下
classpath:/config/resources目录下的config
classpath:/resources目录下

优先级由高到底,高优先级的配置会覆盖低优先级的配置;

SpringBoot会从这四个位置全部加载主配置文件;互补配置

我们还可以通过spring.config.location来改变默认的配置文件位置

项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;

指定配置文件和默认加载的这些配置文件共同起作用形成互补配置;

java -jar ***.jar spring.config.location=E:/application.yml

从spring的运行日志中可以看到:

Loaded config file 'file:./config/application.yml' [file:./config/application.yml] Loaded config file 'file:./application.yml' [file:./application.yml] Loaded config file 'file:/C:/Users/Administrator/Desktop/demo3/target/classes/config/application.yml' [classpath:/config/application.yml] Loaded config file 'file:/C:/Users/Administrator/Desktop/demo3/target/classes/application.yml' [classpath:/application.yml]

配置文件的加载顺序:

  • ./config/application.yml 项目目录下的config目录下的配置文件
  • ./application.yml 项目目录下的配置文件
  • classpath:/config/application.yml 资源路径下的config 目录下的配置文件
  • classpath:/application.yml 资源路径下的配配置文件

总结:

  1. 先加载的优先级最高,后面的优先级低。
  2. 后面的配置文件中如果有不同的配置项,也会读取进来。

springboot-配置文件详解

1.YML是什么

SpringBoot使用一个全局的配置文件,配置文件名是固定的;

  • application.properties
  • application.yml

配置文件的作用:修改SpringBoot自动配置的默认值;

YAML(YAML Aint Markup Language)

YAML A Markup Language:是一个标记语言

YAML isnt Markup Language:不是一个标记语言

标记语言:

以前的配置文件;大多都使用的是xxx.xml文件;

YAML:以数据为中心,比json、xml等更适合做配置文件;

  • YAML:配置例子
server: port: 8081
  • XML:配置例子
8081

2.YML语法

k:[空格]v:表示一对键值对(空格必须有);

空格的缩进来控制层级关系;只要是左对齐的一列数据,都是同一个层级的

server: port: 8081 path: /hello

属性和值也是大小写敏感;

字面量

普通的值(数字,字符串,布尔)

k: v 字面量直接来写

字符串默认不用加上单引号或者双引号; "":双引号;不会转义字符串里面的特殊字符;特殊字符会作为本身想表示的意思 name: "zhangsan \n lisi":输出;zhangsan 换行 lisi '':单引号;会转义特殊字符,特殊字符最终只是一个普通的字符串数据 name: zhangsan \n lisi:输出;zhangsan \n lisi

总结:

对于字串的值,直接写和加上单引号的效果是一样,字串的内容原样输出,如果要使用特殊的字符的功能,需要加上双引号,比如说:\n如果是再双引号中的就作为换行了。

对象、Map

(属性和值)(键值对):

k: v:在下一行来写对象的属性和值的关系;注意缩进

​ 对象还是k: v的方式

friends: lastName: zhangsan age: 20

行内写法:

friends: {lastName: zhangsan, age: 18}

数组

(List、Set):

用 - 值表示数组中的一个元素

pets: - cat - dog - pig

行内写法

pets: [cat, dog, pig]

springboot-配置文件的注入

1、单值注入

使用@Value注解注入单个属性的值

  • yml配置文件
swagger: title: SpringBoot学习 description: SpringBoot快速入门 version: 1.0.0 name: jenrey url: //jenrey.csdn.net email: #server: # #端口号 # port: 8888 person: name: jenrey age: 24
  • java代码
package com.example.demo.controller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class ValueTest { @Value["${person.name}"] private String name; @Value["${person.age}"] private String age; Logger log = LoggerFactory.getLogger[ValueTest.class]; @GetMapping["/value"] public String user[] { log.info["name=" + name + ",age=" + age]; return "Hello 配置文件参数注入"; } }

${key} :来引用属性文件中key对应的值

2、批量注入

使用@ConfigurationProperties注解批量注入配置文件中的多个值

  • yml配置文件
person: lastName: 大汤圆 age: 18 boss: false birth: 2017/12/12 maps: {k1: v1, k2: 12} lists: - 张三 - 李四 dog: name: 小奶狗 age: 2

@Data是一个lomlok插件,免去了getter/setter和toString这些繁琐的东西

在POM文件的节点中间添加

org.projectlombok lombok 1.18.4 provided
  • 新建一个Person的Pojo类,代码如下
package com.example.demo.pojo; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import java.util.Date; import java.util.List; import java.util.Map; //封装配置文件中person中的数据 @ConfigurationProperties[prefix = "person"] @Component @Data public class Person { private String lastName; private Integer age; private Boolean boss; private Date birth; private Map maps; private List lists; private Dog dog; }
  • 新建一个Dog的Pojo类,代码如下
package com.example.demo.pojo; import lombok.Data; @Data public class Dog { private String name; private Integer age; }

使用@ConfigurationProperties注解必须同时添加@Component将当前的配置类放入IOC容器中

在编写yml文件的时候没有出现属性提示:

我们可以导入配置文件处理器,以后编写配置就有提示了

org.springframework.boot spring-boot-configuration-processor true

发现变成了下面的灰色

我们重新启动IDEA,点击一下 隐藏通知 就行啦。

  • 测试代码
package com.example.demo.controller; import com.example.demo.pojo.Person; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class ConfigurationPropertiesTest { Logger log = LoggerFactory.getLogger[ConfigurationPropertiesTest.class]; //把容器里的装配进来 @Autowired private Person person; @GetMapping["/test"] public String hello[] { log.info[person.toString[]];//toString[]方法我们不用写,@Data自动帮我们写了 return "hello"; } }
  • 控制台的输出
Person[lastName=大汤圆, age=18, boss=false, birth=Tue Dec 12 00:00:00 CST 2017, maps={k1=v1, k2=12}, lists=[张三, 李四], dog=Dog[name=小奶狗, age=2]]

javaBean:

  • 将配置文件中配置的每一个属性的值,映射到这个组件中
  • @ConfigurationProperties:告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定;
  • prefix = person:配置文件中哪个下面的所有属性进行一一映射
  • 只有这个组件是容器中的组件,才能使用容器提供的@ConfigurationProperties功能;
  • @Data是一个插件,,免去了getter/setter和toString这些繁琐的东西

3、两种注入的区别

@Value获取值和@ConfigurationProperties获取值的区别

@ConfigurationProperties@Value
功能批量注入配置文件中的属性一个个指定
松散绑定(松散语法)支持不支持
SpEL: #{}不支持支持
JSR303数据校验支持不支持
复杂类型封装支持不支持

松散语法绑定:last_name = last-name = lastName 他们取的值都是相同的

配置文件yml还是properties他们都能获取到值;

总结:

  • 如果说,我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value;
  • 如果说,我们专门编写了一个javaBean来和配置文件进行映射,我们就直接使用@ConfigurationProperties;

4、注入值的数据校验

@ConfigurationProperties[prefix = "person"] @Component @Data @Validated //数据校验 public class Person { @Email[message = "用户名必须是一个正确的邮箱格式"] private String lastName; @Max[value = 200,message = "年龄不能超过200岁"] @Min[value = 0,message = "年龄必须大于0岁"] private Integer age; private Boolean boss; private Date birth; private Map maps; private List lists; private Dog dog; }

经过刚才的测试得出,两个注解不能同时作用在一个属性上。

springboot-其他配置文件

1、@PropertySource

@PropertySource:加载指定的配置文件;

@PropertySource[value = {"classpath:person.properties"}] @Component @ConfigurationProperties[prefix = "person"] public class Person { // lastName必须是邮箱格式 // @Email // @Value["${person.last-name}"] private String lastName; // @Value["#{11*2}"] private Integer age; // @Value["true"] private Boolean boss;

请注意 [字串,bool,时间,列表可以注入],map不能注入,

简单的数据类型Spring注入数据后进行了类型转换

断点查看可以知道注入的数据

person.lastName= person.age=18 person.boss=false person.birth=2017/12/12 person.lists=lisi,zhaoliu People[lastName=, age=18, pets=null, boss=false, birth=Tue Dec 12 00:00:00 CST 2017, lists=[[lisi, zhaoliu]]]

IDEA设置*.properties文件的默认编码

Settings
>Editor
>File Encoding
>Properties Files[*.properties]
>Default encoding for properties files:UTF-8
>OK

2、@ImportResource

@ImportResource:导入Spring的配置文件,让配置文件里面的内容生效;

想让Spring的配置文件生效,@ImportResource标注在一个配置类上

@ImportResource[locations = {"classpath:beans.xml"}] @SpringBootApplication public class SpringbootApplication { public static void main[String[] args] { SpringApplication.run[SpringbootApplication.class, args]; } }
  • Spring的配置文件
  • 测试
@RunWith[SpringRunner.class] @SpringBootTest public class Demo7ApplicationTests { @Autowired ApplicationContext ioc; @Test public void contextLoads[] { boolean p123 = ioc.containsBean["p123"]; System.out.println[p123]; } }

3、@Bean

SpringBoot推荐使用全注解的方式给容器中添加组件

1、配置类@Configuration> Spring配置文件

2、使用@Bean给容器中添加组件

/** * @Configuration:指明当前类是一个配置类;就是来替代之前的Spring配置文件 * 在配置文件中用标签添加组件 */ @Configuration public class MyAppConfig { // 将方法的返回值添加到容器中;容器中这个组件默认的id就是方法名 @Bean public HelloService helloService02[]{ System.out.println["配置类@Bean给容器中添加组件了..."]; return new HelloService[]; } }

测试:

@Test public void testHelloService[] { boolean b = ioc.containsBean["helloService02"]; System.out.println[b]; // true }

输出:配置类@Bean给容器中添加组件了 同时返回true

4、配置文件占位符

  • 随机数
${random.value}、${random.int}、${random.long} ${random.int[10]}、${random.int[1024,65536]}
  • 占位符获取之前配置的值

如果没有可以使用的:指定默认值

person.last-name=张三${random.uuid} person.age=${random.int} person.birth=2017/12/15 person.boss=false person.maps.k1=v1 person.maps.k2=14 person.lists=a,b,c # 没有取到:后面是默认值 person.dog.name=${person.hello:hello}_dog person.dog.age=15

Linux下vim的配置,原文地址://blog.csdn.net/luckytanggu/article/details/52045357

一、安装vundle

$ git clone //github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim
  • 1
  • 1

默认安装在/.vim/bundle/vundle下;


安装v undle

$ git clone //github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim
  • 1
  • 1

默认安装在/.vim/bundle/vundle下;

安装vundle

$ git clone //github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim
  • 1
  • 1

默认安装在/.vim/bundle/vundle下;

安装vundle

$ git clone //github.com/V

二、创建vimrc(vim的配置文件)

可以直接克隆我的vim配置文件到你的本地

git clone :Tangugo/vim.git

把.vimrc配置文件拷贝到~/目录下

cp vim/.vimrc ~/

注:前面带点.的文件是隐藏文件,需ls -la才能查看到

vim配置文件一般分为以下四部分:

  • 加载vim的相关插件[vim插件大全]
  • vim的常规设置
  • vim插件的设置
  • 键盘中一些键的功能重新映射其他键或组合键上[例如Esc退出插入模式映射到jj组合键]

三、安装插件让.vimrc配置文件生效

按以下步骤操作

vim
:PluginInstall

安装插件需要一定的时间,跟网速有关,喝杯茶等待

四、Vim 自动补全插件 YouCompleteMe 安装与配置a

可以参考//howiefh.github.io/2015/05/22/vim-install-youcompleteme-plugin/

1、安装

确保Vim版本至少是7.3.584,并且支持python2脚本

cd ~/.vim/bundle/YouCompleteMe
./install.py

需要支持C语言的话

./install.py clang-completer

2、拷贝配置文件

cp third_party/ycmd/cpp/ycm/.ycm_extra_conf.py ~/

3、修改配置文件,在flags部分后添加如下内容:

-isystem,
/usr/include,

在.vimrc中设定 YouCompleteMe配置[第二部克隆vimrc文件,该vimrc已指定了]

let g:ycm_global_ycm_extra_conf = ~/.ycm_extra_conf.py

五、安装完后我的补全遇到如下问题:

在写代码时,每当输入.就提示ConnectionError错误提示[如输入:os.],到/tmp/ycm_temp目录下查看日志文件,提示如下错误:

Traceback [most recent call last]: File "/home/zhu/.vim/bundle/YouCompleteMe/third_party/ycmd/third_party/JediHTTP/jedihttp.py", line 23, in from waitress import serve ImportError: No module named waitress
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

发现报错源,顺藤摸瓜,于是到PyPi[几乎所有Python的第三方库在此处都能找到]查找waitress模块,下载安装后,完美解决了代码补全出现的问题

waitress安装:

tar -zxvf waitress-1.0a2.tar.gz
cd waitress-1.0a2
python setup.py install # 注:非root用户需在命令前加上sudo

安装完后vim就变得无比强大绚丽了,看截图

以下是我的vimrc配置文件

" ************* Vundle 配置 **************** filetype off " 侦测文件类型 set rtp+=~/.vim/bundle/Vundle.vim call vundle#begin[] " Vundle.vim : vim的一个非常好用的插件管理器 Bundle 'gmarik/Vundle.vim' " 更酷的启动界面 "Bundle 'mhinz/vim-startify' " 协作编程 "Bundle 'FredKSchott/CoVim' " 代码补全 Bundle 'Valloric/YouCompleteMe' Bundle 'SirVer/ultisnips' Bundle 'honza/vim-snippets' Bundle 'YanhaoMo/snippets' " Python代码补全 "Bundle 'Pydiction' " 符号自动补全 Bundle 'Raimondi/delimitMate' " 文件搜索 Bundle 'kien/ctrlp.vim' Bundle 'Shougo/unite.vim' Bundle 'scrooloose/nerdtree' Bundle 'vim-scripts/mru.vim' " 静态语法检查 Bundle 'scrooloose/syntastic' " 代码浏览 Bundle 'majutsushi/tagbar' " git支持 Bundle 'tpope/vim-fugitive' Bundle 'airblade/vim-gitgutter' " 美化主题 Bundle 'tomasr/molokai' Bundle 'morhetz/gruvbox' Bundle 'kien/rainbow_parentheses.vim' Bundle 'bling/vim-airline' "Bundle 'vim-airline-themes' Bundle 'nathanaelkane/vim-indent-guides' Bundle 'solarized' Bundle 'jpo/vim-railscasts-theme' "Bundle 'altercation/vim-colors-solarized.git' "Bundle 'fholgado/minibufexpl.vim' " 代码bug追踪 Bundle 'ZenCoding.vim' " 编辑增强 " 多光标操作 Bundle 'terryma/vim-multiple-cursors' " 成对符号编辑 Bundle 'tpope/vim-surround' Bundle 'tpope/vim-unimpaired' " 快速注释 Bundle 'scrooloose/nerdcommenter' " 自动对齐 Bundle 'godlygeek/tabular' " 快速移动 Bundle 'Lokaltog/vim-easymotion' " 代码块对齐用 Bundle 'Yggdroot/indentLine' " 增强状态栏 Bundle 'rstatusline' " tmux支持 Bundle 'benmills/vimux' " c/c++ Bundle 'vim-scripts/a.vim' Bundle 'vim-scripts/c.vim' " org-mode Bundle 'jceb/vim-orgmode' Bundle 'tpope/vim-speeddating' " markdown Bundle 'plasticboy/vim-markdown' " 可以通过浏览器实时预览,但是要安装额外依赖,详见官网 "Bundle 'suan/vim-instant-markdown' " 网页开发 Bundle 'mattn/emmet-vim' " pyhon Bundle 'klen/python-mode' "Bundle 'python-imports.vim' " js Bundle 'coolwanglu/vim.js' " golang "Bundle 'fatih/vim-go' " 用ack代替grep搜索 Bundle 'mileszs/ack.vim' "bundle 'vimwiki/vimwiki' "Bundle 'vim-scripts/bufexplorer.zip' "Bundle 'terryma/vim-smooth-scroll' call vundle#end[] filetype plugin on " 载入文件类型插件 filetype indent on " 为特定文件类型载入相关缩进文件 " *************** gvim配置 *************** if has["gui_running"] let $LANG='en' "设置gvim菜单栏始终显示为英文 set langmenu=en source $VIMRUNTIME/delmenu.vim source $VIMRUNTIME/menu.vim "set guifont=DejaVu\ Sans\ Mono\ for\ Powerline\ Book\ 10 set guifont=Source\ Code\ Pro\ for\ Powerline\ Regular\ 10 set guioptions-=e set guioptions-=m set guioptions-=T set guioptions-=L set guioptions-=r set guioptions-=B set guioptions-=0 set go= winpos 1000 0 "set lines=100 columns=150 " 开启时的窗口默认大小 endif " *************** vim常用的基本设置 *************** set nocompatible " 不使用vi的键盘模式,而是vim自己的 "syntax enable " 开启语法高亮功能 syntax on " 语法高亮支持 set nu " 显示行号 set rnu " 显示相对行号 set wrap " 当一行文字很长时换行 "set nowrap " 当一行文字很长时取消换行 set showmatch " 当光标移动到一个括号时高亮显示对应的另一个括号 set showcmd " 回显输入的命令 set showmode " 显示当前的模式 set clipboard+=unnamed " 关联系统的剪贴板 set ruler " 在编辑过程中右下角显示光标的行列信息 set nocp " 让Vim工作在不兼容模式下 set shortmess=atI " 启动时不显示捐助乌干达儿童的提示 set so=6 " 上下滚行时空余6行 set autoindent " 自动套用上一行的缩进方式 set smartindent " 智能缩进 set mouse=a " 开启鼠标支持 set laststatus=2 " 总是显示状态行 set backspace=indent,eol,start " 对退格键提供更好的支持 set ts=4 " 设置tab长度为4 set sts=4 " 设置制表符宽度 set shiftwidth=4 " 设置缩进空格数 set expandtab " 用空格代替tab键 set smarttab " 更加智能的tab键 set hid " 当buffer被丢弃时隐藏它 set encoding=utf-8 " 默认使用utf-8编码格式 set fileencodings=utf-8,cp936,gb18030,big5,euc-kr,latin1 " 自动判断编码时 依次尝试一下编码 set ffs=unix,dos,mac " 设置文件类型 set hlsearch " 高亮搜索内容 set ignorecase " 搜索模式里忽略大小写 set smartcase " 如果搜索字符串里包含大写字母,则禁用 ignorecase set incsearch " 显示搜索的动态匹配效果 set lazyredraw " 解决某些类型的文件由于syntax导致vim反应过慢的问题 set ttyfast " 平滑地变化 set cc=80 "80字符处显示分隔符 set foldmethod=indent " 折叠方式 set nofoldenable " 不自动折叠 set foldcolumn=1 " 在行号前空出一列的宽度 set t_Co=256 " 设置256真彩色 set history=1000 " 设置历史记录条数 "set autoread " 当文件在外部被修改时自动载入 "set cindent " 使用c语言的缩进格式 "set whichwrap+=,h,l " 允许backspace和光标键跨越行边界 "set cmdheight=2 " 显示两行命令行 set list lcs=tab:\\ ,trail: " 显示tab键为,并且显示每行结尾的空格为'' " 一些备用字符: " 格式化状态行显示的内容 set statusline=[%t]\ %y\ %m%=%{&fileencoding}\ [%{&ff}]\ [%l,\ %c]\ [%L]\ [%p%%] " 打开一个文件自动定位到上一次退出的位置 if has["autocmd"] au BufReadPost * if line["'\""] > 1 && line["'\""] %.html &" exec "!firefox %.html &" endif endfunc " C,C++的调试 map :call Rungdb[] func! Rungdb[] exec "w" exec "!g++ % -g -o % /dev/null 2>&1" " elseif &filetype == 'perl' " exec "!astyle --style=gnu --suffix=none %" " elseif &filetype == 'py'||&filetype == 'python' " exec "r !autopep8 -i --aggressive %" " elseif &filetype == 'java' " exec "!astyle --style=java --suffix=none %" " elseif &filetype == 'jsp' " exec "!astyle --style=gnu --suffix=none %" " elseif &filetype == 'xml' " exec "!astyle --style=gnu --suffix=none %" " else " exec "normal gg=G" " return " endif " exec "e! %" "endfunc " 更新cscope文件 map :!cscope -Rbq im :!cscope -Rbq " 修改的键盘映射 nmap ' " 当按下\+Enter时取消搜索高亮 map :noh " Unite插件配置 map b :Unite -winheight=10 buffer map r :MRU map f :NERDTreeToggle " Tagbar插件配置 let g:tagbar_autoclose=1 map t :TagbarToggle " 设置文件类型辅助 map s :setfiletype " 更方便的窗口间跳转 map j j map k k map l l map h h map j map k map l map h " vimux插件配置 map e :VimuxPromptCommand map x :VimuxCloseRunner map vl :VimuxRunLastCommand map vi :VimuxInspectRunner " 更方便的页滚动 map map map ,,j [easymotion-w] map ,,k [easymotion-b] map ,,s [easymotion-s] "********** 新建.c,.h,.sh,.java文件,自动插入文件头 ********** autocmd BufNewFile *.cpp,*.[ch],*.sh,*.rb,*.java,*.py exec ":call SetHead[]" "" 定义函数SetHead,自动插入文件头 func! SetHead[] if &filetype == 'sh' call setline[1,"\#!/bin/bash"] call append[line["."], ""] elseif &filetype == 'python' call setline[1,"#!/usr/bin/env python"] call append[line["."],"# -*- coding=utf-8 -*-"] call append[line["."]+1, ""] elseif &filetype == 'ruby' call setline[1,"#!/usr/bin/env ruby"] call append[line["."],"# encoding: utf-8"] call append[line["."]+1, ""] " elseif &filetype == 'mkd' " call setline[1,""] else call setline[1, "/*************************************************************************"] call append[line["."], " > File Name: ".expand["%"]] call append[line["."]+1, " > Author: "] call append[line["."]+2, " > Mail: "] call append[line["."]+3, " > Created Time: ".strftime["%c"]] call append[line["."]+4, " ************************************************************************/"] call append[line["."]+5, ""] endif if expand["%:e"] == 'cpp' call append[line["."]+6, "#include"] call append[line["."]+7, "using namespace std;"] call append[line["."]+8, ""] endif if &filetype == 'c' call append[line["."]+6, "#include"] call append[line["."]+7, ""] endif if expand["%:e"] == 'h' call append[line["."]+6, "#ifndef _".toupper[expand["%:r"]]."_H"] call append[line["."]+7, "#define _".toupper[expand["%:r"]]."_H"] call append[line["."]+8, "#endif"] endif if &filetype == 'java' call append[line["."]+6,"public class ".expand["%:r"]] call append[line["."]+7,""] endif " 新建文件后,自动定位到文件末尾 endfunc autocmd BufNewFile * normal G " ********* 实用设置 ********* if has["autocmd"] autocmd BufReadPost * \ if line["'\""] > 0 && line["'\""]

Chủ Đề