spring boot笔记

#  spring boot笔记

## 一、Spring Boot入门

#### 1.1、Spring 简介

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

#### 1.2、微服务

微服务 架构风格

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

单体应用

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

#### 1.3 、环境准备

JDK1.8    : spring-boot1.7及以上

Maven3.x: Maven3.3以上版本

Idea 2017

SpringBoot 2.x

统一环境

#### 1.4 、部署

**pom.xml中配置该文件表示 打成jar包**

```xml

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

```

cmd 使用命令 `java -jar spring-boot.jar ` 运行对应的程序  -- 可以跟参数

springBoot热部署 通过pom.xml文件引用devtools,保证以后开发过程中,修改了某些代码,不用重启服务器

eclipse 保存代码,自动编译, idea 保存代码 编译按Ctrl+F9编译,修改的代码自动生效

```xml


    org.springframework.boot
    spring-boot-devtools
    true

```

#### 1.5 、POM文件研究

##### 1、父项目

 pom文件中

```xml

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

他的父项目是:

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

```

 dependencies 用来真正管理SpringBoot应用里面所有的依赖版本

以后我们导入依赖默认是不需要写版本(没有在dependencies 的管理中是要声明版本号)

##### 2、启动器

```xml

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

```

spring-boot-web:

  spring-boot-starter: spring-boot场景启动器 帮我们导入web中正常运行的依赖的组件

##### 3、主程序、主入口类

```java
@SpringBootApplication
public class Application extends WebMvcConfigurerAdapter {

    public static void main(String[] args) throws InterruptedException {
        SpringApplication.run(Application.class, args);
    }
}
```

**@SpringBootApplication** : SpringBoot应用标注在某个类上说明这个类是SpringBoot配置类 SpringBoot运行这个main方法来应用  

```java
@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**:springBoot配置类

标注在某个类上 表示这是一个SpringBoot配置类

​        **@Configuration**:配置类上来标注这个注解

配置类-- 配置文件 配置类中也是容器中的一个组件**@Component**

**@EnableAutoConfiguration** : 开启自动注解功能;

springBoot帮我们自动配置,**@EnableAutoConfiguration** 告诉springBoot开启自动配置功能,这样配置才能生效

```java
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
   
}
```

 **@AutoConfigurationPackage** :自动配置包

```
@Import({Registrar.class})
public @interface AutoConfigurationPackage {
}
```

@Import({Registrar.class})

***Spring的底层注解是@Import,给容器中导入一个组件,导入的组件由@AutoConfigurationPackage***

***讲主配置类中的包以及所在包下面的子包的所有组件扫描到SpringBoot容器***

**@Import({AutoConfigurationImportSelector.class})**

给容器导入组件

AutoConfigurationImportSelector 导入哪些组件的选择器

将所有需要导入的组件以类名的方式返回,这些组件就被添加到容器中

会给容器导入非常多的自动配置类(xxxAutoConfiguration) 这就是容器导入这个场景所有的组件,并配置好这些组件。

![xxxAutoConfiguration](\SpringBoot笔记\images\xxxAutoConfiguration.png)

有了自动配置的类,免去了我们手动编写配置注入功能组件等工作;

**SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class ClassLoader);**

**SpringBoot在启动的时候,从类路径下 META-INF/Spring.factories中获取EnableAutoConfiguration指定的值**

**将这些值自动配置类导入到容器中,自动配置类就生效了。**

以前我们需要自己配置的东西,自动配置类都帮我们做了。

J2EE的整体整合解决方案和自动配置都在 spring-boot-autoconfigure.jar 包中

## 二 SpingBoot配置

### 1、配置文件

SpringBoot使用全局配置文件 配置文件的名称是固定的。

application.properties

application.yml

配置文件的使用,修改SpringBoot自动配置的默认值,SpringBoot在底层都给我们自动配置好了。

yml 标记语言 yml已数据为中心,比如JSON,XML等更合适做配置文件

语法:

```yml
server:
  port: 8080
```

porperties 语法:

``` properties
server.port=8080
```

### 2、YMAL语法

##### 1)、基本语法

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

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

```yml
    server:
        port: 8080
        path: /hello
```

##### 2)、值的写法

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

K:V 字面直接来写。 字符串默认不加引号

双引号: 不会转义字符串里面的特殊字符,

name: "zhangsan \n lisi" 输出: zhangsan 换行 lisi

单引号:

name: 'zhangsan \n lisi' 输出   zhangsan \n lisi

**对象 MAP属性和值(键值对)**

K: V 在下一行写对象属性和值的关系,注意缩进

```yml
person:
        name: 张三
        age: 12
```

行内写法:

```yml
person: {name:张三 ,age: 12}
```

**数组(List,SET)**

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

```
 pets
     -cat 
     -dog 
     -pig
```

行内写法:

```yml
pets:[cat,dog,pig]
```

##### 3)、配置文件值的注入

yml配置:

```yml
 person: 
     lastName: hello
     age: 18 
     boss: false
     birth: 2019/03/12
     maps:{k1: v1,k2: v2}
     lists 
         -lisi
         -zhaoliu
     dog:
         name: 小狗
         age: 3
  
```

properties配置:

```properties
#这里的last-name与javaBean中属性lastName值等同,可以这么写 后面提到的松散绑定
person.last-name=张三
person.age=18
person.birth=2019/03/12
person.boss=flase
perosn.maps.k1=v1
person.maps.k2=v2
person.lists=a,b,c
person.dog.name=dog
person.dog.age=15
```

properties配置 UTF-8 格式 

idea设置 file encodings -->  设置 utf-8, 勾上transparent 

javaBean:

```java
/**
 *      
 * @Author Linyichun  
 * @Date 2019/3/6 15:25
 * @ConfigurationProperties告诉springboot讲本类的所有属性和配置文件中相关配置绑定 默认从全局文件提取
 */
@Component
@ConfigurationProperties(prefix = "person")
@PropertySource(value = {"classPath:aa.properties"}) //引用application.properties同级目录下的aa.properties配置文件
@Validated  //JSR303数据校验
public class Person {
    @Email // JSR303数据校验 验证必须是邮箱格式 
    private String lastName;
    private Integer age;
    private Boolean boss;
    private Date birth;
    private Map maps;
    private List lists;
    private Dog dog; //dog为另外一个javaBean

}
```

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

```xml
 
            org.springframework.boot
            spring-boot-configuration-processor
 

```

##### 4)@ConfigurationProperties与@Value的区别

|                    | @ConfigurationProperties | @Value                     |
| ------------------ | ------------------------ | -------------------------- |
| 功能               | 批量注入配置文件中的属性 | 一个个指定                 |
| 松散绑定           | 支持                     | 不支持                     |
| SPEL(Spring表达式) | 不支持  #{11*2}          | 支持 例子:@Value(#{11*2}) |
| JSR303数据校验     | 支持 @Validated          | 不支持                     |
| 复杂类型封装       | 支持                     | 不支持                     |

配置文件不管是yml还是properties都能获取到值

如果说 只是在某个业务逻辑中获取配置文件中的某项值  就用@Value

##### 5)@PropertySource与@ImportResource

 * @PropertySource(value = {"classPath:*.properties"})读取资源下某个指定的资源文件

   

 * @ImportResource 导入spring配置文件 @ImportResource标注在主配置类上

  @ImportResource(value = {"classPath:*.xml"})

例子:

```yml
@SpringBootApplication
@ImportResource(locations={"classpath:kaptcha.xml"})
public class Application  {

```

上一段代码说明引用 application.properties同级目录下的 kaptcha.xml文件

spring配置文件

```xml

```

SpringBoot推荐给容器添加组件的方式

1配置类==== spring配置文件

2使用@bean给容器添加组件

```java
/**
 * @Configuration 指明当前类是一个配置类,就是来代替之前来的Spring的配置文件
 */
@Configuration
public class MyAppConfig {
    //@Bean 将方法的返回值添加到容器中 容器中这个组件默认的id就是方法名
    @Bean
    public HelloService helloService() {
        return new HelloService();
    }
}
```

##### 6)、配置文件占位符

随机数: 

```
${random.uuid}
${random.int}
${random.value}
${random.long}
${random.int(10)}
```

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

```properties
person.lastName=张三
person.dog=${person.hello:hello}_dog
```

读取到person.dog的值为 **hello_dog**

##### 7、Profile

###### 1.多profile文件切换

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

profile的 值 可以为 **test /dev/prod**

默认使用的是application.properties配置文件

###### 2.yml多文档块方式

```yml
server:
  port: 8080
spring:
    profiles:
      active: dev
---
server:
  port: 8081
spring:
  profiles: test
---
server:
  port: 8084
spring:
  profiles: prod 
```

###### 3.激活指定profile

1、配置在properties中指定 spring.profiles.active=dev

2.命令行 `java -jar spring-boot.jar --spring.profiles.active=dev; `

3.虚拟参数-Dspring.profiles.active=dev

##### 8、配置文件加载位置

SpringBoot启动会扫描以下位置的application.properties/yml 文件作为SpringBoot的默认配置文件

**-- file(项目文件)  /config/**

**-- file(项目文件)   /**

**-- file(项目文件)   classpath(resources文件夹):/config/**

**-- file(项目文件) classpath(resources文件夹) :/**

优先级由高到低。 高优先级的配置会覆盖低优先级的配置,互补配置(高优先级没有在考虑使用低优先级

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

项目打包以后,可以通过命令行参数在 指定配置文件新位置。指定的文件跟默认加载的文件形成互补配置

##### 9、外部加载的配置顺序

SpringBoot可以以下位置加载配置,优先级从高到低,高优先级的配置会覆盖低优先级的配置,互补配置

1.命令行参数

修改端口号为8087端口

`java -jar spring-boot.jar --server.port=8087`

2、来自java:comp/env的JNDI属性

3、Java系统属性(System.getProperties())

4、操作系统的环境变量

5、RandomValuePropertySource配置的random.*属性值

由jar包外向jar内寻找

**优先加载带profile**

6、jar包外部的application-{profile}.properties/yml(带spring.profile)配置文件

7、jar包内部的application-{profile}.properties/yml(带spring.profile)配置文件

**其次加载不带profile**

8、jar包外部的application-{profile}.properties/yml(不带spring.profile)配置文件

9、jar包内部的application-{profile}.properties/yml(不带spring.profile)配置文件

10.@Configuration注解类上的@PropertySource

例子:@PropertySource(value = {"classPath:aa.properties"}) //引用application.properties同级目录下的aa.properties配置文件

11.通过SpringApplication.setDefaultProperties指定的默认属性

所有的支持加载来源

 [参考官方文档](https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/reference/htmlsingle/#boot-features-external-config)

##### 10、Spring自动配置原理

###### 1、配置属性

  [配置文件能配置的属性](https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/reference/htmlsingle/#common-application-properties)

自动配置的原理:

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

2)@EnableAutoConfiguration作用:

​    利用AutoConfigurationImportSelector给容器导入了一些组件

​    可以查看selectImports内容,获取候选的配置

​    List configurations = this.getCandidateConfigurations(annotationMetadata, attributes);

```java
 SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class, this.getBeanClassLoader());

扫描所有jar包类路径下的 META-INF/spring.factories 
把扫描的这些文件的内容包装成properties对象
从properties中获取EnableAutoConfiguration.class(类名)对应的值,然后把他们添加到容器中
```
将类路径下META-INF/sping.factories里面配置的所有EnableAutoConfiguration的值加入到容器中

```factories
# 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.CloudServiceConnectorsAutoConfiguration,\
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.CassandraReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
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.jdbc.JdbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
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.RedisReactiveAutoConfiguration,\
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.elasticsearch.rest.RestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
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.http.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\
org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\
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.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
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.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
org.springframework.boot.autoconfigure.reactor.core.ReactorCoreAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityRequestMatcherProviderAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration,\
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.client.RestTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration
```

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

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

4) 以**HttpEncodingAutoConfiguration(http编码自动配置)**为例子解释自动配置原理

```java
@Configuration //表示这是一个配置类,以前编码的配置文件一样,也可以给容器添加组件
@EnableConfigurationProperties({HttpProperties.class}) 
//启动指定类(HttpProperties类)例子下
//ConfigurationProperties功能 将配置文件中对应的值跟HttpProperties绑定起来
//并把HttpProperties加入到IOC容器中
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
//spring底层@Conditional注解,根据不同条件,如果满足指定的条件,整个配置里面的配置就生效
//判断当前引用是否是web项目 如果是当前配置文件生效
@ConditionalOnClass({CharacterEncodingFilter.class})
//CharacterEncodingFilter spring MVC中进行乱码解决的过滤器
@ConditionalOnProperty(
    prefix = "spring.http.encoding",
    value = {"enabled"},
    matchIfMissing = true
)//判断配置文件中是否存在某个配置 即使 spring.http.encoding =true 没配置 默认生效

public class HttpEncodingAutoConfiguration {
    //已经跟springBoot的配置文件映射了 
    private final Encoding properties;
    //只有一个有参的构造器的情况下,参数的值就会从容器中获取
    public HttpEncodingAutoConfiguration(HttpProperties properties) {
        this.properties = properties.getEncoding();
    }
    
    @Bean
    @ConditionalOnMissingBean //判断容器中没有这个组件
    public CharacterEncodingFilter characterEncodingFilter() {
        CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
        filter.setEncoding(this.properties.getCharset().name());
        filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.REQUEST));
        filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.RESPONSE));
        return filter;
    }

```

根据当前不同的条件判断,决定这个配置类是否生效

**一旦这个配置类生效, 这个配置就会给容器中添加各种组件,这些组件的属性是从对应的properties类中获取的**

**这些类里面的每一个属性又是和配置文件绑定的。**

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

HttpProperties类

```java
@ConfigurationProperties(
    prefix = "spring.http"
)
public class HttpProperties {
```

```properties
#我们能配置的属性都是来源于这个功能的properties属性类
spring.http.encoding.enabled=true
spring.http.encoding.charset=UTF-8
spring.http.encoding.force=true
```

精髓:

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

**2)需要的功能是否有SpringBoot默认写好的自动配置类**

**3)  自动配置类中到底有哪些组件(只要需要用的组件,有就不需要配置了)**

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

 xxxAutoConfigurartion:自动配置类

给容器中添加组件 xxxProperties封装配置文件中的相关属性

###### 2、细节

**1、@Conditional派生注解(Spring注解版原生的@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存在指定项                                |

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

在properties配置文件中配置 debug=true ,来让控制台打印自动配置报告,这样就知道哪些自动配置类生效,哪些没有生效。

```properties
#开启springBoot debug
debug=true
```

```java
============================
CONDITIONS EVALUATION REPORT(自动配置报告)
============================
Positive matches:)(自动配置类启用的)
-----------------

   CodecsAutoConfiguration matched:
      - @ConditionalOnClass found required class 'org.springframework.http.codec.CodecConfigurer' (OnClassCondition)
          
 Negative matches:(没有启用,没有匹配成功的自动配置类)
-----------------

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

```

## 三、Spring Boot 日志

### 1.日志框架 

市面上的日志框架

JUL、JCL、Jboss-logging、logback、log4j、log4j2、sjf4j

| 日志门面(日志的抽象层)        | 日志实现                            |
| ----------------------------- | ----------------------------------- |
| JCL,**SLF4J**,Jboss-logging | **Log4j**,JUL,Log4j2,**Logback** |

左边选一个门面(抽象层)、右边选择一个日志实现

(SLF4J/Log4j/LogBack)出自同一个人写的

日志门面一般选择  :SLF4J

日志实现: Log4j/LogBack

SpringBoot底层是Spring框架, Spring框架默认使用的是 JUL(java.util.logging)。

**SpringBoot选用SLF4j和LogBack**

### 2、SLF4J使用

#### 1、如何在系统使用SLF4j

以后在开发的时候, 日志记录方法的调用,不应该来直接调用日志的实现类,而是调用日志抽象层里面的方法

应该给系统里面导入slf4j的jar和logback的实现jar

 ```java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloWorld {
  public static void main(String[] args) {
    Logger logger = LoggerFactory.getLogger(HelloWorld.class);
    logger.info("Hello World");
  }
 ```

图示:![concrete-bindings](images\concrete-bindings.png)

每一个日志的实现框架都有自己的配置文件, 使用slf4j以后,**配置文件还是做成日志实现框架自己本身的配置文件**

#### 2.遗留问题

系统A(slf4j+logback)   Spring(commons-logging)、Hibernate(Jboss-logging)、MyBatis。XXX

统一日志记录,即使是别的框架 我们统一使用slf4进行日志输出

![legacy](images\legacy.png)

如何让系统中所有的日志都统一到slf4j

1、将系统的其他日志框架先排除出去

2、用中间包来替换原有的日志框架

3、导入slf4j其他的实现

#### 3、SpringBoot日志关系

Spring日志使用功能

```xml

            org.springframework.boot
            spring-boot-starter-logging

```

![rizhi](images\rizhi.png)

总结:

1)、SpringBoot底层也是使用slf4j+logback的方式使用日志记录

2)、SpringBoot也把其他的日志文件替换成了slf4j

3)、中间替换包

![logjar](images\logjar.png)

4)、如果要引入其他框架 一定要把这个框架的默认日志依赖移除掉

Spring框架用的 是commons-logging

SpringBoot能自动适配所有的日志,底层使用slf4j+logback记录日志 ,引入其他框架的时候, 只需要把这个框架依赖的日志框架排除掉

#### 4、日志使用

##### 1.默认配置

SpringBoot默认帮我们配置好了日志

```java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootLoggingApplicationTests {
    //日志记录器
   Logger logger = LoggerFactory.getLogger(getClass());

    @Test
    public void contextLoads() {
//        System.out.println();
        //日志级别 由低到高,trace < debug < info < warn < error
        //可以调整输出的日志级别

        logger.trace("1.trace日志");
        logger.debug("2.debug日志");
        //spring boot 默认info级别往上的日志
        logger.info("3.info日志");
        logger.warn("4.warn日志");
        logger.error("5.error日志");
    }

}
```

SpringBoot修改日志的默认配置

```properties
logging.level.com.example=trace

#绝对路径,在当前磁盘的根路径下创建spring文件夹里面的log文件夹,使用spring.log作为默认文件
logging.path=/spring/log
#当前项目下生成springboot日志
#可以指定完整的路径
#logging.file=springboot.log

#在控制台输入的日志格式
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n
#指定文件中日志输出的格式
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} %-5level %logger Line:%-3L - %msg%n
```

```java
日志输出的格式:
 %d 表示日期时间
 %thread 表示线程名称
 %-5level 级别从左显示5个字符宽度
 %logger{50} 表示logger名字最长50个字符,否则按照句点分割
 %msg 日志消息
 %n 换行符
 例子:
 %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{50}  - %msg%n
```

| logging.file | logging.path | example  | description                    |
| ------------ | ------------ | -------- | ------------------------------ |
| none         | none         |          | 只在控制台输出                 |
| 指定文件名   | none         | my.log   | 输出到my.log文件中             |
| none         | 指定目录     | /var/log | 输出到指定目录spring.log文件中 |

##### 2、指定配置

给类路径下放每个日志框架自己的配置文件即可,

| Logging System          | Customization                                                |
| ----------------------- | ------------------------------------------------------------ |
| Logback                 | `logback-spring.xml`, `logback-spring.groovy`, `logback.xml`, or `logback.groovy` |
| Log4j2                  | `log4j2-spring.xml` or `log4j2.xml`                          |
| JDK (Java Util Logging) | `logging.properties`                                         |

例子:

logback.xml:直接被日志框架识别了

logback-spring.xml:日志框架就不直接加载日志的配置项,由springBoot解析日志配置,可以使用SpringBoot的springProfile功能。

```xml

    

logback-spring.xml可以使用如下的配置 ,可以指定某段配置在某段环境下生效
```

## 四、Spring Boot 与Web开发

### 1.使用springBoot

1)创建一个SpringBoot应用。 选择我们需要的模块

2) SpringBoot已经默认将这些场景默认配置好了,只需要在配置文件中指定少量配置就可以运行起来

3)编写业务代码

自动配置原理:

 这个场景SpringBoot帮我们配置了什么, 能否修改,能否扩展。

```java
xxxAutoConfigurartion:帮我们给容器自动配置组件
xxxProperties 配置类来封装配置文件内容
```

### 2.静态资源的映射规则

 WebMvcAutoConfiguration.java

```java
//添加资源映射 addResourceHandlers
public void addResourceHandlers(ResourceHandlerRegistry registry) {
            if (!this.resourceProperties.isAddMappings()) {
                logger.debug("Default resource handling disabled");
            } else {
                Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
                CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
                if (!registry.hasMappingForPattern("/webjars/**")) {
                    this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
                }

                String staticPathPattern = this.mvcProperties.getStaticPathPattern();
                if (!registry.hasMappingForPattern(staticPathPattern)) {
                    this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
                }

            }
        }
//欢迎页
 private Optional getWelcomePage() {
            String[] locations = getResourceLocations(this.resourceProperties.getStaticLocations());
            return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();
        }

//图标
@Configuration
        @ConditionalOnProperty(
            value = {"spring.mvc.favicon.enabled"},
            matchIfMissing = true
        )
        public static class FaviconConfiguration implements ResourceLoaderAware {
            private final ResourceProperties resourceProperties;
            private ResourceLoader resourceLoader;

            public FaviconConfiguration(ResourceProperties resourceProperties) {
                this.resourceProperties = resourceProperties;
            }

            public void setResourceLoader(ResourceLoader resourceLoader) {
                this.resourceLoader = resourceLoader;
            }

            @Bean
            public SimpleUrlHandlerMapping faviconHandlerMapping() {
                SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
                mapping.setOrder(-2147483647);
                //**/favicon.ico
                mapping.setUrlMap(Collections.singletonMap("**/favicon.ico", this.faviconRequestHandler()));
                return mapping;
            }

            @Bean
            public ResourceHttpRequestHandler faviconRequestHandler() {
                ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
                requestHandler.setLocations(this.resolveFaviconLocations());
                return requestHandler;
            }

            private List resolveFaviconLocations() {
                String[] staticLocations = WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter.getResourceLocations(this.resourceProperties.getStaticLocations());
                List locations = new ArrayList(staticLocations.length + 1);
                Stream var10000 = Arrays.stream(staticLocations);
                ResourceLoader var10001 = this.resourceLoader;
                this.resourceLoader.getClass();
                var10000.map(var10001::getResource).forEach(locations::add);
                locations.add(new ClassPathResource("/"));
                return Collections.unmodifiableList(locations);
            }
        }
```

ResourceProperties:

```java
@ConfigurationProperties(
    prefix = "spring.resources",
    ignoreUnknownFields = false
)
public class ResourceProperties {
}
//可以设置和静态资源有关的参数,缓存时间等
```

1)/webjars/** 所有webjars所有的路径  都去"classpath:/META-INF/resources/webjars/ 找资源

webjars : 已jar包的方式引入资源

[webjars链接](https://www.webjars.org/)

![webjars](images\webjars.png)

localhost:8080/webjars/jquery/3.3.1/jquery.js 访问对应的jquery文件

```xml
访问的时候只需要写webjars下面的名称即可

   org.webjars
   jquery
   3.3.1

```

 2) "/**"访问当前项目的任何资源

```java
"classpath:/META-INF/resources/",
"classpath:/resources/", 
"classpath:/static/",
"classpath:/public/"
"/":当前项目的根路径
```

目录如图下所示:

![static](images\static.png)

localhost:8080/a.css从当前项目寻找对应的静态资源a.css文件

3) 欢迎页: 静态资源文件夹下所有的index.html页面 被”/**" 映射

localhost:8080/    --》找index.html页面

4) 所有的 **/favicon.ico 都是在静态资源文件夹下找

如果想修改默认静态资源文件夹的位置,那么就可以在properties中配置对应的静态资源文件

```properties
#定义静态文件夹访问的位置, 定义以后springBoot默认的静态文件夹位置就不能使用
#多个以逗号分隔
spring.resources.static-locations=classpath:/hello,classpath:/huapu
```

定义静态文件位置为 hello文件夹跟huapu文件夹

### 3、模板引擎

JSP,Velocity,Freemaker,Thymeleaf

![template](images\template.png)

springboot推荐Thymelef  语法更简单,功能更强大 

[Thymelef 官网](https://www.thymeleaf.org/)

[官方文档链接地址](https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.pdf)

#### 1、引入thymeleaf

```xml


    org.springframework.boot
    spring-boot-starter-thymeleaf

```

thymeleaf 3主程序  layout2.0以上版本

#### 2、thymeleaf使用语法

内部文件ThymeleafProperties.java

```java
@ConfigurationProperties(
    prefix = "spring.thymeleaf"
)
public class ThymeleafProperties {
    private static final Charset DEFAULT_ENCODING;
    public static final String DEFAULT_PREFIX = "classpath:/templates/";
    public static final String DEFAULT_SUFFIX = ".html";
    private boolean checkTemplate = true;
    private boolean checkTemplateLocation = true;
    private String prefix = "classpath:/templates/";
    private String suffix = ".html";
```

```java
@RequestMapping("/success")
public String success(Map map) {
    //寻找对应的文件classpath:/templates/success.html 页面
    map.put("hello","你好");
    return "success";
}
```

使用:

##### 1)名称空间

```html

```

##### 2)使用语法

```html


   
    Title


   

成功


   
这是欢迎页面


你可能感兴趣的:(spring,boot)