@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 http://maven.aliyun.com/nexus/content/groups/public/ central
  • 在之间添加如下内容
  • 作用:指定项目编译运行使用的JDK版本
jdk-1.8 1.8 true 1.8 1.8 1.8 accp accp http://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可以从这个网站生成(有很多种字体样式可以选择)

http://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文件说明

@Apiimplicitparams là gì

@Apiimplicitparams là gì

@Apiimplicitparams là gì

@Apiimplicitparams là gì

8.添加Banner文件

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

可以更换成你自己的banner

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

9.创建Controller类

  • 文件模板修改

@Apiimplicitparams là gì

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"; } }

直接右上角运行

@Apiimplicitparams là gì

访问http://localhost:8080/hello

@Apiimplicitparams là gì

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

如果这个类下面的所有方法都是加了@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"; } }

http://localhost:8080/hello

http://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"; } }

http://localhost:8080/user/hello

12.其他创建方式

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

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

@Apiimplicitparams là gì

手动添加依赖

@Apiimplicitparams là gì

@Apiimplicitparams là gì

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

@Apiimplicitparams là gì

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

@Apiimplicitparams là gì

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

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

@Apiimplicitparams là gì

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

@Apiimplicitparams là gì

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

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

@Apiimplicitparams là gì

13.其他运行方式

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

在pom/xml文件引用插件

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

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

@Apiimplicitparams là gì

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

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

@Apiimplicitparams là gì


讲原理部分

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里面管理的依赖自然需要声明版本号)

@Apiimplicitparams là gì

@Apiimplicitparams là gì

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

2、启动器

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

@Apiimplicitparams là gì

我们去他的官网看一下

@Apiimplicitparams là gì

@Apiimplicitparams là gì

spring-boot-starter-web

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

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

@Apiimplicitparams là gì

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来标注他是配置类

@Apiimplicitparams là gì

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

@Apiimplicitparams là gì

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

@Apiimplicitparams là gì

下面我们做个试验

@Apiimplicitparams là gì

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

@Apiimplicitparams là gì

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

@Apiimplicitparams là gì

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

@Apiimplicitparams là gì

@Apiimplicitparams là gì

  • 以前我们需要自己配置的东西,自动配置类都帮我们;
  • 有了自动配置类,免去了我们手动编写配置注入功能组件等的工作;
  • 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; } }

@Apiimplicitparams là gì

@Apiimplicitparams là gì

  • 访问:http://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; } }

@Apiimplicitparams là gì

@Apiimplicitparams là gì

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

@Apiimplicitparams là gì

@Apiimplicitparams là gì

如果请求参数的名字跟方法中的形参名字一致可以省略@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; } }

@Apiimplicitparams là gì

@Apiimplicitparams là gì

@Apiimplicitparams là gì


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; } }

@Apiimplicitparams là gì

@Apiimplicitparams là gì

@Apiimplicitparams là gì

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

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; } }

@Apiimplicitparams là gì

@Apiimplicitparams là gì

@Apiimplicitparams là gì

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软件来实现

@Apiimplicitparams là gì

@Apiimplicitparams là gì

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(); } }

@Apiimplicitparams là gì

@Apiimplicitparams là gì

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; } }

@Apiimplicitparams là gì

@Apiimplicitparams là gì


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配置

@Apiimplicitparams là gì

yml配置文件

swagger: title: SpringBoot学习 description: SpringBoot快速入门 version: 1.0.0 name: jenrey url: https://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

@Apiimplicitparams là gì

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

http://localhost:8080/v2/api-docs

@Apiimplicitparams là gì

@Apiimplicitparams là gì

http://localhost:8080/swagger-ui.html

@Apiimplicitparams là gì

@Apiimplicitparams là gì

@Apiimplicitparams là gì

@Apiimplicitparams là gì

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

4.Webjars的使用

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

官网:https://www.webjars.org/

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

org.webjars jquery 3.3.1-1

通过jar包的方式引入了jQuery

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

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

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

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

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

@Apiimplicitparams là gì

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


springboot-配置文件的使用

1、配置文件的使用

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

#修改端口号 server.port=8081 #端口号后需额外添加字符 server.servlet.context-path=/demo
  • 访问:http://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

@Apiimplicitparams là gì

总结:

对于字串的值,直接写和加上单引号的效果是一样,字串的内容原样输出,如果要使用特殊的字符的功能,需要加上双引号,比如说:\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: http://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 配置文件参数注入"; } }

@Apiimplicitparams là gì

${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容器中

@Apiimplicitparams là gì

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

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

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

发现变成了下面的灰色

@Apiimplicitparams là gì

我们重新启动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的配置,原文地址:http://blog.csdn.net/luckytanggu/article/details/52045357

一、安装vundle

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

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


安装v undle

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

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

安装vundle

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

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

安装vundle

$ git clone https://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

可以参考http://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就变得无比强大绚丽了,看截图

@Apiimplicitparams là gì


以下是我的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("'\"") <= line("$") | exe "normal! g'\"" | endif endif " 保存.vim文件后不用退出即可生效 "autocmd BufWritePost $MYVIMRC source $MYVIMRC "au! bufwritepost .vimrc source % " ************** 备份设置 **************** "set nobackup " 不进行备份 "set nowb " 重新载入文件时不要备份 "set noswapfile " 不使用swf文件,可能导致错误无法恢复 " *************** 关闭错误声音 ************** set noerrorbells set novisualbell set t_vb= " **************** 设置vim主题外观 *************** "set background=light " 设置vim背景为浅色 set background=dark " 设置vim背景为深色 set cursorline " 突出显示当前行 set cursorcolumn " 突出显示当前列 "colorscheme molokai " 设置molokai高亮主题 "colorscheme desert " 设置desert高亮主题 "let g:solarized_termcolors=256 "colorscheme solarized " 设置solarized高亮主题 "let g:gruvbox_termcolors=16 colorscheme gruvbox " 设置gruvbox高亮主题 " ************** vim的配色 ************** "hi CursorLine cterm=NONE ctermbg=237 ctermfg=NONE "hi CursorColumn cterm=NONE ctermbg=237 ctermfg=NONE hi vertsplit ctermbg=bg guibg=bg hi GitGutterAdd ctermbg=bg guibg=bg hi GitGutterChange ctermbg=bg guibg=bg hi GitGutterDelete ctermbg=bg guibg=bg hi GitGutterChangeDelete ctermbg=bg guibg=bg hi SyntasticErrorSign ctermbg=bg guibg=bg hi SyntasticWarningSign ctermbg=bg guibg=bg hi FoldColumn ctermbg=bg guibg=bg " *********** NERDTree插件配置 *********** let NERDTreeChDirMode=2 " 设置当前目录为nerdtree的起始目录 let NERDChristmasTree=1 " 使得窗口有更好看的效果 let NERDTreeMouseMode=1 " 双击鼠标左键打开文件 let NERDTreeWinSize=25 " 设置窗口宽度为25 let NERDTreeQuitOnOpen=1 " 打开一个文件时nerdtree分栏自动关闭 " *********** ctags插件配置 *********** set tags+=/usr/include/tags " ********* cscope插件配置 ********** if has("cscope") "set csprg=/usr/bin/cscope set csto=0 set cst set nocsverb set cscopequickfix=s-,c-,d-,i-,t-,e- "在quickfix窗口中显示搜索结果 " add any database in current directory if filereadable("cscope.out") cs add cscope.out " else add database pointed to by environment elseif $CSCOPE_DB != "" cs add $CSCOPE_DB endif set csverb endif " *********** nerdcommenter快速注释插件配置 ********** " Add spaces after comment delimiters by default let g:NERDSpaceDelims = 1 " Use compact syntax for prettified multi-line comments let g:NERDCompactSexyComs = 1 " Align line-wise comment delimiters flush left instead of following code indentation let g:NERDDefaultAlign = 'left' " Set a language to use its alternate delimiters by default let g:NERDAltDelims_java = 1 " Add your own custom formats or override the defaults let g:NERDCustomDelimiters = { 'c': { 'left': '/**','right': '*/' } } " Allow commenting and inverting empty lines (useful when commenting a region) let g:NERDCommentEmptyLines = 1 " Enable trimming of trailing whitespace when uncommenting let g:NERDTrimTrailingWhitespace = 1 " *********** syntastic插件配置 *********** set statusline+=%#warningmsg# set statusline+=%{SyntasticStatuslineFlag()} set statusline+=%* let g:syntastic_always_populate_loc_list = 1 let g:syntastic_auto_loc_list = 1 let g:syntastic_check_on_open = 1 let g:syntastic_check_on_wq = 1 let g:syntastic_error_symbol = '' let g:syntastic_warning_symbol = '' "let g:syntastic_cpp_include_dirs = ['/usr/include/qt'] "let g:syntastic_cpp_compiler_options = '-std=gnu++11 -Wall' let g:syntastic_mode_map = { 'mode': 'passive', 'active_filetypes': [],'passive_filetypes': [] } " ********** pydiction补全设置 ********** "let g:pydiction_location = '~/.vim/bundle/Pydiction/complete-dict' ""defalut g:pydiction_menu_height == 15 "let g:pydiction_menu_height = 10 " ********** youcompleteme自动补全配置 *********** let g:ycm_global_ycm_extra_conf = '~/.ycm_extra_conf.py' "let g:ycm_python_binary_path = 'python' set completeopt=longest,menu "让Vim的补全菜单行为与一般IDE一致(参考VimTip1228) autocmd InsertLeave * if pumvisible() == 0|pclose|endif "离开插入模式后自动关闭预览窗口 inoremap pumvisible() ? "\" : "\" "回车即选中当前项 "上下左右键的行为 会显示其他信息 inoremap pumvisible() ? "\" : "\" inoremap pumvisible() ? "\" : "\" inoremap pumvisible() ? "\\\" : "\" inoremap pumvisible() ? "\\\" : "\" " 跳转到定义处 nnoremap jd :YcmCompleter GoToDefinitionElseDeclaration nnoremap :YcmForceCompileAndDiagnostics "force recomile with syntastic " nnoremap lo :lopen "open locationlist " nnoremap lc :lclose "close locationlist inoremap " 不显示开启vim时检查ycm_extra_conf文件的信息 let g:ycm_confirm_extra_conf=0 " 开启基于tag的补全,可以在这之后添加需要的标签路径 let g:ycm_collect_identifiers_from_tags_files=1 "注释和字符串中的文字也会被收入补全 let g:ycm_collect_identifiers_from_comments_and_strings = 0 " 输入第2个字符开始补全 let g:ycm_min_num_of_chars_for_completion=2 " 禁止缓存匹配项,每次都重新生成匹配项 let g:ycm_cache_omnifunc=0 " 开启语义补全 let g:ycm_seed_identifiers_with_syntax=1 "在注释输入中也能补全 let g:ycm_complete_in_comments = 1 "在字符串输入中也能补全 let g:ycm_complete_in_strings = 1 " 设置在下面几种格式的文件上屏蔽ycm let g:ycm_filetype_blacklist = { \ 'tagbar' : 1, \ 'nerdtree' : 1, \} "youcompleteme 默认tab s-tab 和 ultisnips 冲突 let g:ycm_key_list_select_completion = [''] let g:ycm_key_list_previous_completion = [''] " 修改对C函数的补全快捷键,默认是CTRL + space,修改为ALT + ; let g:ycm_key_invoke_completion = '' " SirVer/ultisnips 代码片断 " Trigger configuration. Do not use if you use https://github.com/Valloric/YouCompleteMe. let g:UltiSnipsExpandTrigger="" let g:UltiSnipsJumpForwardTrigger="" let g:UltiSnipsJumpBackwardTrigger="" let g:UltiSnipsListSnippets="" "定义存放代码片段的文件夹,使用自定义和默认的,将会的到全局,有冲突的会提示 let g:UltiSnipsSnippetDirectories=["~/.vim/bundle/vim-snippets/UltiSnips"] " 参考https://github.com/Valloric/YouCompleteMe/issues/36#issuecomment-62941322 " 解决ultisnips和ycm tab冲突,如果不使用下面的办法解决可以参考 " https://github.com/Valloric/YouCompleteMe/issues/36#issuecomment-63205056的配置 " begin " let g:ycm_key_list_select_completion=['', ''] " let g:ycm_key_list_previous_completion=['', ''] " let g:UltiSnipsExpandTrigger="" " let g:UltiSnipsJumpForwardTrigger="" " let g:UltiSnipsJumpBackwardTrigger="" " end " UltiSnips completion function that tries to expand a snippet. If there's no " snippet for expanding, it checks for completion window and if it's " shown, selects first element. If there's no completion window it tries to " jump to next placeholder. If there's no placeholder it just returns TAB key function! g:UltiSnips_Complete() call UltiSnips#ExpandSnippet() if g:ulti_expand_res == 0 if pumvisible() return "\" else call UltiSnips#JumpForwards() if g:ulti_jump_forwards_res == 0 return "\" endif endif endif return "" endfunction au BufEnter * exec "inoremap " . g:UltiSnipsExpandTrigger . " =g:UltiSnips_Complete()" " Expand snippet or return let g:ulti_expand_res = 1 function! Ulti_ExpandOrEnter() call UltiSnips#ExpandSnippet() if g:ulti_expand_res return '' else return "\" endfunction " Set as primary trigger inoremap =Ulti_ExpandOrEnter() " ********** indentLine插件 ********** let g:indentLine_char = '' "代码块对齐用符号 " *********** UltiSnips插件配置 ********** let g:UltiSnipsExpandTrigger="" ""let g:UltiSnipsJumpForwardTrigger="" ""let g:UltiSnipsJumpBackwardTrigger="" let g:UltiSnipsEditSplit = "vertical" "let g:UltiSnipsSnippetDirectories = ["UltiSnips", "bundle/snippets"] let g:UltiSnipsSnippetDirectories = ["bundle/snippets"] " ********** rainbow_parentheses插件配置 *********** let g:rbpt_colorpairs = [ \ ['brown', 'RoyalBlue3'], \ ['Darkblue', 'SeaGreen3'], \ ['darkgray', 'DarkOrchid3'], \ ['darkgreen', 'firebrick3'], \ ['darkcyan', 'RoyalBlue3'], \ ['darkred', 'SeaGreen3'], \ ['darkmagenta', 'DarkOrchid3'], \ ['brown', 'firebrick3'], \ ['gray', 'RoyalBlue3'], \ ['black', 'SeaGreen3'], \ ['darkred', 'DarkOrchid3'], \ ['darkmagenta', 'DarkOrchid3'], \ ['Darkblue', 'firebrick3'], \ ['darkgreen', 'RoyalBlue3'], \ ['darkcyan', 'SeaGreen3'], \ ['red', 'firebrick3'], \ ] let g:rbpt_max = 16 let g:rbpt_loadcmd_toggle = 0 au VimEnter * RainbowParenthesesToggle au Syntax * RainbowParenthesesLoadRound au Syntax * RainbowParenthesesLoadSquare au Syntax * RainbowParenthesesLoadBraces " ********** vim-multiple-cursors插件配置 *********** let g:multi_cursor_use_default_mapping=0 let g:multi_cursor_next_key='' let g:multi_cursor_prev_key='' let g:multi_cursor_skip_key='' let g:multi_cursor_quit_key='' " ********** airline插件配置 *********** let g:airline_powerline_fonts=1 "配置airline使用powerline字体 "let g:airline#extensions#tabline#enabled = 1 "let g:airline#extensions#tabline#left_sep = ' ' "let g:airline#extensions#tabline#left_alt_sep = '|' " *********** vimwiki插件配置 *********** "let g:vimwiki_list = [{'path' : '~/.vimwiki/', " \'template_path' : '~/.vimwiki/template/', " \'template_default' : 'default_template', " \'template_ext' : '.html', " \'path_html': '~/.vimwiki/html/'} " \] " ********** mru插件配置 ********** let MRU_Auto_Close = 1 let MRU_Max_Entries = 40 " ************ pythom-mode ********* let g:pymode_lint_on_write = 0 let g:pymode_lint_signs = 0 let g:pymode_rope_lookup_project = 0 let g:pymode_rope = 0 let g:pymode_floding = 0 " *********** 重新映射一些键 ********** " 设置以空格打开和关闭折叠 nmap @=((foldclosed(line('.'))<0)?'zc':'zo') " 当一行很长时把分开的段行当作一行来移动 map j gj map k gk " 将Esc键映射到jj,zz im jj im JJ im zz im ZZ map zz map ZZ " quickfix相关的一些快捷键 map cop :copen map ccl :cclose map cn :cn map cp :cp " emacs式的行内跳转 map ^ map $ imap ^i imap $a " ff跳转到文件末尾 map ff G " visual模式下快速对齐 vnoremap < >gv " 关闭打开目录树 map :NERDTreeToggle imap :NERDTreeToggle " 打开树状文件目录 map \be " 生成ctags map :!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q . im :!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q . nmap go g nmap bk nmap s :cs find s =expand("") nmap g :cs find g =expand("") nmap c :cs find c =expand("") nmap t :cs find t =expand("") nmap e :cs find e =expand("") nmap f :cs find f =expand("") nmap i :cs find i ^=expand("")$ nmap d :cs find d =expand("") " 编译运行 :autocmd BufRead,BufNewFile *.dot map :w:!dot -Tjpg -o %<.jpg % && eog %<.jpg && exec "redr!" " C,C++ 按F5编译运行 map :call CompileRunGcc() func! CompileRunGcc() exec "w" if &filetype == 'c' exec "!g++ % -o %<" exec "!time ./%<" elseif &filetype == 'cpp' exec "!g++ % -o %<" exec "!time ./%<" elseif &filetype == 'java' exec "!javac %" exec "!time java %<" elseif &filetype == 'sh' :!time bash % elseif &filetype == 'python' exec "!time python2.7 %" elseif &filetype == 'html' exec "!firefox % &" elseif &filetype == 'go' " exec "!go build %<" exec "!time go run %" elseif &filetype == 'mkd' exec "!~/.vim/markdown.pl % > %.html &" exec "!firefox %.html &" endif endfunc " C,C++的调试 map :call Rungdb() func! Rungdb() exec "w" exec "!g++ % -g -o %<" exec "!gdb ./%<" endfunc " 语法检查 map :SyntasticCheck im :SyntasticCheck "" 代码格式优化化 "map :call FormartSrc() "" 定义FormartSrc() "func FormartSrc() " exec "w" " if &filetype == 'c' " exec "!astyle --style=ansi -a --suffix=none %" " elseif &filetype == 'cpp' || &filetype == 'hpp' " exec "r !astyle --style=ansi --one-line=keep-statements -a --suffix=none %> /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("'\"") <= line("$") | \ exe "normal g`\"" | \ endif endif " 当打开vim且没有文件时自动打开NERDTree autocmd vimenter * if !argc() | NERDTree | endif " 只剩 NERDTree时自动关闭 autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTreeType") && b:NERDTreeType == "primary") | q | endif " quickfix模式 autocmd FileType c,cpp map :w:make