浅谈SpringBoot

1、Spring Boot 入门
一、Spring Boot 简介javascript

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

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

J2EE开发的一站式解决方案;
二、微服务前端

2014,martin fowlerjava

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

一个应用应该是一组小型服务;能够经过HTTP的方式进行互通;react

单体应用:ALL IN ONEjquery

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

详细参照微服务文档git

三、环境准备

http://www.gulixueyuan.com/ 谷粒学院

环境约束

–jdk1.8:Spring Boot 推荐jdk1.7及以上;java version "1.8.0_112"

–maven3.x:maven 3.3以上版本;Apache Maven 3.3.9

–IntelliJIDEA2017:IntelliJ IDEA 2017.2.2 x6四、STS

–SpringBoot 1.5.9.RELEASE:1.5.9;

统一环境;

一、MAVEN设置;

给maven 的settings.xml配置文件的profiles标签添加


jdk-1.8

true
1.8


<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>


二、IDEA设置

整合maven进来;

四、Spring Boot HelloWorld

一个功能:

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

一、建立一个maven工程;(jar)

二、导入spring boot相关的依赖



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



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



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


三、编写一个主程序;启动Spring Boot应用


/**

  • @SpringBootApplication 来标注一个主程序类,说明这是一个Spring Boot应用
    */
    @SpringBootApplication
    public class HelloWorldMainApplication {

    public static void main(String[] args) {

    // Spring应用启动起来
    SpringApplication.run(HelloWorldMainApplication.class,args);
    }
    }
    四、编写相关的Controller、Service

@Controller
public class HelloController {

@ResponseBody
@RequestMapping("/hello")
public String hello(){
return "Hello World!";
}
}

五、运行主程序测试

六、简化部署

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





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



将这个应用打成jar包,直接使用java -jar的命令进行执行;

五、Hello World探究

一、POM文件

一、父项目


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


他的父项目是

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

他来真正管理Spring Boot应用里面的全部依赖版本;

Spring Boot的版本仲裁中心;

之后咱们导入依赖默认是不须要写版本;(没有在dependencies里面管理的依赖天然须要声明版本号)

二、启动器


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

spring-boot-starter-==web==:

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

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

二、主程序类,主入口类

/**

  • @SpringBootApplication 来标注一个主程序类,说明这是一个Spring Boot应用
    */
    @SpringBootApplication
    public class HelloWorldMainApplication {

    public static void main(String[] args) {

    // Spring应用启动起来
    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开启自动配置功能;这样自动配置才能生效;

@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
​ @AutoConfigurationPackage:自动配置包

​ @Import(AutoConfigurationPackages.Registrar.class):

​ Spring的底层注解@Import,给容器中导入一个组件;导入的组件由AutoConfigurationPackages.Registrar.class;

==将主配置类(@SpringBootApplication标注的类)的所在包及下面全部子包里面的全部组件扫描到Spring容器;==

​ @Import(EnableAutoConfigurationImportSelector.class);

​ 给容器中导入组件?

​ EnableAutoConfigurationImportSelector:导入哪些组件的选择器;

​ 将全部须要导入的组件以全类名的方式返回;这些组件就会被添加到容器中;

​ 会给容器中导入很是多的自动配置类(xxxAutoConfiguration);就是给容器中导入这个场景须要的全部组件,并配置好这些组件;

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

​ SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,classLoader);

==Spring Boot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值,将这些值做为自动配置类导入到容器中,自动配置类就生效,帮咱们进行自动配置工做;==之前咱们须要本身配置的东西,自动配置类都帮咱们;

J2EE的总体整合解决方案和自动配置都在spring-boot-autoconfigure-1.5.9.RELEASE.jar;

==Spring注解版(谷粒学院)==

六、使用Spring Initializer快速建立Spring Boot项目

一、IDEA:使用 Spring Initializer快速建立项目

IDE都支持使用Spring的项目建立向导快速建立一个Spring Boot项目;

选择咱们须要的模块;向导会联网建立Spring Boot项目;

默认生成的Spring Boot项目;

主程序已经生成好了,咱们只须要咱们本身的逻辑

resources文件夹中目录结构

static:保存全部的静态资源; js css images;

templates:保存全部的模板页面;(Spring Boot默认jar包使用嵌入式的Tomcat,默认不支持JSP页面);可使用模板引擎(freemarker、thymeleaf);

application.properties:Spring Boot应用的配置文件;能够修改一些默认设置;

二、STS使用 Spring Starter Project快速建立项目

2、配置文件
一、配置文件

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:


8081

二、YAML语法:

一、基本语法

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

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

server:
port: 8081
path: /hello
属性和值也是大小写敏感;

二、值的写法

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

​ 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]

三、配置文件值注入

配置文件

person:
lastName: hello
age: 18
boss: false
birth: 2017/12/12
maps: {k1: v1,k2: 12}
lists:
- lisi
- zhaoliu
dog:
name: 小狗
age: 12
person:
lastName: hello
age: 18
boss: false
birth: 2017/12/12
maps: {k1: v1,k2: 12}
lists:
- lisi
- zhaoliu
dog:
name: 小狗
age: 12
javaBean:

/**

  • 将配置文件中配置的每个属性的值,映射到这个组件中
  • @ConfigurationProperties:告诉SpringBoot将本类中的全部属性和配置文件中相关的配置进行绑定;
  • prefix = "person":配置文件中哪一个下面的全部属性进行一一映射
  • 只有这个组件是容器中的组件,才能容器提供的@ConfigurationProperties功能;
  • */
    @Component
    @ConfigurationProperties(prefix = "person")
    public class Person {

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

    private Map<String,Object> maps;
    private List lists;
    private Dog dog;

    咱们能够导入配置文件处理器,之后编写配置就有提示了

    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

    一、properties配置文件在idea中默认utf-8可能会乱码

    调整

    二、@Value获取值和@ConfigurationProperties获取值比较

    @ConfigurationProperties @Value
    功能 批量注入配置文件中的属性 一个个指定
    松散绑定(松散语法) 支持 不支持
    SpEL 不支持 支持
    JSR303数据校验 支持 不支持
    复杂类型封装 支持 不支持
    配置文件yml仍是properties他们都能获取到值;

    若是说,咱们只是在某个业务逻辑中须要获取一下配置文件中的某项值,使用@Value;

    若是说,咱们专门编写了一个javaBean来和配置文件进行映射,咱们就直接使用@ConfigurationProperties;

    三、配置文件注入值数据校验

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

    /**
    *
    *
    *
    /

    //lastName必须是邮箱格式
    @Email
    //@Value("${person.last-name}")
    private String lastName;
    //@Value("#{11
    2}")
    private Integer age;
    //@Value("true")
    private Boolean boss;

    private Date birth;
    private Map<String,Object> maps;
    private List lists;
    private Dog dog;

    四、@PropertySource&@ImportResource&@Bean

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

    /**

    • 将配置文件中配置的每个属性的值,映射到这个组件中
    • @ConfigurationProperties:告诉SpringBoot将本类中的全部属性和配置文件中相关的配置进行绑定;
    • prefix = "person":配置文件中哪一个下面的全部属性进行一一映射
    • 只有这个组件是容器中的组件,才能容器提供的@ConfigurationProperties功能;
    • @ConfigurationProperties(prefix = "person")默认从全局配置文件中获取值;
    • */
      @PropertySource(value = {"classpath:person.properties"})
      @Component
      @ConfigurationProperties(prefix = "person")
      //@Validated
      public class Person {

      /**
      • <property name="lastName" value="字面量/${key}从环境变量、配置文件中获取值/#{SpEL}"></property>

      • /

        //lastName必须是邮箱格式
        // @Email
        //@Value("${person.last-name}")
        private String lastName;
        //@Value("#{11
        2}")
        private Integer age;
        //@Value("true")
        private Boolean boss;

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

    Spring Boot里面没有Spring的配置文件,咱们本身编写的配置文件,也不能自动识别;

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

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

    不来编写Spring的配置文件






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

    一、配置类@Configuration------>Spring配置文件

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

    /**

    • @Configuration:指明当前类是一个配置类;就是来替代以前的Spring配置文件
    • 在配置文件中用 标签添加组件
    • */
      @Configuration
      public class MyAppConfig {

      //将方法的返回值添加到容器中;容器中这个组件默认的id就是方法名
      @Bean
      public HelloService helloService02(){
      System.out.println("配置类@Bean给容器中添加组件了...");
      return new HelloService();
      }
      }
      四、配置文件占位符

    一、随机数

    ${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

    五、Profile

    一、多Profile文件

    咱们在主配置文件编写的时候,文件名能够是 application-{profile}.properties/yml

    默认使用application.properties的配置;

    二、yml支持多文档块方式


    server:
    port: 8081
    spring:
    profiles:
    active: prod

    ---
    server:
    port: 8083
    spring:
    profiles: dev


    ---

    server:
    port: 8084
    spring:
    profiles: prod #指定属于哪一个环境

    三、激活指定profile

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

    ​ 二、命令行:

    ​ java -jar spring-boot-02-config-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev;

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

    ​ 三、虚拟机参数;

    ​ -Dspring.profiles.active=dev

    六、配置文件加载位置

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

    –file:./config/

    –file:./

    –classpath:/config/

    –classpath:/

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

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

    ==咱们还能够经过spring.config.location来改变默认的配置文件位置==

    项目打包好之后,咱们可使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;指定配置文件和默认加载的这些配置文件共同起做用造成互补配置;

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

    七、外部配置加载顺序

    ==SpringBoot也能够从如下位置加载配置; 优先级从高到低;高优先级的配置覆盖低优先级的配置,全部的配置会造成互补配置==

    1.命令行参数

    全部的配置均可以在命令行上进行指定

    java -jar spring-boot-02-config-02-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)配置文件

    ==再来加载不带profile==

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

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

    10.@Configuration注解类上的@PropertySource

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

    全部支持的配置加载来源;

    参考官方文档

    八、自动配置原理

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

    配置文件能配置的属性参照

    一、自动配置原理:

    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的值加入到了容器中;==

    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 //表示这是一个配置类,之前编写的配置文件同样,也能够给容器中添加组件
    @EnableConfigurationProperties(HttpEncodingProperties.class) //启动指定类的ConfigurationProperties功能;将配置文件中对应的值和HttpEncodingProperties绑定起来;并把HttpEncodingProperties加入到ioc容器中

    @ConditionalOnWebApplication //Spring底层@Conditional注解(Spring注解版),根据不一样的条件,若是知足指定的条件,整个配置类里面的配置就会生效; 判断当前应用是不是web应用,若是是,当前配置类生效

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

    @ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true) //判断配置文件中是否存在某个配置 spring.http.encoding.enabled;若是不存在,判断也是成立的
    //即便咱们配置文件中不配置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");

    精髓:

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

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

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

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

    xxxxAutoConfigurartion:自动配置类;

    给容器中添加组件

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

    二、细节

    一、@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存在指定项
    自动配置类必须在必定的条件下才能生效;

    咱们怎么知道哪些自动配置类生效;

    ==咱们能够经过启用 debug=true属性;来让控制台打印自动配置报告==,这样咱们就能够很方便的知道哪些自动配置类生效;

    =========================
    AUTO-CONFIGURATION REPORT
    =========================


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

    DispatcherServletAutoConfiguration matched:
    - @ConditionalOnClass found required class 'org.springframework.web.servlet.DispatcherServlet'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
    - @ConditionalOnWebApplication (required) found StandardServletEnvironment (OnWebApplicationCondition)

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


    ActiveMQAutoConfiguration:
    Did not match:
    - @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.ActiveMQConnectionFactory' (OnClassCondition)

    AopAutoConfiguration:
    Did not match:
    - @ConditionalOnClass did not find required classes 'org.aspectj.lang.annotation.Aspect', 'org.aspectj.lang.reflect.Advice' (OnClassCondition)

    3、日志
    一、日志框架

    小张;开发一个大型系统;

    ​ 一、System.out.println("");将关键数据打印在控制台;去掉?写在一个文件?

    ​ 二、框架来记录系统的一些运行时信息;日志框架 ; zhanglogging.jar;

    ​ 三、高大上的几个功能?异步模式?自动归档?xxxx? zhanglogging-good.jar?

    ​ 四、将之前框架卸下来?换上新的框架,从新修改以前相关的API;zhanglogging-prefect.jar;

    ​ 五、JDBC---数据库驱动;

    ​ 写了一个统一的接口层;日志门面(日志的一个抽象层);logging-abstract.jar;

    ​ 给项目中导入具体的日志实现就好了;咱们以前的日志框架都是实现的抽象层;

    市面上的日志框架;

    JUL、JCL、Jboss-logging、logback、log4j、log4j二、slf4j....

    日志门面 (日志的抽象层) 日志实现
    JCL(Jakarta Commons Logging) SLF4j(Simple Logging Facade for Java) jboss-logging Log4j JUL(java.util.logging) Log4j2 Logback
    左边选一个门面(抽象层)、右边来选一个实现;

    日志门面: SLF4J;

    日志实现:Logback;

    SpringBoot:底层是Spring框架,Spring框架默认是用JCL;‘

    ​ ==SpringBoot选用 SLF4j和logback;==

    二、SLF4j使用

    一、如何在系统中使用SLF4j https://www.slf4j.org

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

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

    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");
    }
    }
    图示;

    每个日志的实现框架都有本身的配置文件。使用slf4j之后,配置文件仍是作成日志实现框架本身自己的配置文件;

    二、遗留问题

    a(slf4j+logback): Spring(commons-logging)、Hibernate(jboss-logging)、MyBatis、xxxx

    统一日志记录,即便是别的框架和我一块儿统一使用slf4j进行输出?

    如何让系统中全部的日志都统一到slf4j;

    ==一、将系统中其余日志框架先排除出去;==

    ==二、用中间包来替换原有的日志框架;==

    ==三、咱们导入slf4j其余的实现==

    三、SpringBoot日志关系

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

    SpringBoot使用它来作日志功能;

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

    底层依赖关系

    总结:

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

    ​ 2)、SpringBoot也把其余的日志都替换成了slf4j;

    ​ 3)、中间替换包?

    @SuppressWarnings("rawtypes")
    public abstract class LogFactory {

    static String UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J = "http://www.slf4j.org/codes.html#unsupported_operation_in_jcl_over_slf4j";

    static LogFactory logFactory = new SLF4JLogFactory();

    ​ 4)、若是咱们要引入其余框架?必定要把这个框架的默认日志依赖移除掉?

    ​ Spring框架用的是commons-logging;

    <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

    ==SpringBoot能自动适配全部的日志,并且底层使用slf4j+logback的方式记录日志,引入其余框架的时候,只须要把这个框架依赖的日志框架排除掉便可;==

    四、日志使用;

    一、默认配置

    SpringBoot默认帮咱们配置好了日志;

    //记录器
    Logger logger = LoggerFactory.getLogger(getClass());
    @Test
    public void contextLoads() {
        //System.out.println();


    //日志的级别;
    //由低到高 trace<debug<info<warn<error
    //能够调整输出的日志级别;日志就只会在这个级别以之后的高级别生效
    logger.trace("这是trace日志...");
    logger.debug("这是debug日志...");
    //SpringBoot默认给咱们使用的是info级别的,没有指定级别的就用SpringBoot默认规定的级别;root级别
    logger.info("这是info日志...");
    logger.warn("这是warn日志...");
    logger.error("这是error日志...");


    }

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

    SpringBoot修改日志的默认配置

    logging.level.com.atguigu=trace

    logging.path=

    不指定路径在当前项目下生成springboot.log日志

    能够指定完整的路径;

    logging.file=G:/springboot.log

    在当前磁盘的根路径下建立spring文件夹和里面的log文件夹;使用 spring.log 做为默认文件

    logging.path=/spring/log

    在控制台输出的日志的格式

    logging.pattern.console=%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n

    指定文件中日志输出的格式

    logging.pattern.file=%d{yyyy-MM-dd} === [%thread] === %-5level === %logger{50} ==== %msg%n
    logging.file logging.path Example Description
    (none) (none) 只在控制台输出
    指定文件名 (none) my.log 输出日志到my.log文件
    (none) 指定目录 /var/log 输出到指定目录的 spring.log 文件中
    二、指定配置

    给类路径下放上每一个日志框架本身的配置文件便可;SpringBoot就不使用他默认配置的了

    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的高级Profile功能



    能够指定某段配置只在某个环境下生效


    如:





    %d{yyyy-MM-dd HH:mm:ss.SSS} ----> [%thread] ---> %-5level %logger{50} - %msg%n


    %d{yyyy-MM-dd HH:mm:ss.SSS} ==== [%thread] ==== %-5level %logger{50} - %msg%n


    若是使用logback.xml做为日志配置文件,还要使用profile功能,会有如下错误

    no applicable action for [springProfile]

    五、切换日志框架

    能够按照slf4j的日志适配图,进行相关的切换;

    slf4j+log4j的方式;


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


    logback-classic
    ch.qos.logback


    log4j-over-slf4j
    org.slf4j





    org.slf4j
    slf4j-log4j12

    切换为log4j2


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


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





    org.springframework.boot
    spring-boot-starter-log4j2

    4、Web开发
    一、简介

    使用SpringBoot;

    1)、建立SpringBoot应用,选中咱们须要的模块;

    2)、SpringBoot已经默认将这些场景配置好了,只须要在配置文件中指定少许配置就能够运行起来

    3)、本身编写业务代码;

    自动配置原理?

    这个场景SpringBoot帮咱们配置了什么?能不能修改?能修改哪些配置?能不能扩展?xxx

    xxxxAutoConfiguration:帮咱们给容器中自动配置组件;
    xxxxProperties:配置类来封装配置文件的内容;

    二、SpringBoot对静态资源的映射规则;

    @ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
    public class ResourceProperties implements ResourceLoaderAware {
    //能够设置和静态资源有关的参数,缓存时间等

    WebMvcAuotConfiguration:
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            if (!this.resourceProperties.isAddMappings()) {
                logger.debug("Default resource handling disabled");
                return;
            }
            Integer cachePeriod = this.resourceProperties.getCachePeriod();
            if (!registry.hasMappingForPattern("/webjars/**")) {
                customizeResourceHandlerRegistration(
                        registry.addResourceHandler("/webjars/**")
                                .addResourceLocations(
                                        "classpath:/META-INF/resources/webjars/")
                        .setCachePeriod(cachePeriod));
            }
            String staticPathPattern = this.mvcProperties.getStaticPathPattern();
            //静态资源文件夹映射
            if (!registry.hasMappingForPattern(staticPathPattern)) {
                customizeResourceHandlerRegistration(
                        registry.addResourceHandler(staticPathPattern)
                                .addResourceLocations(
                                        this.resourceProperties.getStaticLocations())
                        .setCachePeriod(cachePeriod));
            }
        }


    //配置欢迎页映射
    @Bean
    public WelcomePageHandlerMapping welcomePageHandlerMapping(
    ResourceProperties resourceProperties) {
    return new WelcomePageHandlerMapping(resourceProperties.getWelcomePage(),
    this.mvcProperties.getStaticPathPattern());
    }

    //配置喜欢的图标
    @Configuration
    @ConditionalOnProperty(value = "spring.mvc.favicon.enabled", matchIfMissing = true)
    public static class FaviconConfiguration {

    private final ResourceProperties resourceProperties;

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

    @Bean
    public SimpleUrlHandlerMapping faviconHandlerMapping() {
    SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
    mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
    //全部 /favicon.ico
    mapping.setUrlMap(Collections.singletonMap("
    /favicon.ico",
    faviconRequestHandler()));
    return mapping;
    }

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

    }

    ==1)、全部 /webjars/** ,都去 classpath:/META-INF/resources/webjars/ 找资源;==

    ​ webjars:以jar包的方式引入静态资源;

    http://www.webjars.org/

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

    在访问的时候只须要写webjars下面资源的名称便可

    org.webjars
    jquery
    3.3.1

    ==2)、"/**" 访问当前项目的任何资源,都去(静态资源的文件夹)找映射==

    "classpath:/META-INF/resources/",
    "classpath:/resources/",
    "classpath:/static/",
    "classpath:/public/"
    "/":当前项目的根路径
    localhost:8080/abc === 去静态资源文件夹里面找abc

    ==3)、欢迎页; 静态资源文件夹下的全部index.html页面;被"/**"映射;==

    ​ localhost:8080/ 找index页面

    ==4)、全部的 **/favicon.ico 都是在静态资源文件下找;==

    三、模板引擎

    JSP、Velocity、Freemarker、Thymeleaf

    SpringBoot推荐的Thymeleaf;

    语法更简单,功能更强大;

    一、引入thymeleaf;

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

    切换thymeleaf版本

    <thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>


    <thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version>

    二、Thymeleaf使用

    @ConfigurationProperties(prefix = "spring.thymeleaf")
    public class ThymeleafProperties {

    private static final Charset DEFAULT_ENCODING = Charset.forName("UTF-8");

    private static final MimeType DEFAULT_CONTENT_TYPE = MimeType.valueOf("text/html");

    public static final String DEFAULT_PREFIX = "classpath:/templates/";

    public static final String DEFAULT_SUFFIX = ".html";
    //
    只要咱们把HTML页面放在classpath:/templates/,thymeleaf就能自动渲染;

    使用:

    一、导入thymeleaf的名称空间

    二、使用thymeleaf语法;

    <!DOCTYPE html>



    Title


    成功!



    这是显示欢迎信息



    三、语法规则

    1)、th:text;改变当前元素里面的文本内容;

    ​ th:任意html属性;来替换原生属性的值

    2)、表达式?

    Simple expressions:(表达式语法)
    Variable Expressions: ${...}:获取变量值;OGNL;
    1)、获取对象的属性、调用方法
    2)、使用内置的基本对象:
    #ctx : the context object.
    #vars: the context variables.
    #locale : the context locale.
    #request : (only in Web Contexts) the HttpServletRequest object.
    #response : (only in Web Contexts) the HttpServletResponse object.
    #session : (only in Web Contexts) the HttpSession object.
    #servletContext : (only in Web Contexts) the ServletContext object.

    ${session.foo}
            3)、内置的一些工具对象:

    execInfo : information about the template being processed.

    messages : methods for obtaining externalized messages inside variables expressions, in the same way as they would be obtained using #{…} syntax.

    uris : methods for escaping parts of URLs/URIs

    conversions : methods for executing the configured conversion service (if any).

    dates : methods for java.util.Date objects: formatting, component extraction, etc.

    calendars : analogous to #dates , but for java.util.Calendar objects.

    numbers : methods for formatting numeric objects.

    strings : methods for String objects: contains, startsWith, prepending/appending, etc.

    objects : methods for objects in general.

    bools : methods for boolean evaluation.

    arrays : methods for arrays.

    lists : methods for lists.

    sets : methods for sets.

    maps : methods for maps.

    aggregates : methods for creating aggregates on arrays or collections.

    ids : methods for dealing with id attributes that might be repeated (for example, as a result of an iteration).


    Selection Variable Expressions: *{...}:选择表达式:和${}在功能上是同样;
    补充:配合 th:object="${session.user}:


    Name: Sebastian.


    Surname: Pepper.


    Nationality: Saturn.


    Message Expressions: #{...}:获取国际化内容
    Link URL Expressions: @{...}:定义URL;
            @{/order/process(execId=${execId},execType='FAST')}
    Fragment Expressions: ~{...}:片断引用表达式
            <div th:insert="~{commons :: main}">...</div>

    Literals(字面量)
    Text literals: 'one text' , 'Another one!' ,…
    Number literals: 0 , 34 , 3.0 , 12.3 ,…
    Boolean literals: true , false
    Null literal: null
    Literal tokens: one , sometext , main ,…
    Text operations:(文本操做)
    String concatenation: +
    Literal substitutions: |The name is ${name}|
    Arithmetic operations:(数学运算)
    Binary operators: + , - , * , / , %
    Minus sign (unary operator): -
    Boolean operations:(布尔运算)
    Binary operators: and , or
    Boolean negation (unary operator): ! , not
    Comparisons and equality:(比较运算)
    Comparators: > , < , >= , <= ( gt , lt , ge , le )
    Equality operators: == , != ( eq , ne )
    Conditional operators:条件运算(三元运算符)
    If-then: (if) ? (then)
    If-then-else: (if) ? (then) : (else)
    Default: (value) ?: (defaultvalue)
    Special tokens:
    No-Operation: _
    四、SpringMVC自动配置

    https://docs.spring.io/spring-boot/docs/1.5.10.RELEASE/reference/htmlsingle/#boot-features-developing-web-applications

    1. Spring MVC auto-configuration

    Spring Boot 自动配置好了SpringMVC

    如下是SpringBoot对SpringMVC的默认配置:==(WebMvcAutoConfiguration)==

    Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.

    自动配置了ViewResolver(视图解析器:根据方法的返回值获得视图对象(View),视图对象决定如何渲染(转发?重定向?))

    ContentNegotiatingViewResolver:组合全部的视图解析器的;

    ==如何定制:咱们能够本身给容器中添加一个视图解析器;自动的将其组合进来;==

    Support for serving static resources, including support for WebJars (see below).静态资源文件夹路径,webjars

    Static index.html support. 静态首页访问

    Custom Favicon support (see below). favicon.ico

    自动注册了 of Converter, GenericConverter, Formatter beans.

    Converter:转换器; public String hello(User user):类型转换使用Converter

    Formatter 格式化器; 2017.12.17===Date;

    @Bean
        @ConditionalOnProperty(prefix = "spring.mvc", name = "date-format")//在文件中配置日期格式化的规则
        public Formatter<Date> dateFormatter() {
            return new DateFormatter(this.mvcProperties.getDateFormat());//日期格式化组件
        }

    ​ ==本身添加的格式化器转换器,咱们只须要放在容器中便可==

    Support for HttpMessageConverters (see below).

    HttpMessageConverter:SpringMVC用来转换Http请求和响应的;User---Json;

    HttpMessageConverters 是从容器中肯定;获取全部的HttpMessageConverter;

    ==本身给容器中添加HttpMessageConverter,只须要将本身的组件注册容器中(@Bean,@Component)==

    Automatic registration of MessageCodesResolver (see below).定义错误代码生成规则

    Automatic use of a ConfigurableWebBindingInitializer bean (see below).

    ==咱们能够配置一个ConfigurableWebBindingInitializer来替换默认的;(添加到容器)==

    初始化WebDataBinder;
    请求数据=====JavaBean;
    org.springframework.boot.autoconfigure.web:web的全部自动场景;

    If you want to keep Spring Boot MVC features, and you just want to add additional MVC configuration (interceptors, formatters, view controllers etc.) you can add your own @Configuration class of type WebMvcConfigurerAdapter, but without @EnableWebMvc. If you wish to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter or ExceptionHandlerExceptionResolver you can declare a WebMvcRegistrationsAdapter instance providing such components.

    If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.

    二、扩展SpringMVC

    <mvc:view-controller path="/hello" view-name="success"/>
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/hello"/>
            <bean></bean>
        </mvc:interceptor>
    </mvc:interceptors>

    ==编写一个配置类(@Configuration),是WebMvcConfigurerAdapter类型;不能标注@EnableWebMvc==;

    既保留了全部的自动配置,也能用咱们扩展的配置;

    //使用WebMvcConfigurerAdapter能够来扩展SpringMVC的功能
    @Configuration
    public class MyMvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
    // super.addViewControllers(registry);
    //浏览器发送 /atguigu 请求来到 success
    registry.addViewController("/atguigu").setViewName("success");
    }
    }
    原理:

    ​ 1)、WebMvcAutoConfiguration是SpringMVC的自动配置类

    ​ 2)、在作其余自动配置时会导入;@Import(EnableWebMvcConfiguration.class)

    @Configuration
    public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration {
      private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();


    //从容器中获取全部的WebMvcConfigurer
    @Autowired(required = false)
    public void setConfigurers(List configurers) {
    if (!CollectionUtils.isEmpty(configurers)) {
    this.configurers.addWebMvcConfigurers(configurers);
    //一个参考实现;将全部的WebMvcConfigurer相关配置都来一块儿调用;
    @Override
    // public void addViewControllers(ViewControllerRegistry registry) {
    // for (WebMvcConfigurer delegate : this.delegates) {
    // delegate.addViewControllers(registry);
    // }
    }
    }
    }
    ​ 3)、容器中全部的WebMvcConfigurer都会一块儿起做用;

    ​ 4)、咱们的配置类也会被调用;

    ​ 效果:SpringMVC的自动配置和咱们的扩展配置都会起做用;

    三、全面接管SpringMVC;

    SpringBoot对SpringMVC的自动配置不须要了,全部都是咱们本身配置;全部的SpringMVC的自动配置都失效了

    咱们须要在配置类中添加@EnableWebMvc便可;

    //使用WebMvcConfigurerAdapter能够来扩展SpringMVC的功能
    @EnableWebMvc
    @Configuration
    public class MyMvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
    // super.addViewControllers(registry);
    //浏览器发送 /atguigu 请求来到 success
    registry.addViewController("/atguigu").setViewName("success");
    }
    }
    原理:

    为何@EnableWebMvc自动配置就失效了;

    1)@EnableWebMvc的核心

    @Import(DelegatingWebMvcConfiguration.class)
    public @interface EnableWebMvc {
    2)、

    @Configuration
    public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
    3)、

    @Configuration
    @ConditionalOnWebApplication
    @ConditionalOnClass({ Servlet.class, DispatcherServlet.class,
    WebMvcConfigurerAdapter.class })
    //容器中没有这个组件的时候,这个自动配置类才生效
    @ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
    @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
    @AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
    ValidationAutoConfiguration.class })
    public class WebMvcAutoConfiguration {
    4)、@EnableWebMvc将WebMvcConfigurationSupport组件导入进来;

    5)、导入的WebMvcConfigurationSupport只是SpringMVC最基本的功能;

    五、如何修改SpringBoot的默认配置

    模式:

    ​ 1)、SpringBoot在自动配置不少组件的时候,先看容器中有没有用户本身配置的(@Bean、@Component)若是有就用用户配置的,若是没有,才自动配置;若是有些组件能够有多个(ViewResolver)将用户配置的和本身默认的组合起来;

    ​ 2)、在SpringBoot中会有很是多的xxxConfigurer帮助咱们进行扩展配置

    ​ 3)、在SpringBoot中会有不少的xxxCustomizer帮助咱们进行定制配置

    六、RestfulCRUD

    1)、默认访问首页


    //使用WebMvcConfigurerAdapter能够来扩展SpringMVC的功能
    //@EnableWebMvc 不要接管SpringMVC
    @Configuration
    public class MyMvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
    // super.addViewControllers(registry);
    //浏览器发送 /atguigu 请求来到 success
    registry.addViewController("/atguigu").setViewName("success");
    }

    //全部的WebMvcConfigurerAdapter组件都会一块儿起做用
    @Bean //将组件注册在容器
    public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
    WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/").setViewName("login");
    registry.addViewController("/index.html").setViewName("login");
    }
    };
    return adapter;
    }
    }

    2)、国际化

    1)、编写国际化配置文件;

    2)、使用ResourceBundleMessageSource管理国际化资源文件

    3)、在页面使用fmt:message取出国际化内容

    步骤:

    1)、编写国际化配置文件,抽取页面须要显示的国际化消息

    2)、SpringBoot自动配置好了管理国际化资源文件的组件;

    @ConfigurationProperties(prefix = "spring.messages")
    public class MessageSourceAutoConfiguration {

    /**
     * Comma-separated list of basenames (essentially a fully-qualified classpath
     * location), each following the ResourceBundle convention with relaxed support for
     * slash based locations. If it doesn't contain a package qualifier (such as
     * "org.mypackage"), it will be resolved from the classpath root.
     */
    private String basename = "messages";  
    //咱们的配置文件能够直接放在类路径下叫messages.properties;
    
    @Bean
    public MessageSource messageSource() {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        if (StringUtils.hasText(this.basename)) {
            //设置国际化资源文件的基础名(去掉语言国家代码的)
            messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray(
                    StringUtils.trimAllWhitespace(this.basename)));
        }
        if (this.encoding != null) {
            messageSource.setDefaultEncoding(this.encoding.name());
        }
        messageSource.setFallbackToSystemLocale(this.fallbackToSystemLocale);
        messageSource.setCacheSeconds(this.cacheSeconds);
        messageSource.setAlwaysUseMessageFormat(this.alwaysUseMessageFormat);
        return messageSource;
    }

    3)、去页面获取国际化的值;

    <!DOCTYPE html>






    Signin Template for Bootstrap












    效果:根据浏览器语言设置的信息切换了国际化;

    原理:

    ​ 国际化Locale(区域信息对象);LocaleResolver(获取区域信息对象);

    @Bean
        @ConditionalOnMissingBean
        @ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
        public LocaleResolver localeResolver() {
            if (this.mvcProperties
                    .getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
                return new FixedLocaleResolver(this.mvcProperties.getLocale());
            }
            AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
            localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
            return localeResolver;
        }

    默认的就是根据请求头带来的区域信息获取Locale进行国际化
    4)、点击连接切换国际化

    /**

    • 能够在链接上携带区域信息
      */
      public class MyLocaleResolver implements LocaleResolver {

      @Override
      public Locale resolveLocale(HttpServletRequest request) {
      String l = request.getParameter("l");
      Locale locale = Locale.getDefault();
      if(!StringUtils.isEmpty(l)){
      String[] split = l.split("_");
      locale = new Locale(split[0],split[1]);
      }
      return locale;
      }

      @Override
      public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {

      }
      }


      @Bean
      public LocaleResolver localeResolver(){
      return new MyLocaleResolver();
      }
      }


      3)、登录

    开发期间模板引擎页面修改之后,要实时生效

    1)、禁用模板引擎的缓存

    禁用缓存

    spring.thymeleaf.cache=false
    2)、页面修改完成之后ctrl+f9:从新编译;

    登录错误消息的显示

    4)、拦截器进行登录检查

    拦截器


    /**

    • 登录检查,
      */
      public class LoginHandlerInterceptor implements HandlerInterceptor {
      //目标方法执行以前
      @Override
      public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
      Object user = request.getSession().getAttribute("loginUser");
      if(user == null){
      //未登录,返回登录页面
      request.setAttribute("msg","没有权限请先登录");
      request.getRequestDispatcher("/index.html").forward(request,response);
      return false;
      }else{
      //已登录,放行请求
      return true;
      }

      }

      @Override
      public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

      }

      @Override
      public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

      }
      }

    注册拦截器

    //全部的WebMvcConfigurerAdapter组件都会一块儿起做用
    @Bean //将组件注册在容器
    public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
    WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/").setViewName("login");
    registry.addViewController("/index.html").setViewName("login");
    registry.addViewController("/main.html").setViewName("dashboard");
    }

    //注册拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    //super.addInterceptors(registry);
    //静态资源; .css , .js
    //SpringBoot已经作好了静态资源映射
    registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**")
    .excludePathPatterns("/index.html","/","/user/login");
    }
    };
    return adapter;
    }
    5)、CRUD-员工列表

    实验要求:

    1)、RestfulCRUD:CRUD知足Rest风格;

    URI: /资源名称/资源标识 HTTP请求方式区分对资源CRUD操做

    普通CRUD(uri来区分操做) RestfulCRUD
    查询 getEmp emp---GET
    添加 addEmp?xxx emp---POST
    修改 updateEmp?id=xxx&xxx=xx emp/{id}---PUT
    删除 deleteEmp?id=1 emp/{id}---DELETE
    2)、实验的请求架构;

    实验功能 请求URI 请求方式
    查询全部员工 emps GET
    查询某个员工(来到修改页面) emp/1 GET
    来到添加页面 emp GET
    添加员工 emp POST
    来到修改页面(查出员工进行信息回显) emp/1 GET
    修改员工 emp PUT
    删除员工 emp/1 DELETE
    3)、员工列表:

    thymeleaf公共页面元素抽取

    一、抽取公共片断


    © 2011 The Good Thymes Virtual Grocery


    二、引入公共片断

    ~{templatename::selector}:模板名::选择器
    ~{templatename::fragmentname}:模板名::片断名

    三、默认效果:
    insert的公共片断在div标签中
    若是使用th:insert等属性进行引入,能够不用写~{}:
    行内写法能够加上:[[~{}]];[(~{})];

    三种引入公共片断的th属性:

    th:insert:将公共片断整个插入到声明引入的元素中

    th:replace:将声明引入的元素替换为公共片断

    th:include:将被引入的片断的内容包含进这个标签中

    © 2011 The Good Thymes Virtual Grocery


    引入方式





    效果


    © 2011 The Good Thymes Virtual Grocery




    © 2011 The Good Thymes Virtual Grocery



    © 2011 The Good Thymes Virtual Grocery

    引入片断的时候传入参数:


相关文章
相关标签/搜索