SpringBoot - 快速入门(SpringBoot 1.5.9.RELEASE为例)

一、Spring Boot 入门

1、Spring Boot 简介

  • 简化Spring应用开发的一个框架;
  • 整个Spring技术栈的一个大整合;
  • J2EE开发的一站式解决方案;

2、微服务

2014,martin fowler提出

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

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

单体应用:ALL IN ONE

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

详细参照微服务文档:https://martinfowler.com/articles/microservices.html#MicroservicesAndSoa

3、Spring Boot HelloWorld

环境准备:

  • 这里以 SpringBoot 1.5.9.RELEASE版本为例。

MAVEN设置:

  • 给maven 的settings.xml配置文件的profiles标签添加
<profile>
	<id>jdk‐1.8</id>
	<activation>
		<activeByDefault>true</activeByDefault>
		<jdk>1.8</jdk>
	</activation>
	<properties>
		<maven.compiler.source>1.8</maven.compiler.source>
		<maven.compiler.target>1.8</maven.compiler.target>
		<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
	</properties>
</profile>

基本功能:

  • 浏览器发送hello请求,服务器接受请求并处理,响应Hello World字符串;

1、创建一个maven工程

2、导入spring boot相关的依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>top.onefine</groupId>
    <artifactId>springboot_maven</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <!-- 父项目:真正管理springboot应用里的所有依赖版本
            也称为springboot的版本仲裁中心,即以后导入依赖默认不需要指明版本号
            但若没有在dependencies里面管理的依赖自然需要声明版本号
    -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
    </parent>

    <dependencies>
        <!-- 启动器
             spring-boot-starter:spring-boot场景启动器,帮我们导入了web模块正常运行所依赖的组件;
             Spring Boot将所有的功能场景都抽取出来,做成一个个的starters(启动器)
             只需要在项目里面引入这些starter 相关场景的所有依赖都会导入进来。要用什么功能就导入什么场景的启动器
         -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <!-- 引入此插件可以将应用打包成一个可执行的jar包 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3、编写一个主程序:启动Spring Boot应用

package top.onefine;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication  // 标注一个主程序,用来说明这是一个springboot应用
public class HelloWorldMainApplication {

    //
    public static void main(String[] args) {
        // 启动springboot应用程序
        SpringApplication.run(HelloWorldMainApplication.class, args);
    }
}

4、编写相关的Controller或Service

package top.onefine.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloController {
    @ResponseBody
    @RequestMapping("/hello")
    public String hello() {
        return "Hello SpringBoot";
    }
}

或者:

package top.onefine.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

//@ResponseBody  // 作用在类上表示这个类的所有方法返回的数据直接写给浏览器,和作用在单独的方法上效果一致
//@Controller
@RestController  // = @ResponseBody + @Controller
public class HelloController {

//    @ResponseBody  // 作用在方法上表示这个方法返回的数据直接写给浏览器(如果是对象还能转为json数据)
    @RequestMapping("/hello")
    public String hello() {
        return "hello world quick!";
    }
}

5、运行主程序测试

执行main方法,浏览器中输入127.0.0.1:8080/hello
在这里插入图片描述

6、简化部署

<!-- 引入此插件可以将应用打包成一个可执行的jar包; -->
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

将这个应用打成jar包:Maven -> 项目名称 -> Lifecycle -> package

找到jar包导出位置:项目名称/target/项目名-版本号.jar

直接使用java -jar的命令进行执行:

# 查看指定端口被占用情况
D:\projects\java\study_springboot\springboot_maven\target>netstat -ano|findstr "8080"
  TCP    0.0.0.0:8080           0.0.0.0:0              LISTENING       9392
  TCP    [::]:8080              [::]:0                 LISTENING       9392

# 关闭进程号对应的进程
D:\projects\java\study_springboot\springboot_maven\target>taskkill -PID 9392 -F
成功: 已终止 PID 为 9392 的进程。

D:\projects\java\study_springboot\springboot_maven\target>java -jar springboot_maven-1.0-SNAPSHOT.jar

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.9.RELEASE)

2020-05-23 11:01:58.183  INFO 10016 --- [           main] top.onefine.HelloWorldMainApplication    : Starting HelloWorldMainApplication v1.0-SNAPSHOT on DESKTOP-LNTOAM6 with PID 10016 (D:\projects\java\study_springboot\springboot_maven\target\springboot_maven-1.0-SNAPSHOT.jar started by Lenovo in D:\projects\java\study_springboot\springboot_maven\target)
2020-05-23 11:01:58.187  INFO 10016 --- [           main] top.onefine.HelloWorldMainApplication    : No active profile set, falling back to default profiles: default
2020-05-23 11:01:58.258  INFO 10016 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@1698c449: startup date [Sat May 23 11:01:58 CST 2020]; root of context hierarchy
2020-05-23 11:01:59.736  INFO 10016 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2020-05-23 11:01:59.754  INFO 10016 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-05-23 11:01:59.757  INFO 10016 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.23
2020-05-23 11:01:59.870  INFO 10016 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-05-23 11:01:59.870  INFO 10016 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1615 ms
2020-05-23 11:01:59.983  INFO 10016 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'dispatcherServlet' to [/]
2020-05-23 11:01:59.987  INFO 10016 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2020-05-23 11:01:59.987  INFO 10016 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2020-05-23 11:01:59.987  INFO 10016 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2020-05-23 11:01:59.987  INFO 10016 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2020-05-23 11:02:00.294  INFO 10016 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@1698c449: startup date [Sat May 23 11:01:58 CST 2020]; root of context hierarchy
2020-05-23 11:02:00.415  INFO 10016 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/hello]}" onto public java.lang.String top.onefine.controller.HelloController.hello()
2020-05-23 11:02:00.421  INFO 10016 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2020-05-23 11:02:00.422  INFO 10016 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2020-05-23 11:02:00.468  INFO 10016 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2020-05-23 11:02:00.469  INFO 10016 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2020-05-23 11:02:00.527  INFO 10016 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2020-05-23 11:02:00.651  INFO 10016 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2020-05-23 11:02:00.732  INFO 10016 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2020-05-23 11:02:00.740  INFO 10016 --- [           main] top.onefine.HelloWorldMainApplication    : Started HelloWorldMainApplication in 2.904 seconds (JVM running for 3.238)

4、主程序类、主入口类探究

@SpringBootApplication  // 标注一个主程序,用来说明这是一个springboot应用
public class HelloWorldMainApplication {

    //
    public static void main(String[] args) {
        // 启动springboot应用程序
        SpringApplication.run(HelloWorldMainApplication.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:开启自动配置功能;
以前我们需要配置的东西,现在Spring Boot帮我们自动配置;@EnableAutoConfiguration告诉SpringBoot开启自
动配置功能,这样自动配置才能生效;@EnableAutoConfiguration源码如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
	// ...
}

解释:

@AutoConfigurationPackage:自动配置包

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {

}

@Import(AutoConfigurationPackages.Registrar.class)

  • Spring的底层注解@Import,给容器中导入一个组件;
  • 导入的组件由AutoConfigurationPackages.Registrar.class 将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到Spring容器;

@Import(EnableAutoConfigurationImportSelector.class):给容器中导入组件EnableAutoConfigurationImportSelector

  • EnableAutoConfigurationImportSelector:导入哪些组件的选择器;
  • 将所有需要导入的组件以全类名的方式返回,这些组件就会被添加到容器中;
  • 会给容器中导入非常多的自动配置类(xxxAutoConfiguration):作用就是给容器中导入这个场景需要的所有组件,并配置好这些组件;

在这里插入图片描述

  • 有了自动配置类,免去了我们手动编写配置注入功能组件等的工作;SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,classLoader):Spring Boot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中,自动配置类就生效,帮我们进行自动配置工作;以前我们需要自己配置的东西,自动配置类都帮我们;J2EE的整体整合解决方案和自动配置都在spring-boot-autoconfigure-1.5.9.RELEASE.jar中做好了。

5、resources文件夹中目录结构

  • static:保存所有的静态资源; js、css、images;
  • templates:保存所有的模板页面;Spring Boot默认jar包使用嵌入式的Tomcat,默认不支持JSP页面;可以使用模板引擎(freemarker、thymeleaf);
  • application.properties:Spring Boot应用的配置文件;可以修改一些默认设置;

二、配置文件

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

  • application.properties
  • application.yml

配置文件的作用:由于SpringBoot在底层都给我们自动配置好大多数配置,配置文件用于修改SpringBoot自动配置的这些默认值;

YAML(YAML Ain’t Markup Language)

  • YAML A Markup Language:是一个标记语言
  • YAML isn’t Markup Language:不是一个标记语言;

标记语言

  • 以前的配置文件;大多都使用的是 xxxx.xml文件;
  • YAML:以数据为中心,比json、xml等更适合做配置文件;

YAML:配置例子

server:
	port: 8081

对应XML形式:

<server>
	<port>8081</port>
</server>

对应properties形式:

server.port=8081

1、YAML语法:

1.1、基本语法

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

  • 以空格的缩进来控制层级关系;只要是左对齐的一列数据,都是同一个层级的
server: 
	port: 8081
	path: /hello
  • 属性和值也是大小写敏感;

1.2、值的写法

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

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

对象、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]

2、配置文件值注入

配置文件src\main\resources\application.yml

server:
  port: 8090

person:
  lastName: one fine中文
  age: 18
  boss: false
  birth: 1996/3/1
  map: {k1: v1, k2: 12}
  list:
    - li si
    - wang wu
  dog:
    name: 小狗
    age: 2

javaBean:

package top.onefine.bean;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 将配置文件中配置的每一个属性的值映射到这个组件中
 *
 * @ ConfigurationProperties
 *      告诉springboot将本类中的所有属性和配置文件中相关的配置进行绑定
 * prefix = "person"
 *      配置文件中哪个下面的所有属性进行一一映射
 *
 *  注意:只有当这个组件是容器中的组件,才能使用容器提供的@ ConfigurationProperties功能
 *      @ Component 将组件加入到容器中
 */
@Getter
@Setter
@ToString
@Component
@ConfigurationProperties(prefix = "person")
public class Person {

    private String lastName;
    private Integer age;
    private Boolean boss;
    private Date birth;

    private Map<String, Object> map;
    private List<Object> list;
    private Dog dog;
}
package top.onefine.bean;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class Dog {

    private String name;
    private String age;
}

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

<!‐‐导入配置文件处理器,配置文件进行绑定就会有提示‐‐>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring‐boot‐configuration‐processor</artifactId>
	<optional>true</optional>
</dependency>

测试类:

package top.onefine;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import top.onefine.bean.Person;

/**
 * springboot单元测试
 *
 */
@SpringBootTest
class SpringbootQuickApplicationTests {

    @Autowired
    private Person person;

    @Test
    void contextLoads() {
        System.out.println(person);
    }
}

结果:

Person(lastName=one fine中文, age=18, boss=false, birth=Fri Mar 01 00:00:00 CST 1996, map={k1=v1, k2=12}, list=[li si, wang wu], dog=Dog(name=小狗, age=2))

附:完整pom.xml(这里使用springboot 2.3.0.RELEASE):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>top.onefine</groupId>
    <artifactId>springboot_quick</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>springboot_quick</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>

        <!-- springboot进行单元测试的模块 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- 配置文件处理器,导入后配置文件进行绑定时就会有提示 -->
        <!--
        https://docs.spring.io/spring-boot/docs/2.3.0.RELEASE/reference/html/appendix-configuration-metadata.html#configuration-metadata-annotation-processor
        -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3、properties形式

server.port=8091

person.last-name=one中文
#[email protected]
person.age=18
person.birth=1996/3/1
person.boss=false
person.map.k1=v1
person.map.k2=v2
person.list=a,b,c
person.dog.name=dog
person.dog.age=15

properties配置文件在idea中默认utf-8可能会乱码,更改idea设置:

在这里插入图片描述

4、@Value获取值

package top.onefine.bean;

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Data
@Component
//@ConfigurationProperties(prefix = "person")
public class Person {

    /**
     * <bean class="Person">
     *      <property name="lastName" value="字面量/${key}从环境变量、配置文件中获取值/{SpEL}"></property>
     * <bean/>
     */
    @Value(value = "${person.last-name}")  // ${key}从环境变量、配置文件中获取值
    private String lastName;
    @Value("#{9 * 2}")  // spring表达式语言:{SpEL}
    private Integer age;
    @Value("true")  // 字面量
    private Boolean boss;
    private Date birth;

    private Map<String, Object> map;
    private List<Object> list;
    private Dog dog;
}

运行测试:
在这里插入图片描述

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

松散绑定
在这里插入图片描述

JSR303数据校验

maven中导入座标:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.3.6.Final</version>
</dependency>
package top.onefine.bean;

import lombok.Data;
import org.hibernate.validator.constraints.Email;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Data
@Component
@Validated  // 数据校验
@ConfigurationProperties(prefix = "person")
public class Person {

//    @Value(value = "${person.last-name}")  // ${key}从环境变量、配置文件中获取值
    @Email  // 数据校验:lastName必须是邮箱格式
    private String lastName;
//    @Value("#{9 * 2}")  // spring表达式语言:{SpEL}
    private Integer age;
//    @Value("true")  // 字面量
    private Boolean boss;
    private Date birth;

    private Map<String, Object> map;
    private List<Object> list;
    private Dog dog;
}

执行:

在这里插入图片描述

关于复杂类型封装

package top.onefine.bean;

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Data
@Component
//@ConfigurationProperties(prefix = "person")
public class Person {

    @Value(value = "${person.last-name}")  // ${key}从环境变量、配置文件中获取值
    private String lastName;
    @Value("#{9 * 2}")  // spring表达式语言:{SpEL}
    private Integer age;
    @Value("true")  // 字面量
    private Boolean boss;
    private Date birth;

    @Value("${person.dog.name}")
    private Map<String, Object> map;
    private List<Object> list;
    private Dog dog;
}

在这里插入图片描述

总结

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

某个业务逻辑举例:

package top.onefine.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HiDemo {

    @Value("${person.last-name}")
    private String name;

    @RequestMapping("/sayHi")
    public String sayHello() {
        return "hello " + name;
    }
}
@PropertySource&@ImportResource&@Bean

@ConfigurationProperties(prefix = "person")默认从全局配置文件中获取值。

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

配置文件person.properties:

person.last-name=fine配置
person.age=18
person.birth=1996/3/1
person.boss=false
person.map.k1=v1
person.map.k2=v2
person.list=a,b,c
person.dog.name=小狗
person.dog.age=15
package top.onefine.bean;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Data
@Component
@ConfigurationProperties(prefix = "person")  // 默认从全局配置文件中获取值
@PropertySource(value = {"classpath:person.properties"})  // 修改加载指定配置文件位置,不从全局配置文件中加载值
public class Person {

    private String lastName;
    private Integer age;
    private Boolean boss;
    private Date birth;
    private Map<String, Object> map;
    private List<Object> list;
    private Dog dog;
}

在这里插入图片描述

注:加载顺序为application.properties->application.yml->person.properties

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

  • Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别;想使用Spring的配置文件加载进来生效:使用@ImportResource标注在一个配置类上:

src\main\java\top\onefine\service\HelloService.java:

package top.onefine.service;

public class HelloService {

}

spring的配置文件beans.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="helloService" class="top.onefine.service.HelloService" />

</beans>
@package top.onefine;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;

@ImportResource(locations = {"classpath:beans.xml"})  // 导入Spring的配置文件让其生效
@SpringBootApplication
public class SpringbootQuickApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootQuickApplication.class, args);
    }

}

测试类:

package top.onefine;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;

/**
 * springboot单元测试
 *
 */
@SpringBootTest
class SpringbootQuickApplicationTests {
    @Autowired
    ApplicationContext ioc;  // IOC容器

    @Test
    void contextLoads() {
        boolean b = ioc.containsBean("helloService");
        System.out.println(b ? "存在" : "不存在");
    }
}

SpringBoot推荐给容器中添加组件的方式:使用全注解的方式,不要编写这里的配置文件beans.xml和启动器上的@ImportResource注解
1、配置类@Configuration—替代—>Spring配置文件 bean.xml

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

package top.onefine.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import top.onefine.service.HelloService;

@Configuration  // 标明这是一个配置类,替代spring的配置文件如刚才的beans.xml
public class MyAppConfig {
    // 刚才的配置文件使用<bean></bean>标签来添加组件

    //
    // 将方法的返回值添加到容器中,容器中组件默认的id就是方法名
    @Bean
    public HelloService helloService() {
        return new HelloService();
    }
}

5、配置文件占位符

占位符获取之前配置的值,如果没有可以是用:指定默认值

${random.value}
${random.int}
${random.long}
${random.int(10)}
${random.int[1024,65536]}
// ...

举例:

server.port=8091
# 随机数
person.last-name=one中文${random.uuid}
#person.last-name=onefine@qq.com
person.age=${random.int}
person.birth=1996/3/1
person.boss=false
# 获取不存在的值
person.map.k1=${one}
# 不存在则设置默认值v2
person.map.k2=${one:v2}
person.list=a,b,c
# 引用值
person.dog.name=${person.last-name}的小狗
person.dog.age=15

执行测试文件:

package top.onefine;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import top.onefine.bean.Person;

@SpringBootTest
class SpringbootQuickApplicationTests {

    @Autowired
    private Person person;

    @Test
    void contextLoads() {
        System.out.println(person);
    }
}

结果:
在这里插入图片描述

6、Profile

Profile是Spring对不同环境提供不同配置功能的支持,可以通过激活、指定参数等方式快速切换环境。

6.1、多Profile文件

在编写主配置文件的时候,文件名可以是 application-{profile}.properties/yml

  • application-dev.properties
  • application-prod.properties

默认使用application.properties的配置

6.2、激活指定profile方式

1、在配置文件(src\main\resources\application.properties)中指定

server.port=8081

# 激活开发环境
#spring.profiles.active=dev

# 激活生产环境
spring.profiles.active=prod

2、命令行:

java -jar springboot_quick-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev

在这里插入图片描述

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

在这里插入图片描述

3、虚拟机参数:

# jvm参数
-Dspring.profiles.active=dev

在这里插入图片描述

6.3、yml支持多文档块方式

使用---分隔文档块

# 文档块1
server:
  port: 8081
  servlet:
    context-path: /boot

## 配置项目的访问路径


## 激活开发环境
#spring:
#  profiles:
#    active: dev

## 激活生产环境
spring:
  profiles:
    active: prod
---

# 文档块2
server:
  port: 8082

## 指定环境:开发环境
spring:
  profiles: dev
---

# 文档块3
server:
  port: 8083

## 指定环境:生产环境
spring:
  profiles: prod

7、配置文件加载位置

springboot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件:

  • file:./config/ :file表示当前项目文件路径,在项目名/
  • file:./
  • classpath:/config/ :classpath表示当前项目类路径,在项目名/src/main/resources/
  • classpath:/

以上是优先级由高到低的顺序排列,所有位置的文件都会被加载,高优先级的配置会覆盖低优先级的配置;

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

我们还可以通过spring.config.location来改变默认的配置文件位置:项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;指定配置文件和默认加载的这些配置文件共同起作用形成互补配置

java -jar springboot_quick-0.0.1-SNAPSHOT.jar --spring.config.location=G:/application.properties

8、外部配置加载顺序

SpringBoot也可以从以下位置加载配置,优先级从高到低,且高优先级的配置覆盖低优先级的配置,所有的配置会形成互补配置:

  • 1.命令行参数
    • 所有的配置都可以在命令行上进行指定
    • java -jar springboot_quick-0.0.1-SNAPSHOT.jar --server.port=8087 --server.context-path=/abc
    • 多个配置用空格分开,格式为:--配置项=值
  • 2.来自java:comp/env的JNDI属性
  • 3.Java系统属性(System.getProperties())
  • 4.操作系统环境变量
  • 5.RandomValuePropertySource配置的random.*属性值

由jar包外向jar包内进行寻找,优先加载带profile:

  • 6.jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件
  • 7.jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件

注:
jar包外部是指和jar同一级目录
jar包内部是指项目打包前项目内的配置文件

再来加载不带profile:

  • 8.jar包外部的application.properties或application.yml(不带spring.profile)配置文件
  • 9.jar包内部的application.properties或application.yml(不带spring.profile)配置文件

  • 10.@Configuration注解类上的@PropertySource
  • 11.通过SpringApplication.setDefaultProperties指定的默认属性

以上仅列出常用的配置加载来源,所有支持的配置加载来源,详参考官方文档

9、自动配置原理

配置文件到底能写什么?怎么写?自动配置原理;

配置文件能配置的属性参照:官方文档

9.1、自动配置原理:

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

  • 利用EnableAutoConfigurationImportSelector给spring容器中导入一些组件
  • 可以查看selectImports()方法的内容:List configurations = getCandidateConfigurations(annotationMetadata, attributes);获取候选的配置。
SpringFactoriesLoader.loadFactoryNames()
// 扫描所有jar包类路径下 META‐INF/spring.factories 文件
// 把扫描到的这些文件的内容包装成properties对象
// 从properties中获取到EnableAutoConfiguration.class类(类名)对应的值,然后把他们添加在容器中

// 将类路径下 `META-INF/spring.factories` 里面配置的所有`EnableAutoConfiguration`的值加入到了容器中:
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\ 
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.DeviceDelegatingViewResolverAutoConfiguration,\ 
org.springframework.boot.autoconfigure.mobile.SitePreferenceAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.reactor.ReactorAutoConfiguration,\
org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.FallbackWebSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.OAuth2AutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.social.SocialWebAutoConfiguration,\
org.springframework.boot.autoconfigure.social.FacebookAutoConfiguration,\
org.springframework.boot.autoconfigure.social.LinkedInAutoConfiguration,\
org.springframework.boot.autoconfigure.social.TwitterAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration

// 每一个这样的 xxxAutoConfiguration类都是容器中的一个组件,都加入到容器中;用他们来做自动配置;

3)、每一个自动配置类进行自动配置功能;

4)、以HttpEncodingAutoConfiguration(Http编码自动配置)为例解释自动配置原理:

@Configuration //表示这是一个配置类,和以前编写的配置文件一样,也可以给容器中添加组件
//启动指定类的ConfigurationProperties功能;将配置文件中对应的值和HttpEncodingProperties绑定起来;并把HttpEncodingProperties加入到ioc容器中
@EnableConfigurationProperties(HttpEncodingProperties.class) 

//Spring底层@Conditional注解,根据不同的条件,如果满足指定的条件,整个配置类里面的配置就会生效; 判断当前应用是否是web应用,如果是,当前配置类生效
@ConditionalOnWebApplication 

//判断当前项目有没有CharacterEncodingFilter这个类,这是SpringMVC中进行乱码解决的过滤器;
@ConditionalOnClass(CharacterEncodingFilter.class) 

//判断配置文件中是否存在某个配置 spring.http.encoding.enabled;matchIfMissing 表示如果不存在,判断也是成立的,即默认配置。
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true) 
//即使我们配置文件中不配置pring.http.encoding.enabled=true,也是默认生效的;
public class HttpEncodingAutoConfiguration {
	//他已经和SpringBoot的配置文件映射了
	private final HttpEncodingProperties properties;
	
	//只有一个有参构造器的情况下,参数的值就会从容器中拿
	public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) {
		this.properties = properties;
	} 
	
	@Bean //给容器中添加一个组件,这个组件的某些值需要从properties中获取
	@ConditionalOnMissingBean(CharacterEncodingFilter.class) //判断容器没有这个组件?
	public CharacterEncodingFilter characterEncodingFilter() {
		CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
		filter.setEncoding(this.properties.getCharset().name());
		filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));
		filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
		return filter;
	}
}

根据当前不同的条件判断,决定这个配置类是否生效。一但这个配置类生效,这个配置类就会给容器中添加各种组件;这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;

5)、所有在配置文件中能配置的属性都是在xxxxProperties类中封装者‘,配置文件能配置什么就可以参照某个功能对应的这个属性类:

@ConfigurationProperties(prefix = "spring.http.encoding") //从配置文件中获取指定的值和bean的属性进行绑定
public class HttpEncodingProperties {
	public static final Charset DEFAULT_CHARSET = Charset.forName("UTF‐8");
}

springboot精髓

1)、SpringBoot启动会加载大量的自动配置类
2)、我们看我们需要的功能有没有SpringBoot默认写好的自动配置类;
3)、我们再来看这个自动配置类中到底配置了哪些组件;(只要要用的组件有,就不需要再来配置了)
4)、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们就可以在配置文件中指定这些属性的值;

总结:

  • xxxxAutoConfigurartion:自动配置类,会给容器中添加组件;

  • xxxxProperties:封装配置文件中相关属性;

9.2、细节

1、@Conditional派生注解

作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;

自动配置类必须在一定的条件下才能生效:

@Conditional扩展注解 作用(判断是否满足当前指定条件)
@ConditionalOnJava 系统的java版本是否符合要求
@ConditionalOnBean 容器中存在指定Bean;
@ConditionalOnMissingBean 容器中不存在指定Bean;
@ConditionalOnExpression 满足SpEL表达式指定
@ConditionalOnClass 系统中有指定的类
@ConditionalOnMissingClass 系统中没有指定的类
@ConditionalOnSingleCandidate 容器中只有一个指定的Bean,或者这个Bean是首选Bean
@ConditionalOnProperty 系统中指定的属性是否有指定的值
@ConditionalOnResource 类路径下是否存在指定资源文件
@ConditionalOnWebApplication 当前是web环境
@ConditionalOnNotWebApplication 当前不是web环境
@ConditionalOnJndi JNDI 存在指定项

我们怎么知道哪些自动配置类生效?可以通过在配置文件中启用 debug=true属性;来让控制台打印自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效:

# 开启springboot的debug模式,这里是在application.yml中配置的
debug: true

项目运行时控制台打印结果

============================
CONDITIONS EVALUATION REPORT
============================


Positive matches:(自动配置类启用的)
-----------------

   AopAutoConfiguration matched:
      - @ConditionalOnProperty (spring.aop.auto=true) matched (OnPropertyCondition)

   AopAutoConfiguration.ClassProxyingConfiguration matched:
      - @ConditionalOnMissingClass did not find unwanted class 'org.aspectj.weaver.Advice' (OnClassCondition)
      - @ConditionalOnProperty (spring.aop.proxy-target-class=true) matched (OnPropertyCondition)

   # ...省略


Negative matches:(没有启动,没有匹配成功的自动配置类)

-----------------

   ActiveMQAutoConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required class 'javax.jms.ConnectionFactory' (OnClassCondition)

   AopAutoConfiguration.AspectJAutoProxyingConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required class 'org.aspectj.weaver.Advice' (OnClassCondition)
	# ...省略
  
Exclusions:
-----------

    None


Unconditional classes:
----------------------

    org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration

    org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration

    org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration

    org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration

    org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration


一. 启动

1. idea启动

2. 命令行启动

luckymoney> mvn spring-boot:run

3. 服务器端打包方式

luckymoney> mvn clean package
# ...
luckymoney> java -jar target/luckymoney-0.0.1-SNAPSHOP.jar

二、配置

0. 使用0

src/main/resources/application.properties

server.port = 8081
server.servlet.context-path = /luckymoney

1. 使用1

  1. src/main/resources/application.yml
server:
  port: 8082
  servlet:
    context-path: /luckymoney

minMoney: 1
description: 最少要发${minMoney}
  1. src/main/java/top/onefine/luckymoney/HelloController.java:@Value注解
package top.onefine.luckymoney;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;

@RestController
public class HelloController {

    @Value("${minMoney}")
    private BigDecimal minMoney;

    @Value("${description}")
    private String description;

    @GetMapping("/hello")
    public String say() {
        return "开启SpringBoot! 金额:" + minMoney + ", 说明:" + description;
    }
}

2. 使用2

src/main/resources/application.yml

spring:
  profiles:
    active: prod

src/main/resources/application-dev.yml

# 开发环境
server:
  port: 8082
  servlet:
    context-path: /luckymoney

# 使用对象配置
limit:
  minMoney: 0.01
  maxMoney: 9999
  description: 最少要发${limit.minMoney}元,最多${limit.maxMoney}

src/main/resources/application-prod.yml

# 生产环境
server:
  port: 8082
  servlet:
    context-path: /luckymoney

# 使用对象配置
limit:
  minMoney: 1
  maxMoney: 9999
  description: 最少要发${limit.minMoney}元,最多${limit.maxMoney}

src/main/java/top/onefine/luckymoney/LimitConfig.java@Component@ConfigurationProperties注解

package top.onefine.luckymoney;

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

import java.math.BigDecimal;

@Component
@ConfigurationProperties(prefix = "limit")
public class LimitConfig {
    private BigDecimal minMoney;
    private BigDecimal maxMoney;
    private String description;

    public BigDecimal getMinMoney() {
        return minMoney;
    }

    public void setMinMoney(BigDecimal minMoney) {
        this.minMoney = minMoney;
    }

    public BigDecimal getMaxMoney() {
        return maxMoney;
    }

    public void setMaxMoney(BigDecimal maxMoney) {
        this.maxMoney = maxMoney;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

src/main/java/top/onefine/luckymoney/HelloController.java

package top.onefine.luckymoney;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @Autowired
    private LimitConfig limitConfig;

    @GetMapping("/hello")
    public String say() {
        return "开启SpringBoot! 金额:" + limitConfig.getMinMoney() + ", 说明:" + limitConfig.getDescription();
    }
}

默认启用的是生产环境的配置,服务器端打包方式运行时启用开发环境的配置:java -jar -Dspring.profiles.active=dev target/luckymoney-0.0.1-SNAPSHOP.jar

在这里插入图片描述

三、Controller的使用

在这里插入图片描述

1. Controller

maven添加依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

2. src/main/resources/templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<h1>SpringBoot入门</h1>

</body>
</html>

3. src/main/java/top/onefine/luckymoney/HelloController.java

返回html页面(不常用)

package top.onefine.luckymoney;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

import java.math.BigDecimal;

@Controller
public class HelloController {

    @Autowired
    private LimitConfig limitConfig;

    @GetMapping("/hello")
    public String say() {
        return "index";
    }
}

或者返回String:

package top.onefine.luckymoney;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@ResponseBody
public class HelloController {


    @Autowired
    private LimitConfig limitConfig;

    @GetMapping("/hello")
    public String say() {
        return "开启SpringBoot! 金额:" + limitConfig.getMinMoney() + ", 说明:" + limitConfig.getDescription();
    }
}

注意:

@RestController  // @RestController = @Controller + @ResponseBody
//@Controller
//@ResponseBody

4.

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