SpringBoot笔记

一、SpringBoot入门

1、SpringBoot简介

简化spring应用的框架

整个Spring技术栈的大整合

j2ee开发的一站式解决方案

2、微服务

2014 马丁·福勒(martin fowler)

微服务: 架构风格

一个应用应该是一组小型微服务,可以通过HTTP的方式去进行访问

单体应用: ALL IN ONE

微服务:每一个功能元素最终都是一个独立运行或者升级的软件单元

3、 环境的准备

环境:

- jdk1.8  : SpringBoot官方推荐的1.7以上  java version "1.8.0_171"
- maven: Apache Maven 3.6.0
- idea: IntelliJ IDEA 2020.1 x64
- SpringBoot: 2.3.0

4、SpringBoot HelloWorld

一个需求:

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

  1. 创建Maven工程
  2. 导入Springboot相关依赖
  3. 编写主程序:启动SpringBoot应用
  4. 编写相关的controller、service
  5. 运行主程序进行测试
  6. 简化部署
    1. Jar包 打包过后直接使用 java -jar 在cmd里运行

5、Hello World 探究

5.1、POM文件

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.0.RELEASE</version>
</parent>他的父项目是
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>2.3.0.RELEASE</version></parent>他是真正用来管理Spring boot 应用的所有依赖版本

SpringBoot的版本仲裁中心

​ 我们以后导入依赖的时候都不需要写版本(没有写在dependencies中的需要单独声明版本号)

5.2、 启动器

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

spring-boot-starter == web ==

​ spring-boot-starter :springboot 的场景启动器,帮我们导入web模块正常运行所需要的组件

SpringBoot把所有的功能场景都提取出来,做成一个个starter(启动器),我们只需要在项目里导入相关的starter相关的场景就会把所有相关的依赖都会导入进来。要用什么功能就达到入什么场景的启动器

5.3、主程序类和入口类

/***   @SpringBootApplication 来标准一个主程序类,说明当前是一个SpringBoot应用*/
@SpringBootApplication
public class HelloWorldMainApplication {public static void main(String[] args) {//  让 Spring应用程序跑起来SpringApplication.run(HelloWorldMainApplication.class,args);}}

@SpringBootApplication: 这个注解标注到哪个类上面,就代表了这个类是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: SpringBoot的配置类:

​ 标注在哪个类,表示当前是一个SpringBoot的一个配置类

@Configuration:标注在配置类上的

​ 配置类 ------ 配置文件: 配置类也是容器中的一个组键,@Component

@EnableAutoConfiguration: 开启自动配置功能

以前需要配置东西的时候,SpringBoot会帮我们配置,@EnableAutoConfiguration 是告诉SpringBoot开启自动配置,这样我们的配置才会生效

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

@AutoConfigurationPackage : 自动配置包

@Import(AutoConfigurationImportSelector.class)

@Import是spring的底层注解,给容器导入一个组件;导入的组件由AutoConfigurationImportSelector.class

这个注解会将主配置类(@SpringBootApplication所标注的类)下面所有的子包里面的组价扫描到spring容器

@Import(AutoConfigurationImportSelector.class)

给容器中导入组件

AutoConfigurationImportSelector: 导入哪些主键的选择器

将所有需要导入的组件以全类目的方式返回: 这些组件就会加载到spring容器中

会给容器导入很多的配置类(xx.AutoConfiguration):其实就是导入你当前的场景所需要的依赖包

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vNcBPkYW-1591951707033)(C:\Users\JiangXinWei\Desktop\第二十八天\springBoot笔记\images\1589772241592_0B427267-7E72-4ba3-B3AE-034D934FE971.png)]

有了这个配置类,我们就不用手动去编写配置类去加载到项目中;

SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());

springboot会在启动的时候在类路径下的META-INF/spring.factories,会获取道@EnableAutoConfiguration制定的值,把这些值作为自动配置加入到容器。然后自动配置类就会生效。

5.4 、使用spring中的项目创建的向导器Spring Initializr去创建SpringBoot项目

- idea都有一个快速构建springboot项目的向导器Spring Initializr,可以使用它来创建项目,只需要勾选你想要的场景模块,就会自动下载所需要的依赖, 注: 创建过程中必须要联网 。
- 出程序以及生产好了,只需要根据我们的逻辑需求去编写
  • resources 文件夹下的目录结构

    • static: 存放当前项目下的所有静态资源 CSS、JS、Images …
    • templates: 存放所有的模板页面;
      • 注: 因为SpringBoot是内嵌Tomcat,所以说默认不支持JSP页面,可以使用插件去使用JSP页面
      • 注:SpringBoot推荐使用模板引擎 - Thymeleaf、Freemarker
        - application.properties : SpringBoot默认加载的配置文件,可以去修改一些默认配置

二、配置文件

6、配置文件

6.1、配置文件

​ SpringBoot使用了一个全局的配置文件,配置文件的名字是固定的。

​ application.properties

​ application.yml

​ 作用: 修改SpringBoot中的一些默认配置,这个文件会被springboot进行自动配置

yml = YAML:

  • 格式: 序列化

  • 写法: 递归的写法

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

  • “YAML Ain’t a Markup Language”(YAML不是一种标记语言)

    “Yet Another Markup Language”(仍是一种标记语言)

标记语言:

​ 以前 使用xxx.xml

​ 现在: YAML更好一些

.xml

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

.yml

server: port: 8081

6.2 YAML语法

6.2.1 基本语法

K: (空格)V 类似于键值对的写法,注意: 冒号后面要跟空格才能写V(值)

用空格来控制层级关系,只要根据左对齐的方式,同一列的数据都同一层级

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

6.2.2 值的写法

1、基本语法

​ K: (空格)V 类似于键值对的写法,注意: 冒号后面要跟空格才能写V(值)

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

​ K: V : 直接键值对写值

​ 注: - 如果说值是字符串也不需要去给引号

​ 在什么情况下可以加引号?

​ 双引号 " " : 如果说包含特殊字符,那么引不会转义特殊字符的含义,会直接根据特殊字符的本身含义展示出来

user:name: "laowang \n gebi"  -----     name: laowang 换行  gebi**

​ 单引号 ’ ':如果说包含特殊字符,那么单引号会转义特殊字符的含义,会直接把特殊字符作为一个字符串进行输出

user:name: ‘laowang \n gebi’  -----     name: laowang \n  gebi**

3、对象、Map

​ K: V : 在下一行去根据键值对的方式写属性个值

user:username: xiaomingage: 18gender:

如果说想把对象或者Map在一行内写出来

user: {username: xiaoming,age: 18,gender:}
4、数组、list、set

​ 在下一行使用 - (空格)值,来表示一个元素

sub:- JAVA- Python- HTML

如果说想把组或者list、set在一行内写出来

sub: java,python,html

6.3 获取YAML中的值

​ 配置文件:

​ .yml

user:userName: xiaomingage: 18gender:isgirl: truemaps: {k1: v1,k2: v2}sub:- java- python- htmlgirl:name: 小芳age: 16

JavaBean

/*** @ConfigurationProperties 标注在一个类上,告诉Springboot讲本类中所有的属性和指定的配置文件中的参数进行绑定*      注: ConfigurationProperties 属于容器中的注解,* prefix = "" 指定获取的是配置文件中哪一个下面所有参数*/
@Component
@ConfigurationProperties(prefix = "user")
public class User {private String userName;private int age;private String gender;private boolean isgirl;private Map<String,Object> maps;private List<Object> sub;private Girl girl;

配置文件处理器,到入这个包之后,我们进行属性和参数的绑定时会有人性化提示

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

.properties中的的参数取值乱码怎么办?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ED1rug3C-1591951707038)(C:\Users\JiangXinWei\Desktop\第二十九天\springBoot笔记\images\1.png)]

6.4 @Value 和 @ConfigurationProperties 应用场景

@ConfigurationProperties @Value
取值 可以一次取出全部参数进行绑定 一个一个取
SpEL 不支持 支持
松散绑定 支持 不支持
JSR303数据校验 支持 不支持
复杂类型绑定 支持 不支持

提问:

​ 这两个直接的应用场景分别是什么?

​ 如果说你只是在处理业务时,需要用到配置问价中某一个参数的值,就用@Value

​ 如果说你专门做实体绑定配置文件的实例,这是用@ConfigurationProperties

数据校验

/*** @ConfigurationProperties 标注在一个类上,告诉Springboot讲本类中所有的属性和指定的配置文件中的参数进行绑定*      注: ConfigurationProperties 属于容器中的注解,* prefix = "user" 指定获取的是配置文件中哪一个下面所有参数*/
@Component
@ConfigurationProperties(prefix = "user")
@Validated
public class User {/***  <bean class="user">*       <property name="userName" value="字面量、${},从配置文件中取值、*       SpEL表达式#{},spring表达式,用来做四则运算的"*  </bean>*///    @Value("${user.user-name}")private String userName;
//    @Value("#{2*5*8}")private int age;private String gender;
//    @Value("false")private boolean isgirl;
//    @Value("${maps}")

6.5 @PorpertySource & @ImportSource & @Bean

@PorpertySource: 加载指定的配置文件


/*** @Author Administrator* @Date 2020/5/20 15:31* @ConfigurationProperties 会告诉springboot将本类中的属性和配置文件相关的参数进行绑定* 注: ConfigurationProperties 是容器中的方法,所以当前类必须要容器中** prefix = "user" ;去指定配置文件中的哪一个下面的属性**/
@PropertySource(value = {"classpath:User.properties"}) //加载指定的配置文件
@Component
@ConfigurationProperties(prefix = "user")
//@Validated
public class User {

@ImportSource: 导入spring的配置文件,使其生效;

Springbooot中是 没有Spring配置文件的,我们自己编写的配置文件,也不会自动识别。

可以使用@ImportSource,让spring的配置类生效

注:@ImportSource 必须要标注在一个配置类上

<?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="userService" class="com.gm.service.UserService"></bean>
</beans>

如果说,我们项目中不允许出现.xml文件怎么办呢?

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

@Configuration ------ spring配置文件

@Bean —

/*** @Author Administrator* @Date 2020/5/22 14:51* @Configuration 标注在哪个类上,就代表当前是springboot的配置类**<bean id="userService" class="com.gm.service.UserService"></bean>**/
@Configuration
public class BootConfig {// 把返回值加载到容器中@Beanpublic UserService userService(){System.out.println("正在给spring容器注入组件");return new UserService();}
}

6.6 占位符

6.6 .1随机数

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

赋值 、 取值 、 自定义

user.user-name= 夏明翰${random.UUID}
user.age=${random.int}
user.gender=男
user.isgirl=true
user.maps.k1=v1
user.maps.k2=v2
user.sub=java,python,html
user.girl.name=${user.user-name}${user.password:的第二个}老Boby
user.girl.age=16

7、Profiles

7.1多Profiles文件

我们在主配置文件编写的时候,文件名可以是 :

application.properties/.yml

application-{profiles}.properties/.yml

当项目中同时存在默认配置文件喝profiles文件时,

默认使用 application.properties/.yml

7.2 YAML支持多文档块

server:port: 8084
spring:profiles:active: prov
---server:port: 8085
spring:profiles: devs
---server:port: 8086
spring:profiles: prov

7.3 激活制定的profiles的方法

​ 1. 在配置文件中激活 spring.profiles.active: prov

  1. 在spring环境里去激活 --spring.profiles.active=devs
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JBc3anwb-1591951707041)(C:\Users\JiangXinWei\Desktop\springBoot笔记\springBoot笔记\images\2.PNG)]
  1. 命令行:

    ​ java -jar springboot-03-config2-0.0.1-SNAPSHOT.jar --spring.profiles.active=devs

  2. 虚拟机参数:

    -Dspring.profiles.active=devs

8. 配置文件的加载位置

SpringBoot启动的时候会扫描以下位置application.properties和application.yml的默认配置文件

file:./config/

file: ./

classpath: /config/

classpath: /

优先级由高到低,

如果项目中存在相同配置不同位置的properties文件,那么高优先级是不是会覆盖低优先级;

如果项目中存在不同配置不同位置的properties文件,那么会发生 互补配置;

还可以通过 命令行: spring.config.location来改变默认加载的配置文件位置,同时,会同样遵守互补配置;

java -jar springboot-03-config-0.0.1-SNAPSHOT.jar --spring.config.location=C:/Users/JiangXinWei/Desktop/application.properties

9、配置文件的外部加载顺序

Springboot也可以从以下位置加载配置文件,优先级从高到低、遵循高覆盖低而且配置互补。

1.命令行参数

所有的配置都可以在命令行行进行执行

java -jar springboot-03-config-0.0.1-SNAPSHOT.jar --server.port=8088 --server.servlet.context-path=/ufo

书写规范: –配置项=值

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指定的默认属性

10 自动配置的原理

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

10.1 自动配置原理

  1. springboot启动的时候回加载主配置类,开启自动配置:@EnableAutoConfiguration
  2. @EnableAutoConfiguration:
    • 利用AutoConfigurationImportSelector给容器导入了一些组件
    • selectImports()方法的内容
    • List configurations = getCandidateConfigurations(annotationMetadata, attributes); 获取候选的配置
 SpringFactoriesLoader.loadFactoryNames()扫描所以jar类路径下的 : META-INF/spring.factories把扫描的这些文件的内容包装成properties对象从properties中获取EnableAutoConfiguration.class类名对应的值,然后把他们添加到容器中
# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer# Auto Configuration Import Listeners
org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener# Auto Configuration Import Filters
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
org.springframework.boot.autoconfigure.condition.OnBeanCondition,\
org.springframework.boot.autoconfigure.condition.OnClassCondition,\
org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition# 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.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
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.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration,\
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.r2dbc.R2dbcDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcTransactionManagerAutoConfiguration,\
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.ElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
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.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration,\
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.r2dbc.R2dbcAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
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.security.rsocket.RSocketSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration,\
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# Failure analyzers
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.boot.autoconfigure.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer,\
org.springframework.boot.autoconfigure.flyway.FlywayMigrationScriptMissingFailureAnalyzer,\
org.springframework.boot.autoconfigure.jdbc.DataSourceBeanCreationFailureAnalyzer,\
org.springframework.boot.autoconfigure.jdbc.HikariDriverConfigurationFailureAnalyzer,\
org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryBeanCreationFailureAnalyzer,\
org.springframework.boot.autoconfigure.session.NonUniqueSessionRepositoryFailureAnalyzer# Template availability providers
org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.mustache.MustacheTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.web.servlet.JspTemplateAvailabilityProvider

每一个xxxxxxAutoConfiguration类都是容器中的一个组件,都加到容器中,同时就是用他们来自做自动配置。

  1. 接下来用 HttpEncodingAutoConfiguration (Http编码自动配置) 来解释一下自动原理
@Configuration(proxyBeanMethods = false) // 表示是一个配置类,相当于以前的xml配置文件@EnableConfigurationProperties(ServerProperties.class) // 启动指定类的ConfigurationProperties,将配置文件中对应的值和ServerProperties进行绑定,并且绑定完之后会把ServerProperties加载道IOC容器中@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)// Conditiona 是spring中的底层注解,用来判断的,根据不同的条件,如果满足指定的条件,整个配置类中的配置才会生效。        判断当前是不是WEB项目,如果是,当前配置类生效@ConditionalOnClass(CharacterEncodingFilter.class) //  判断当前项目中有没有这个类,CharacterEncodingFilter.class: SpringMVC中解决乱码问题的过滤器@ConditionalOnProperty(prefix = "server.servlet.encoding", value = "enabled", matchIfMissing = true)// 判断配置文件中有没有某个配置,server.servlet.encoding.enabled,如果不存在,判断也是成立的,即使我们的配置文件中不存在server.servlet.encoding.enabled=true,也是默认生效的public class HttpEncodingAutoConfiguration {// 已经和springboot的配置文件进行绑定了private final Encoding properties;// 有参构造、当只有一个有参构造的时候,参数的值会从容器中得到public HttpEncodingAutoConfiguration(ServerProperties properties) {this.properties = properties.getServlet().getEncoding();}@Bean // 给容器中添加一个组价,组件中有些值需要从properties去获取@ConditionalOnMissingBean // 判断当前容器中有没有这个组件,CharacterEncodingFilterpublic CharacterEncodingFilter characterEncodingFilter() {CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();filter.setEncoding(this.properties.getCharset().name());filter.setForceRequestEncoding(this.properties.shouldForce(Encoding.Type.REQUEST));filter.setForceResponseEncoding(this.properties.shouldForce(Encoding.Type.RESPONSE));return filter;}

Conditiona 根据不同的条件判断得到不同的结果;

一旦这个配置文件生效,这个配置类就会给容器中添加各种组件;这些组件中的属性都是从对应的properties中获取的,同时,这些类里面的每一个属性有和配置文件进行绑定

  1. 每一个XXXAutoConfiguration都应该有一个相对于的xxxxproperties文件。

总结:

​ 1, springboot启动时会加载大量的配置类;

​ 2,我们在写之前,看一下我们需要的东西有没有是springboot默认写好的自动配置类

​ 3,如果有,只需要看一下自动配置类中到底 配置了哪些组件;

​ 4, 给容器中自动配置类添加组件的时候。会从从对应的properties中获取的,就可在配置文件中制定这些属性的值

11 拓展 @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 来查看哪些配置生效

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)DispatcherServletAutoConfiguration matched:- @ConditionalOnClass found required class 'org.springframework.web.servlet.DispatcherServlet' (OnClassCondition)- found 'session' scope (OnWebApplicationCondition)DispatcherServletAutoConfiguration.DispatcherServletConfiguration matched:- @ConditionalOnClass found required class 'javax.servlet.ServletRegistration' (OnClassCondition)- Default DispatcherServlet did not find dispatcher servlet beans (DispatcherServletAutoConfiguration.DefaultDispatcherServletCondition)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)

三、Web开发

1、简介

使用Springboot:

  1. 创建springboot应用,选中我们需要的模块;
  2. springboot已经默认的把这些场景都配置好了,只需要去更改配置文件中的少量配置就可以运行起来
  3. 自己编写业务代码;

自动配置原理?

Springboot到底给我们配置了什么? 能不能修改? 能不能修改默认配置?。。。。

xxxAutoConfiguration  帮我们给容器中自动配置组件
xxxproperties 配置类来封装配置文件的内容

2、SpringBoot对静态资源路径映射的规则

WebMvcAutoConfiguration@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {if (!this.resourceProperties.isAddMappings()) {logger.debug("Default resource handling disabled");return;}Duration cachePeriod = this.resourceProperties.getCache().getPeriod();CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();if (!registry.hasMappingForPattern("/webjars/**")) {customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/").setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));}String staticPathPattern = this.mvcProperties.getStaticPathPattern();// 静态资源文件夹映射if (!registry.hasMappingForPattern(staticPathPattern)) {customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern).addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));}}// 首页的映射
@Beanpublic WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),this.mvcProperties.getStaticPathPattern());welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());return welcomePageHandlerMapping;}
  1. 所有的 /webjars/都会去 classpath:/META-INF/resources/webjars/ 去资源**

    webjars: 把前段的资源以jar包的方式引用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yxa7FBKb-1591951707044)(C:\Users\JiangXinWei\Desktop\springBoot笔记\springBoot笔记\images\5.png)]

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

<!--Jquery组件(前端)-->
<dependency><groupId>org.webjars</groupId><artifactId>jquery</artifactId><version>3.3.1</version>
</dependency>
  1. “/” 访问当前项目的任何资源,都会去静态资源的文件夹去找映射
"classpath:/META-INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/"
"/" 当前项目的根路径

http://localhost:8080/style.js 会从静态资源路径去找style.js

  1. 欢迎页/首页,静态资源文件夹下的所有的index.html页面,都会背部“/”映射

http://localhost:8080/

  1. 所有的**/favicon.ico 都在静态资源目录中去找

3、模板引擎

jSP、Velocity、Freemarker、Thymeleaf

Thymeleaf:

1、Thymeleaf 是 Web 和独立环境的现代服务器端 Java 模板引擎,能够处理HTML,XML,JavaScript,CSS 甚至纯文本。

2、Thymeleaf 的主要目标是提供一种优雅和高度可维护的创建模板的方式。为了实现这一点,它建立在自然模板的概念上,将其逻辑注入到模板文件中,不会影响模板被用作设计原型。这改善了设计的沟通,弥补了设计和开发团队之间的差距。

3、Thymeleaf 也从一开始就设计了Web标准 - 特别是 HTML5 - 允许您创建完全验证的模板,Spring Boot 官方推荐使用 thymeleaf 而不是 JSP。

4、Thymeleaf 官网:https://www.thymeleaf.org/

5、Thymeleaf 在 Github 的主页:https://github.com/thymeleaf/thymeleaf

6、Spring Boot 中使用 Thymeleaf 模板引擎时非常简单,因为 Spring Boot 已经提供了默认的配置,比如解析的文件前缀,文件后缀,文件编码,缓存等等,程序员需要的只是写 html 中的内容即可,可以参考《Spring Boot 引入 Thymeleaf 及入门》

特点 : 语法更简单、功能更强大

原 理:

模板引擎原理图如下,模板引擎的作用都是将模板(页面)和数据进行整合然后输出显示,区别在于不同的模板使用不同的语法,如 JSP 的 JSTL 表达式,以及 JSP 自己的表达式和语法,同理 Thymeleaf 也有自己的语法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VcYoEPHg-1591951707047)(C:\Users\JiangXinWei\Desktop\springBoot笔记\springBoot笔记\images\6.png)]

3.1 引入Thymeleaf:

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

使用Thymeleaf:

@ConfigurationProperties(prefix = "spring.thymeleaf")
public class ThymeleafProperties {private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;public static final String DEFAULT_PREFIX = "classpath:/templates/";public static final String DEFAULT_SUFFIX = ".html";

所以说,只要把页面放到classpath:/templates/,thymeleaf就可以自动进行渲染。

使用:

  1. 需要导入Thymeleaf的名称空间
<html lang="en" xmlns:th="http://www.thymeleaf.org">
  1. 使用thymeleaf语法:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><p>这里是测试页面</p><hr><p  id="p" >[[ ${hello} ]]</p><hr><input th:value="${hello}"  value="我是取值的Input标签"/><hr><p th:each="user:${list}" th:text="${user}">我是取list的地方</p></body>
</html>
  1. 语法规则:
  2. th:text ; 改变当前元素里面的文本内容
  3. th: 任意html属性,来替换原生属性的值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9Ty6GWKW-1591951707048)(C:\Users\JiangXinWei\Desktop\springBoot笔记\springBoot笔记\images\9.png)]

取值:

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: *{...} : 选择表达式,和${}在功能上是一样的补充: <div th:object="${session.user}">   <p>Name: <span th:text="*{firstName}">Sebastian</span>.</p>   <p>Surname: <span th:text="*{lastName}">Pepper</span>.</p>    <p>Nationality: <span th:text="*{nationality}">Saturn</span>.</p>  </div>Message Expressions: #{...} : 获取国际化内容Link URL Expressions: @{...} : 定义URL
<!-- Will produce 'http://localhost:8080/gtvg/order/details?orderId=3' (plus             rewriting) -->
<a href="details.html"th:href="@{http://localhost:8080/gtvg/order/details(orderId=${o.id})}">view</a>
<!-- Will produce '/gtvg/order/details?orderId=3' (plus rewriting) -->
<a href="details.html" th:href="@{/order/details(orderId=${o.id})}">view</a>
<!-- Will produce '/gtvg/order/3/details' (plus rewriting) -->
<a href="details.html" th:href="@{/order/{orderId}/details(orderId=${o.id})}">view</a>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: nullLiteral 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): ! , notComparisons 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: _

3.2 SpringMVC自动配置:

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

1. Spring MVC Auto-configuration

Spring Boot 自动配置好了SprinMVC

以下是SpringBoot对SpringMVC的默认配置:WebMvcAutoConfiguration

org\springframework\boot\autoconfigure\web\servlet\WebMvcAutoConfiguration.java

  • Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.

    • 自动配置了ViewResolver(视图解析器: 根据当前的方法返回值,得到视图对象(View),视图的对象绝对了如何进行渲染(转发,重定向))
    • ContentNegotiatingViewResolver : 组合所有的视图解析器
    • 如何自己去写: 我们可以给容器中添加一个视图解析器;自动帮我们将自己写的组合进去
  • Support for serving static resources, including support for WebJars (covered later in this document)). :

    • WebJars ,静态资源文件夹路径的webjars
    • localhost:8080/webjars/xxxxxxx
  • 自动注册了 of Converter, GenericConverter, and Formatter beans.

    • Converter:转换器;public String Hello(User user){}; 类型转换器Converter
    • Formatter : 格式化器: 2020.05.30 === Date
  • Support for HttpMessageConverters (covered later in this document).

    • HttpMessageConverters : SpringMVC用来转换Http请求的请求和相应的;User—JSON
    • HttpMessageConverters: 从容器中确定: 获取所有的HttpMessageConverters,
    • 如果自己去添加,只需要将自己的组件去注册到容器中(@Bean,@Component)
  • Automatic registration of MessageCodesResolver (covered later in this document).

    • 定义错误代码生成规则
  • Static index.html support.: 静态资源的首页访问

  • Custom Favicon support (covered later in this document). : Favicon.ico

  • Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document).

    • 可以去定义一个属于自己的ConfigurableWebBindingInitializer 来替换默认的,只需要将自己写的祖册到容器中

If you want to keep those Spring Boot MVC customizations and make more MVC customizations (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without@EnableWebMvc.

If you want to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver, and still keep the Spring Boot MVC customizations, you can declare a bean of type WebMvcRegistrations and use it to provide custom instances of those components.

If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc, or alternatively add your own @Configuration-annotated DelegatingWebMvcConfiguration as described in the Javadoc of @EnableWebMvc.

2. 扩展SpringMVC
<mvc:view-controller path="/JJ" view-name="test2"/><mvc:interceptors><mvc:interceptor><mvc:mapping path="/JJ"/><bean></bean></mvc:interceptor></mvc:interceptors>

步骤: 编写一个配置类(@Configuration),属于WebMvcConfigurer类型(2.3.0),之前的版本叫做WebMvcConfigurerApapter;不能是@EnableWebMvc


@Configuration
//@EnableWebMvc
public class MyMvcConfig implements WebMvcConfigurer{@Overridepublic void addViewControllers(ViewControllerRegistry registry) {registry.addViewController("/JJ").setViewName("test2");registry.addViewController("/").setViewName("test2");}
}

原理:

1. WebMvcConfigurer 是SpringMVC的自动配置类
2. 当我们配置好的时候启动项目,容器中所有的WebMvcConfigurer  都会一起起作用3. 我们的配置类也会生效

3.3 全面接管SpringMVC

@EnableWebMvc:SpringBoot对SpringMVC的自动配置已经不需要了。所有的都需要我们自已配置;所以SprigMVC的自动配置失效了;

实现: 只需要在配置类中加入@EnableWebMvc注解

// WebMvcConfigurer 可以扩展SpringMVC中的功能
@Configuration
@EnableWebMvc
public class MyMvcConfig implements WebMvcConfigurer{@Overridepublic void addViewControllers(ViewControllerRegistry registry) {registry.addViewController("/JJ").setViewName("test2");registry.addViewController("/").setViewName("test2");}
}

原理:

​ 为什么加入@EnableWebMvc之后自动配置就失效了?

1、@EnableWebMvc的核心

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}
@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {

3、

@ConditionalOnMissingBean(WebMvcConfigurationSupport.class) // 容器中没有WebMvcConfigurationSupport 配置类才生效
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {

4、@EnableWebMvc将所有的WebMvcConfigurationSupport组件导入进来

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

3.4 如何去修改SpringBoot的默认配置

模式:

​ 1. SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(@Bean,@Component),如果有就用用户自己配置的,如果没有才会进行自动配置。如果说有一些组件可以配置多个(ViewResolver)会将用户配置和自己默认的配置组合起来。

​ 2. SpringBoot中会有很多的XXXXConfigurer帮我们去自定义扩展配置

​ 3. SpringBoot中会有很多的XXXXCustomizer帮我们去定制配置

4. RestFul CRUD

4.1 首页

1. 默认访问首页1. 写一个转发的方法
@Controller
public class LoginController {@RequestMapping({"/","login.html"})public String dpPage(){return "login";}
}
  1. 自定义配置文件
@Configuration
public class MyConfig {@Beanpublic WebMvcConfigurer webMvcConfigurer(){WebMvcConfigurer webMvcConfigurer = new WebMvcConfigurer() {@Overridepublic void addViewControllers(ViewControllerRegistry registry) {registry.addViewController("/").setViewName("login");registry.addViewController("/login.html").setViewName("login");}};return webMvcConfigurer;}}
  1. 自行修改页面中的静态资源路径

4.2 国际化

  1. 需要编写国际化相关的配置文件

     2.  使用ResourceBundleMessageSource管理国际化资源文件(Springboot中已经自动配置了)3.  jsp的时候使用fmt:message取出国际化内容(Springboot中使用#{})
    

步骤:

​ 1. 编写国际化配置文件,抽取页面需要显示的国际化(汉化)内容

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8lbkvdH0-1591951707049)(C:\Users\JiangXinWei\Desktop\springBoot笔记\springBoot笔记\images\10.png)]

  1. SpringBoot自动配置好了管理国际化文件的组件
public class MessageSourceProperties {/*** 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@Beanpublic MessageSource messageSource(MessageSourceProperties properties) {ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();if (StringUtils.hasText(properties.getBasename())) {// login   login_zh_CN   login_en_US// 设置国际化资源文件的基础名(去掉语言和国家代码)messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray(StringUtils.trimAllWhitespace(properties.getBasename())));}if (properties.getEncoding() != null) {messageSource.setDefaultEncoding(properties.getEncoding().name());}messageSource.setFallbackToSystemLocale(properties.isFallbackToSystemLocale());Duration cacheDuration = properties.getCacheDuration();if (cacheDuration != null) {messageSource.setCacheMillis(cacheDuration.toMillis());}messageSource.setAlwaysUseMessageFormat(properties.isAlwaysUseMessageFormat());messageSource.setUseCodeAsDefaultMessage(properties.isUseCodeAsDefaultMessage());return messageSource;}
# 指定国际化资源文件
spring.messages.basename=i18n.login
  1. 去页面取出国际化的值:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><meta name="description" content=""><meta name="author" content=""><title>Signin Template for Bootstrap</title><!-- Bootstrap core CSS --><link href="asserts/css/bootstrap.min.css" th:href="@{/webjars/bootstrap/3.3.5/css/bootstrap.css}"  rel="stylesheet"><!-- Custom styles for this template --><link href="asserts/css/signin.css" th:href="@{/asserts/css/signin.css}" rel="stylesheet"></head><body class="text-center"><form class="form-signin" action="dashboard.html"><img class="mb-4" src="asserts/img/bootstrap-solid.svg" th:src="@{/asserts/img/bootstrap-solid.svg}" alt="" width="72" height="72"><h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1><label class="sr-only">Username</label><input type="text" class="form-control" placeholder="Username" th:placeholder="#{login.username}" required="" autofocus=""><label class="sr-only">Password</label><input type="password" class="form-control" placeholder="Password" th:placeholder="#{login.password}" required=""><div class="checkbox mb-3"><label><input type="checkbox" value="remember-me" /> [[ #{login.remember} ]]</label></div><button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.sign}">Sign in</button><p class="mt-5 mb-3 text-muted">© 2019-2020</p><a class="btn btn-sm">中文</a><a class="btn btn-sm">English</a></form></body></html>

效果:

​ 当前只能根据浏览器的语言选项来切换国际化

我们想要的是点击链接进行切换

​ 首先要了解Springboot到底是怎么处理国际化资源的

​ 原理:

​ 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进行国际化
  1. 点击链接切换国际化
package com.gm.common;import org.apache.logging.log4j.util.Strings;
import org.springframework.web.servlet.LocaleResolver;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;public class MyLocaleResolver implements LocaleResolver {@Overridepublic Locale resolveLocale(HttpServletRequest request) {String i = request.getParameter("i");Locale locale = Locale.getDefault();if (!Strings.isEmpty(i)) {// i = en_USString[] s = i.split("_");locale = new Locale(s[0],s[1]);}return locale;}@Overridepublic void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {}
}@Beanpublic LocaleResolver localeResolver(){return new MyLocaleResolver();}

4.3 登录

模拟登录

package com.gm.controller;import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;@Controller
public class LoginController {
//    @PutMapping
//    @DeleteMapping
//    @GetMapping
//    @RequestMapping(value = "/user/login",method = RequestMethod.POST)@PostMapping("/user/login")public String doLogin(@RequestParam("username") String username,@RequestParam("password") String password,Model model){if (!Strings.isEmpty(username) && "000000".equals(password)){// 登录成功return "dashboard";} else {// 登录失败model.addAttribute("msg","用户名密码错误!");return "login";}}
}

4.4 添加拦截器

package com.gm.common;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {Object user = request.getSession().getAttribute("user");if (user == null) {// 未登录,返回登录页面request.setAttribute("msg","没有操作权限,请先登录!");request.getRequestDispatcher("/login.html").forward(request,response);return false;}else {// 成功登录,进行放行return true;}}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}
}@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/login.html","/","/user/login").excludePathPatterns("/asserts/**").excludePathPatterns("/webjars/**");}

4.5 CRUD - 员工列表实现

RestFul web service

Restful风格:

RUI : /资源名称/资源标识 HTTP请求方式区分对资源的CRUD操作

普通CRUD RestFul CRUD
添加 addEmp Emp - POST
删除 delEmp?id=xxx Emp/{id} - DELETE
查询 findEmps?id=xxx Emp/{id} - GET
修改 updEmp?id=xxx Emp/{id} - PUT

当前的项目需求: 满足RestFul 风格

功能需求 请求的URI 请求方式
查询所有员工 Emps GET
点击到增加页面 Emp GET
添加 Emp POST
单查询 Emp/{id} GET
修改前的查询 Emp/{id} GET
修改 Emp PUT
删除 Emp/{id} DELETE
  1. 公共页面的提取
<div th:fragment="copy">  &copy; 2011 The Good Thymes Virtual Grocery
</div> <div th:insert="~{footer :: copy}"></div>
footer : 公共片段存在的页面~{templatename::selector}: 模板名:: 选择器~{templatename::fragmentname} :模板名:: 片段名th:insert 效果:把公共页面插入到了获取时包裹的标签中

引入公共页面的方式

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

th:replace:将声明的元素替换为公共片段

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

<footer th:fragment="copy">  &copy; 2011 The Good Thymes Virtual Grocery
</footer><div th:insert="footer :: copy"></div><div th:replace="footer :: copy"></div><div th:include="footer :: copy"></div> <div> <footer>     &copy; 2011 The Good Thymes Virtual Grocery    </footer>
</div><footer>   &copy; 2011 The Good Thymes Virtual Grocery
</footer><div>   &copy; 2011 The Good Thymes Virtual Grocery
</div> 

引入片段的时候传入参数

<!--  引入头部公共页面    --><div th:replace="common/header :: header"></div><div class="container-fluid"><div class="row"><!-- 引入左侧        --><div th:replace="common/header :: #sidebar(active='Emps')"></div>

查询:

@Controller
public class EmployeeController {@Autowiredprivate EmployeeDao employeeDao;//    @DeleteMapping
//    @PutMapping
//    @PostMapping
//    @RequestMapping(value = "/Emps",method = RequestMethod.POST)@GetMapping("/Emps")public String findAllEmps(Model model){Collection<Employee> all = employeeDao.getAll();model.addAttribute("emps",all);return "emp/list";}
}

list.html

<table class="table table-striped table-sm"><thead><tr><th>id</th><th>姓名</th><th>邮箱</th><th>性别</th><th>部门</th><th>生日</th><th>操作</th></tr></thead><tbody><tr th:each="emp:${emps}"><td th:text="${emp.id}"></td><td th:text="${emp.lastName}"></td><td th:text="${emp.email}"></td><td th:text="${emp.gender==0}?'':''"></td><td th:text="${emp.department.getDepartmentName()}"></td><td th:text="${#dates.format(emp.birth, 'yyyy-MM-dd HH:mm')}"></td><td><button class="btn btn-sm btn-info">编辑</button><button class="btn btn-sm btn-danger">删除</button></td></tr></tbody></table>s

4.6 员工添加

1 2 3 4 5

添加

// 点击添加来到添加页面@GetMapping("/emp")public String toAddPage(Model model){// 点击查询按钮,应当查出来所有的部门信息,以供选择Collection<Department> departments = this.departmentDao.getDepartments();model.addAttribute("depms",departments);return "emp/add";}// 添加操作,Springboot web阶段使用的还是SpringMVC,会帮我们自动进行封装@PostMapping("/emp")public String addEmp(Employee employee){
//        System.out.println("得到的员工信息为:" + employee );this.employeeDao.save(employee);return "redirect:/Emps";}

4.7 员工修改

<form action="/emp" th:action="@{/emp}" method="post"><!--      怎么进行发生PUT请求修改数据1. SpringMVC中配置 HiddenHttpMethodFilter;2. 页面中有一个表单3. 在表单中需要Input,name属性=_method;值就是我们指定的请求方式--><input type="hidden" name="_method" value="put" th:if="${emp!=null}"><input type="hidden" name="id" th:if="${emp!=null}" th:value="${emp.id}"><div class="form-group"><label>LastName</label><input type="text" name="lastName" class="form-control" placeholder="zhangsan" th:value="${emp!=null}?${emp.lastName}"></div><div class="form-group"><label>Email</label><input type="email" name="email" class="form-control" placeholder="zhangsan@dd.com" th:value="${emp!=null}?${emp.email}"></div><div class="form-group"><label>Gender</label><br/><div class="form-check form-check-inline"><input class="form-check-input" type="radio" name="gender" th:checked="${emp!=null}?${emp.gender==1}"  value="1"><label class="form-check-label"></label></div><div class="form-check form-check-inline"><input class="form-check-input" type="radio" name="gender" th:checked="${emp!=null}?${emp.gender==0}" value="0"><label class="form-check-label"></label></div></div><div class="form-group"><label>department</label><select class="form-control" name="department.id"><option th:each="depm:${depms}" th:value="${depm.id}" th:selected="${emp!=null}?${depm.id == emp.department.id}" th:text="${depm.departmentName}">部门</option></select></div><div class="form-group"><label>Birth</label><input type="text" name="birth" class="form-control" placeholder="zhangsan" th:value="${emp!=null}?${#dates.format(emp.birth, 'yyyy-MM-dd')}"></div><button type="submit" class="btn btn-primary" th:text="${emp!=null}?'修改':'添加'">添加</button></form>
// 点击编辑到页面,显示员工信息@GetMapping("/emp/{id}")public String toUpdPage(@PathVariable("id") Integer id,Model model){Employee employee = this.employeeDao.get(id);model.addAttribute("emp",employee);// 点击查询按钮,应当查出来所有的部门信息,以供选择Collection<Department> departments = this.departmentDao.getDepartments();model.addAttribute("depms",departments);return "emp/add";}// 修改@PutMapping("/emp")public String updEmp(Employee employee){this.employeeDao.save(employee);return "redirect:/Emps";}

4.8 员工删除

方法、

<button th:attr="action_uri=@{/emp/}+${emp.id}"  class="btn btn-sm btn-danger delete" >删除</button><form  id="deleteEmpForm" method="post"><input type="hidden" name="_method" value="delete">
</form><script>$(".delete").click(function () {$("#deleteEmpForm").attr("action",$(this).attr("action_uri")).submit();return false;});</script>

4.9 退出登录

    @GetMapping("/user/logout")public String logOut(HttpSession session){
//        session.invalidate();session.removeAttribute("user");return "login";}

5. 配置嵌入式Servlet容器

Springboot 默认使用Tomcat作为嵌入式的servlet容器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rmQTxXJk-1591951707050)(C:\Users\Administrator\Desktop\springBoot笔记\springBoot笔记\images\12.png)]

问题?

5.1.如何去修改servlet容器相关的配置:

​ 1. 修改个server有关的配置(serverProperties)

server.port=8081
server.servlet.context-path=/crudserver.tomcat.uri-encoding=utf-8
  1. 自定义WebServerFactoryCustomizer
// serverProperties 在底层最终会实现WebServerFactoryCustomizer@Beanpublic WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> myServer(){return new WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>() {@Overridepublic void customize(ConfigurableServletWebServerFactory factory) {factory.setPort(8083);}};}

5.2 注册servlet中的三大组件: Servlet、Filter、Listener

自定义Servlet: **ServletRegistrationBean**
@Beanpublic ServletRegistrationBean<MyServlet> myServlet(){ServletRegistrationBean<MyServlet> myServlet = new ServletRegistrationBean<>(new MyServlet(),"/MyServlet");return myServlet;}

​ 自定义Filter: FilterRegistrationBean

 @Beanpublic FilterRegistrationBean<MyFilter> myFilter(){FilterRegistrationBean<MyFilter> myFilter = new FilterRegistrationBean<>();myFilter.setFilter(new MyFilter());myFilter.setUrlPatterns(Arrays.asList("/hello","/MyFilter"));return myFilter;}

​ 自定义 Listener: ServletListenerRegistrationBean

@Beanpublic ServletListenerRegistrationBean<MyListener> myListener(){ServletListenerRegistrationBean<MyListener> myListener = new ServletListenerRegistrationBean<>();myListener.setListener(new MyListener());return myListener;}

SpringBoot 在自动配置SpringMVC时,自动注册了SpringMVC中的前端控制器:DispatcherServlet

@Bean(name = DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)@ConditionalOnBean(value = DispatcherServlet.class, name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)public DispatcherServletRegistrationBean dispatcherServletRegistration(DispatcherServlet dispatcherServlet,WebMvcProperties webMvcProperties, ObjectProvider<MultipartConfigElement> multipartConfig) {DispatcherServletRegistrationBean registration = new DispatcherServletRegistrationBean(dispatcherServlet,webMvcProperties.getServlet().getPath());/*默认拦截: / 所有请求,包括静态资源,但是会放行.jsp请求/*  所有请求,包括静态资源,同时拦截JSp请求*.do可以通过spring.mvc.servlet.path来修改SpringMVC前端控制器默认拦截的路径*/registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);registration.setLoadOnStartup(webMvcProperties.getServlet().getLoadOnStartup());multipartConfig.ifAvailable(registration::setMultipartConfig);return registration;}

SpringBoot 入门04相关推荐

  1. SpringBoot入门(二)——起步依赖

    本文来自网易云社区 在前一篇我们通过简单几步操作就生成了一个可以直接运行的Web程序,这是因为SpringBoot代替我们做了许多工作,概括来讲可以分为起步依赖和自动配置.这一篇先来看看起步依赖. 项 ...

  2. springboot 入门教程(4)--web开发(spring mvc和Thymeleaf模板,带源码)

    2019独角兽企业重金招聘Python工程师标准>>> 首先回顾下前几篇的内容:springboot 入门教程(1),springboot 入门教程-Thymeleaf(2), sp ...

  3. 【Java】SpringBoot入门学习及基本使用

    SpringBoot入门及基本使用 SpringBoot的介绍我就不多说了,核心的就是"约定大于配置",接下来直接上干货吧! 本文的实例: github-LPCloud,欢迎sta ...

  4. SpringBoot入门和配置

    一.SpringBoot入门和微服务简介  1.SpringBoot入门 springboot:J2EE一站式解决方案 springcloud:分布式整体解决方案 2.微服务简介    微服务:架构风 ...

  5. 最简单最详细的SpringBoot入门项目——HelloWorld

    最详细的SpringBoot入门项目--HelloWorld 关于SpringBoot的介绍以及优点这里就不说了,想了解的可以直接点击这里 Spring Boot百度百科 接下来我们直奔主题,开始用S ...

  6. SpringBoot简介、SpringBoot 入门程序搭建、与JDBC、Druid、Mybatis和SpringData JPA的整合

    一.SpringBoot 简介: spring boot并不是一个全新的框架,它不是spring解决方案的一个替代品,而是spring的一个封装.所以,你以前可以用spring做的事情,现在用spri ...

  7. springboot 历史版本文档_乘风破浪,SpringBoot入门

    SpringBoot入门篇 前言 在普通的java项目中,大量的xml文件配置起来相当繁琐,导致了开发效率非常低下,整合第三方框架的配置可能会存在冲突问题导致部署效率低,打包方式是将项目打成一个war ...

  8. (原创)SpringBoot入门

    本文章是SpringBoot入门的介绍在这里   我会尽量写一些细节性的东西,我用的是IDEA2016  Tomcat7 JDK1.8 Maven3.3.9 IDEA Tomcat JDK Maven ...

  9. 【网络爬虫入门04】彻底掌握BeautifulSoup的CSS选择器

    [网络爬虫入门04]彻底掌握BeautifulSoup的CSS选择器 广东职业技术学院  欧浩源 2017-10-21 1.引言 目前,除了官方文档之外,市面上及网络详细介绍BeautifulSoup ...

最新文章

  1. 激活函数之softmax介绍及C++实现
  2. 标记meta http-equiv = X-UA-Compatible content = IE=edge,chrome=1
  3. numpy 笔记: random模块
  4. 在Mapnik中显示中文(网上资料整理)
  5. CodeForces - 1328D Carousel(构造+贪心)
  6. 运营商主动关闭WLAN热点背后:关键是找准产业位置
  7. 微信小程序 蓝牙的使用
  8. MySQL查询结果导出到文件
  9. 详解CPU几个重点基础知识
  10. 数据库设计方法、规范和技巧
  11. mysql sleep进程 java_请教java更新mysql,更新进程sleep
  12. 在线动态几何编辑器 GeometryEditor
  13. 2021年下半年信息安全工程师上午真题及答案解析
  14. 【BP数据预测】基于matlab狼群算法优化BP神经网络数据预测【含Matlab源码 658期】
  15. 英文系统下手工安装五笔86版
  16. CSS 网格 Gird 布局
  17. pygame-KidsCanCode系列jumpy-part0-使用sprite
  18. 玉伯:做一个简单自由有爱的技术人
  19. 二十、JVM命令行监控工具
  20. 【Grasshopper基础8】电池的序列化与反序列化 Serilization of Grasshopper Component

热门文章

  1. 为织梦文章管理系统首页添加栏目间广告
  2. R语言——在linux环境下如何画图或保存图片
  3. 万里汇WorldFirst个人账号好还是公司账号好?
  4. Python3.9的新的特性
  5. 替代Google Earth查历史影像的网站
  6. Web核心-Http-Tomcat-Servlet学习记录
  7. STM32使用ESP8266接入机智云点亮LED教程
  8. java工程师进阶路线
  9. 网信办第三批区块链备案清单:金融行业成区块链应用最广泛领域
  10. 【P50】TDA1543 解码 DIY Part3:全分立 IV 转换