SpringMVC原理分析
Spring Boot学习
5、Hello World探究
1、POM文件
1、父项目
org.springframework.boot
spring-boot-starter-parent
2.0.2.RELEASE
他的父项目是:
org.springframework.boot
spring-boot-dependencies
2.0.2.RELEASE
../../spring-boot-dependencies
他才真正的管理springboot应用的所有依赖版本。
Spring Boot的版本仲裁中心:
以后我们导入依赖,默认不需要写版本(没有在dependencies里面的依赖需要我们手动写上版本);
2、启动器
org.springframework.boot
spring-boot-starter-web
spring-boot-starter-web
spring-boot-starter:spring-boot场景启动器;帮我们导入了web模块正常运行所依赖的组件;
Spring Boot将所有的功能场景都抽取出来,做成一个个starters(启动器),只要在项目里面引入这些starter相关场景的所有依赖都会导入进来。要用什么功能,就导入什么场景的启动器。
2、主程序类,主入口类
/**
* @author Alan
* @date 2018/5/12 16:11
* @SpringBootApplication 来标注一个主程序类,说明这是一个Spring Boot应用
*/
@SpringBootApplication
publicclassHelloWorldApplication{
publicstaticvoidmain(String[]args) {
//spring应用启动起来
SpringApplication.run(HelloWorldApplication.class,args);
}
}
@SpringBootApplication: Spring Boot应用标注在某个类上说明这个类是Spring Boot的主配置类,Spring Boot就应该运行这个类的main方法来启动Spring Boot应用。
@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@interfaceSpringBootApplication{
@SpringBootConfiguration:Spring Boot的配置类
标注在某个类上,表示 这是一个Spring Boot的配置类;
@Configuration:配置类上来标注这个注解;
配置类----配置文件;配置类也是一个组件:@Component
@EnableAutoConfiguration:开启自动配置功能;
以前我们需要配置的东西,Spring Boot帮我们自动配置;@EnableAutoConfiguration告诉Spring开启自动配置功能,这样自动配置才能生效;
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public@interfaceEnableAutoConfiguration{
@AutoConfigurationPackage:自动配置包;
@Import({Registrar.class}):
Spring底层注释@Import,给容器中导入一个组件;导入的组件由AutoConfigurationImportSelector.class指定。
将主配置类(@SpringBootApplication标注的类)的所在包及下面的所有组件扫描到Spring容器;
@Import({Registrar.class}):
给容器中导入组件?
AutoConfigurationImportSelector.class:导入哪些组件的选择器
将所有需要的组件以全类名的方式返回;这些组件就会被添加到容器中;
会给容器中导入非常多的自动配置类(xxxAutoConfiguration);就是给容器中导入这个场景需要的所有组件,并配置好这些组件;
有了自动配置类,免去了我们手动编写配置注入功能组件等工作;
SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,class Loader)
Spring Boot在启动的时候,从类路径 META-INFO/spring.facotries中获取EnableAutoConfiguration指定的值;将这些值作为自动配置类导入到容器中,自动配置类就生效了,帮我们自动配置工作;
我们点一个webmvc进去,如下:
以前我们需要配置的东西都帮我们自动配置了,J2EE的整体整合解决方案和自动配置都在:
C:\Users\Alan.m2\repository\org\springframework\boot\spring-boot-autoconfigure\2.0.2.RELEASE\spring-boot-autoconfigure-2.0.2.RELEASE.jar
6、使用Spring Initializer快速创建Spring Boot项目
IDE都 支持使用Spring的创建向导快速创建一个Spring Boot项目;
选择我们需要的模块,向导会联网创建Spring Boot项目;
默认生成的Spring Boot项目:
主程序已经生成好了
resources文件夹目录结构
static: 保存所有的静态资源;js、css、images;
templates:保存所有的模板页面:(Spring Boot默认jar包使用嵌入式的Tomcat,默认不支持JSP页面);可以使用模板引擎(thymeleaf、freemarker);
applications.properties:Spring Boot应用的配置文件;可以修改一些默认配置;
二、配置文件
1、配置文件
Spring Boot使用一个全局的配置文件,配置文件名是固定的:
application.properties
application.yml
配置文件的作用:修改Spring Boot自动配置的默认值;
Spring Boot在底层都给我们自动配置好了;
YAML(YAML Ain't Markup Language)
YAML A Markup Language:是一个标记语言;
YAML isn't Markup Language:不是一个标记语言;
标记语言:
以前的配置文件,大多是xxx.xml文件;
YAML:以数据为中心,比json、xml更适合做配置文件;
YAML配置例子:
server:
port: 8080
XML配置例子:
8080
2、YAML语法
1、基本语法
k:(空格)v :表示一对键值对(空格必须有)
以空格的缩进来控制层级关系;只要是左对齐的一列数据,都表示同一层级;
server:
port: 8080
path: /hello
属性和值也是大小写敏感的;
2、值的写法
字面量:普通的值(数字、字符串、布尔)
k: v :字面直接来写;
字符串默认不用加上双引号和单引号;
“”:双引号,不会转义字符串里面的特殊字符,特殊字符会作为本身想表示的意思
name: "zhangsan \n lisi":输出zhangsan 换行 lisi
’‘:单引号:会转义特殊字符,特殊字符最终只是一个普通字符串数据
name: 'zhangsan \n lisi':输出zhangsan \n lisi
对象、Map(属性和值)(键值对):
k: v:在下一行写对象的属性和值的关系,注意缩进;
对象还是k: v格式
friends:
lastName: zhangsan
age: 20
行内写法:
friends: {lastName: zhangsan,age: 20}
数组(List、Set):
用- 值表示数组中的一个元素
pets:
- cat
- dog
- monkey
行内写法:
pets: [cat,dog,monkey]
3、配置文件值注入
配置文件:
person:
lastName: zhangsan
age: 18
boss: false
birthday: 2017/12/12
maps: {k1: v1,k2: v2}
lists:
- lisi
- zhaoliu
dog:
name: 小狗
age: 2
JavaBean:
/**
* @author Alan
* @date 2018/5/12 21:01
* 将配置文件中的每一个属性值,映射到这个组件中
* @ConfigurationProperties:告诉SpringBoot将本类的所有属性和配置文件中相关的配置绑定
* prefix = "person" 配置文件中的哪个属性进行一一映射
* 只有这个组件是容器中的组件,才能使用容器提供的@ConfigurationProperties功能
*/
@Component
@ConfigurationProperties(prefix="person")
publicclassPerson{
privateStringlastName;
privateIntegerage;
privateBooleanboss;
privateDatebirthday;
privateMapmaps;
privateListlists;
privateDogdog;
我们可以导入导入配置文件处理器,以后编写配置就有提示了:
org.springframework.boot
spring-boot-configuration-processor
true
单元测试例子:
packagecom.example.demo;
importcom.example.demo.bean.Person;
importorg.junit.Test;
importorg.junit.runner.RunWith;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.boot.test.context.SpringBootTest;
importorg.springframework.test.context.junit4.SpringRunner;
/**
* SpringBoot单元测试
* 可以在测试期间很方便的类似编码一样进行自动注入
*/
@RunWith(SpringRunner.class)
@SpringBootTest
publicclassDemoApplicationTests{
@Autowired
Personperson;
@Test
publicvoidcontextLoads() {
System.out.println(person);
}
}
1、properties文件在idea中默认utf-8可能会乱码
结果发现中文乱码,需要进行设置:勾选Transparent native-to-ascii conversion,转出ascii码
这样就不会乱码了:
2、@Value与@ConfigurationProperties获取值比较
@ConfigurationProperties@Value
功能批量注入配置文件中的属性一个一个指定
松散绑定(松散语法)支持不支持
SpEL不支持支持
JSR303数据校验支持不支持
复杂类型封装支持不支持
配置文件yml还是properties他们都能获取到值;
如果说,我们只是在业务逻辑中要获取一下配置文件中的某项值,使用@Value;
如果说,我们编写了一个JavaBean和配置文件进行映射,我们就直接使用@ConfigurationProperties;
3、配置文件注入值数据校验
@Component
@ConfigurationProperties(prefix="person")
@Validated
publicclassPerson{
//lastName必须是邮箱格式,default message [不是一个合法的电子邮件地址]
//@Value("${person.last-name}")
privateStringlastName;
privateIntegerage;
4、@PropertySource与@ImportResource
@PropertySource:加载指定的配置文件
/**
* @author Alan
* @date 2018/5/12 21:01
* 将配置文件中的每一个属性值,映射到这个组件中
* @ConfigurationProperties:告诉SpringBoot将本类的所有属性和配置文件中相关的配置绑定
* prefix = "person" 配置文件中的哪个属性进行一一映射
* 只有这个组件是容器中的组件,才能使用容器提供的@ConfigurationProperties功能
* @ConfigurationProperties(prefix = "person")默认从全局配置文件中获取值
*/
@PropertySource(value="classpath:person.properties")
@Component
@ConfigurationProperties(prefix="person")
//@Validated
publicclassPerson{
//lastName必须是邮箱格式,default message [不是一个合法的电子邮件地址]
//@Value("${person.last-name}")
privateStringlastName;
privateIntegerage;
privateBooleanboss;
privateDatebirthday;
privateMapmaps;
privateListlists;
privateDogdog;
@ImportResource:导入Spring的配置文件,让配置文件里面的内容生效
Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别;
想让Spring的配置文件生效,加载进来,@ImportResource标注在一个配置类上;
beans.xml:
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">
SpringBootApplication类:
//导入Spring的配置文件,使其生效
@ImportResource(locations={"classpath:beans.xml"})
@SpringBootApplication
publicclassDemoApplication{
publicstaticvoidmain(String[]args) {
SpringApplication.run(DemoApplication.class,args);
}
}
test类:
@RunWith(SpringRunner.class)
@SpringBootTest
publicclassDemoApplicationTests{
@Autowired
Personperson;
@Autowired
ApplicationContextioc;
@Test
publicvoidhelloservice(){
Booleanb=ioc.containsBean("helloservice");
System.out.println(b);
}
单元测试结果:
不来编写Spring的配置文件:
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">
Spring Boot推荐的给容器中添加组件的方式:推荐使用全注解的方式
1、配置类======Spring配置文件
2、使用@Bean给容器中添加组件
/**
* @author Alan
* @date 2018/5/12 22:30
* @Configuration:指明当前类是一个配置文件,就是来替代之前的Spring配置文件
* 配置文件使用标签添加组件
*/
@Configuration
publicclassMyAppConfig{
//将方法的返回值添加到容器中,容器中这个组件默认的id就是方法名
@Bean
publicHelloServicehelloService(){
System.out.println("@Bean给容器添加组件了...");
returnnewHelloService();
}
}
4、配置文件占位符
1、随机数
${random.value}、${random.int}、${random.long}
${random.int(10)}、${random.int[1024,65536]}
2、占位符获取之前配置的值,如果没有可以使用:指定默认值
person.last-name=张三${random.uuid}
person.age=${random.int}
person.boss=true
person.birthday=2019/02/03
person.maps.k1=v1
person.maps.k2=v2
person.lists=a,b,c
person.dog.name=${person.hello:hello}小狗
person.dog.age=2
5、Profile
1、多profile文件
我们在主配置文件编写的时候,文件名可以是application-{profile}.properties/yml
默认使用application.properties
2、yml支持多文档块方式
server:
port: 8080
spring:
profiles:
active: prod
---
server:
port: 8083
spring:
profiles: dev
---
server:
port: 8084
spring:
profiles: prod#指定属于哪个环境
3、激活指定profile
1、在配置文件中指定spring.profiles.active=dev
2、命令行:
java -jar demo-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev
可以直接在测试的时候,配置传入命令行参数
利用idea的maven插件进行打包(双击package)
之后target目录下会生成jar文件,target右键-show in explorer,然后地址栏输入cmd,这样就进入了target目录,然后输入如下命令:java -jar demo-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev
端口就启动了dev下的端口号,而不是默认配置文件里面的prod端口号(8084)
3、虚拟机参数
-Dspring.profiles.active=dev
6、配置文件的加载位置
Spring Boot启动会扫描以下位置的application.properties或者application.yml文件作为Spring Boot的默认配置文件
-file:./config/
-file:./
-classpath:/config
-classpath:/
优先级,由高到低,高优先级的配置会覆盖低优先级的配置;
Spring Boot从4个位置全局加载主配置文件;互补配置
我们还可以通过spring.config.location来改变默认的配置文件位置
项目打包好后,我们可以使用命令行参数的形式,启动项目的时候指定配置文件的新位置;指定配置文件和默认加载的这些配置文件共同起作用,形成互补配置。解释:主要是针对运维,比如项目打包好后是8084,但是需要改变端口号,我们只要命令行运行时加上--spring.config.location=G:/application.properties,这样项目就可以通过8085访问了,不需要重新打包jar包,通过加载外部配置文件即可办到,比较方便。
比如在D盘新建一个配置文件,更改端口为8085:
IDEA-terminal:
cd target
D:\idea project\SpringBoot-02-helloworld\target>java -jar demo-0.0.1-SNAPSHOT.jar --spring.config.location=D:/application.properties
项目启动时的端口就是8085了:
7、外部配置加载顺序
1.命行参数
java -jar demo-0.0.1-SNAPSHOT.jar --server.port=8087 --server.context-path=/abc
多个配置用空格分开,--配置项=值
2.来自 java: comp/env的ND属性3.Java系统属性( System getproperties0)4.操作系统环境变量
Random Value Property Source配置的 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注解类上的@ PropertySource11.通过 SpringApplication. setDefaultproperties指定的默认属性
8、自动配置原理
配置文件能写什么?怎么写?自动配置原理,参见:
https://docs.spring.io/spring-boot/docs/2.0.2.RELEASE/reference/htmlsingle/#appendix
1、自动配置原理:
1)Spring Boot启动的时候,加载主配置类,开启了自动配置功能@EnableAutoConfiguration
2)@EnableAutoConfiguration的作用:
利用AutoConfigurationImportSelector给容器中导入一些组件;
可以查看selectImports()方法的内容:
List configurations = this.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.CassandraReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.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.MongoReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\
org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
org.springframework.boot.autoconfigure.reactor.core.ReactorCoreAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientAutoConfiguration,\
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.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.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
每一个这样的xxxAutoConfiguration类都是容器中的一个组件,到加入到容器中;用他们来做自动配置;
3)每一个自动配置类进行自动配置功能;
4)以HttpEncodingAutoConfiguration(Http编码自动配置)为例解释自动配置原理;
@Configuration//表示这是一个配置类,以前的配置文件一样,也可以给容器中添加组件
@EnableConfigurationProperties({HttpEncodingProperties.class})//启用指定类的ConfigurationProperties功能,将配置文件中对应的值和HttpEncodingProperties绑定起来;并把HttpEncodingProperties加入到ioc容器中
@ConditionalOnWebApplication(//sping底层@Conditional注解,根据不同的条件,如果满足指定的条件,整个配置类里面的配置就会生效:判断当前应用是否为web应用,如果是,当前配置类生效
type=Type.SERVLET
)
@ConditionalOnClass({CharacterEncodingFilter.class})//判断当前项目有没CharacterEncodingFilte类:SpringMVC中进行乱码解决的过滤器;
//判断文件是否存在某个配置:spring.http.encoding.enabled,如果不存在,判断也是成立的,即使配置文件中不配置spring.http.encoding.enabled=true,也是默认生效的;
@ConditionalOnProperty(
prefix="spring.http.encoding",
value={"enabled"},
matchIfMissing=true
)
publicclassHttpEncodingAutoConfiguration{
//他已经和SpringBoot的配置文件映射了
privatefinalHttpEncodingPropertiesproperties;
//只有一个有参构造器的情况下,参数的值就会从容器中拿
publicHttpEncodingAutoConfiguration(HttpEncodingPropertiesproperties) {
this.properties=properties;
}
@Bean//给容器中添加一个组件,这个组件的某些值需要从properties中获取
@ConditionalOnMissingBean
publicCharacterEncodingFiltercharacterEncodingFilter() {
CharacterEncodingFilterfilter=newOrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpEncodingProperties.Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpEncodingProperties.Type.RESPONSE));
returnfilter;
}
根据当前不同的条件判断,决定这个配置类是否生效;
一旦这个配置类生效,这个配置类就会给容器中添加各种组件,这些组件的属性是从对应的properties类中获取的,这些类里的每一个属性又是和配置文件绑定的;
5)所有在配置文件中能配置的属性都是在xxxProperties类中封装着;配置文件能配置什么就可以参照某个功能 对应的属性类;
@ConfigurationProperties(//从配置文件中获取指定的值和bean的属性进行绑定
prefix="spring.http.encoding"
)
publicclassHttpEncodingProperties{
publicstaticfinalCharsetDEFAULT_CHARSET;
精髓:
1)、Spring Boot启动会加载大量的自动配置类;
2)、我们看我们需要的功能有没有Spring Boot默认写好的自动配置类;
3)、我们再来看这个自动配置中到底配置了哪些组件;(只要我们要用的组件有,我们就不需要再来配置了);
4)、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性,我们就可以在配置文件中指定这些属性的值;
xxxAutoConfiguration:自动配置类;
会给容器中添加组件;
xxxProperties:封装配置文件中的相关属性;
举thymeleaf例子:ctrl+n:
@Configuration
@EnableConfigurationProperties({ThymeleafProperties.class})
@ConditionalOnClass({TemplateMode.class})
@AutoConfigureAfter({WebMvcAutoConfiguration.class,WebFluxAutoConfiguration.class})
publicclassThymeleafAutoConfiguration{
ThymeleafProperties.class:
@ConfigurationProperties(
prefix="spring.thymeleaf"
)
publicclassThymeleafProperties{
privatestaticfinalCharsetDEFAULT_ENCODING;
publicstaticfinalStringDEFAULT_PREFIX="classpath:/templates/";
publicstaticfinalStringDEFAULT_SUFFIX=".html";
privatebooleancheckTemplate=true;
privatebooleancheckTemplateLocation=true;
privateStringprefix="classpath:/templates/";
privateStringsuffix=".html";
privateStringmode="HTML";
privateCharsetencoding;
privatebooleancache;
privateIntegertemplateResolverOrder;
privateString[]viewNames;
privateString[]excludedViewNames;
privatebooleanenableSpringElCompiler;
privatebooleanenabled;
privatefinalThymeleafProperties.Servletservlet;
privatefinalThymeleafProperties.Reactivereactive;
这样application.properties文件中可以加的配置可以有:
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffi=.html
spring.thymeleaf.checkTemplate=true
2、细节
1、@Conditional派生注解(Spring注解版@Conditional作用)
作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置里面的内容才能生效;
自动配置类在一定条件下才能生效;
我们可以在配置文件中启动debug=true属性来让控制台打印自动配置报告;这样我们就可以方便知道哪些自动配置类生效;
============================
CONDITIONSEVALUATIONREPORT
============================
Positivematches:(自动配置类启用的)
-----------------
CodecsAutoConfigurationmatched:
-@ConditionalOnClassfoundrequiredclass'org.springframework.http.codec.CodecConfigurer';@ConditionalOnMissingClassdidnotfindunwantedclass(OnClassCondition)
Negativematches:(没用启用,没有匹配成功的自动配置类)
-----------------
ActiveMQAutoConfiguration:
Didnotmatch:
-@ConditionalOnClassdidnotfindrequiredclasses'javax.jms.ConnectionFactory','org.apache.activemq.ActiveMQConnectionFactory'(OnClassCondition)
4、Web开发
2、Spring Boot对静态资源的映射规则
@ConfigurationProperties(
prefix="spring.resources",
ignoreUnknownFields=false
)
publicclassResourcePropertiesimplementsResourceLoaderAware,InitializingBean{
//可以设置和静态资源有关的参数、缓存时间等
publicvoidaddResourceHandlers(ResourceHandlerRegistryregistry) {
if(!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
}else{
IntegercachePeriod=this.resourceProperties.getCachePeriod();
if(!registry.hasMappingForPattern("/webjars/**")) {
this.customizeResourceHandlerRegistration(registry.addResourceHandler(newString[]{"/webjars/**"}).addResourceLocations(newString[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(cachePeriod));
}
StringstaticPathPattern=this.mvcProperties.getStaticPathPattern();
if(!registry.hasMappingForPattern(staticPathPattern)) {
this.customizeResourceHandlerRegistration(registry.addResourceHandler(newString[]{staticPathPattern}).addResourceLocations(this.resourceProperties.getStaticLocations()).setCachePeriod(cachePeriod));
}
}
}
//配置欢迎页
@Bean
publicWelcomePageHandlerMappingwelcomePageHandlerMapping(
ResourcePropertiesresourceProperties) {
returnnewWelcomePageHandlerMapping(resourceProperties.getWelcomePage(),
this.mvcProperties.getStaticPathPattern());
}
//配置喜欢的图标
@Configuration
@ConditionalOnProperty(value="spring.mvc.favicon.enabled",matchIfMissing=true)
publicstaticclassFaviconConfiguration{
privatefinalResourcePropertiesresourceProperties;
publicFaviconConfiguration(ResourcePropertiesresourceProperties) {
this.resourceProperties=resourceProperties;
}
@Bean
publicSimpleUrlHandlerMappingfaviconHandlerMapping() {
SimpleUrlHandlerMappingmapping=newSimpleUrlHandlerMapping();
mapping.setOrder(Ordered.HIGHEST_PRECEDENCE+1);
//所有**/favicon.ico
mapping.setUrlMap(Collections.singletonMap("**/favicon.ico",
faviconRequestHandler()));
returnmapping;
}
@Bean
publicResourceHttpRequestHandlerfaviconRequestHandler() {
ResourceHttpRequestHandlerrequestHandler=newResourceHttpRequestHandler();
requestHandler
.setLocations(this.resourceProperties.getFaviconLocations());
returnrequestHandler;
}
}
}
1)、所有webjars/*都去classpath:/META-INF/resources/webjars/找资源;
webjars:以jar包的形式引入静态资源;
http://www.webjars.org/
比如引入jquery3.3.1:
org.webjars
jquery
3.3.1-1
http://localhost:8080/webjars/jquery/3.3.1-1/jquery.js 访问时只要写webjars下资源的名称即可:
2)“/”访问当前项目的任何资源:(静态资源的文件夹)**
"/":当前项目的根目录
"classpath:/META-INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/
localhost:8080/abc-->默认从静态资源文件夹里找abc资源;
3)、欢迎页:静态资源文件下的index.html页面,被"/"映射;**
localhost:8080/ 找index.html
比如在public文件夹下放index.html:
4)、所有的/favicon.ico都是在静态资源文件下找;**
比如在resource文件夹下放一个自定义图标:
3、模板引擎
JSP、Velocity、Freemarker、Thymeleaf;
SpringBoot推荐的Thymeleaf:
语法更简单、功能更强大;
1、引入Thymeleaf
切换thymeleaf版本
3.0.9.RELEASE
2.3.0
具体参见:
thymeleaf发布:https://github.com/thymeleaf/thymeleaf/releases
thymeleaf layout dialect:https://github.com/ultraq/thymeleaf-layout-dialect/releases
org.springframework.boot
spring-boot-starter-thymeleaf
Layout 2.0.0的版本开始视频thymeleaf3
2、Thymeleaf使用&语法
@ConfigurationProperties(prefix="spring.thymeleaf")
publicclassThymeleafProperties{
privatestaticfinalCharsetDEFAULT_ENCODING=Charset.forName("UTF-8");
privatestaticfinalMimeTypeDEFAULT_CONTENT_TYPE=MimeType.valueOf("text/html");
publicstaticfinalStringDEFAULT_PREFIX="classpath:/templates/";
publicstaticfinalStringDEFAULT_SUFFIX=".html";
//只要我们把html页面放到classpath:/templates/路径下,thymeleaf就能自动渲染
只要我们把html页面放到classpath:/templates/路径下,thymeleaf就能自动渲染
使用:
1、导入Thymeleaf的名称空间
2、使用Thymeleaf的使用
Title
success
这是欢迎信息
3、语法规则
1)、th:text:改变当前元素里面的文本内容;
th:任意html属性:来替换原生属性的值;参考官方pdf文档第10章(Attribute Precedence:属性优先级)
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.
等价于:
Name: Sebastian.
Surname: Pepper.
Nationality: Saturn.
Message Expressions: #{...}:获取国际化内容
Link URL Expressions: @{...}:获取URL:
@{/order/process(execId=${execId},execType='FAST')}
Fragment Expressions: ~{...}:片段引用的表达式
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:
Page 17 of 104No-Operation:
4、SpringMVC自动配置
https://docs.spring.io/spring-boot/docs/2.0.2.RELEASE/reference/htmlsingle/#boot-features-developing-web-applications
27.1.1 Spring MVC Auto-configuration
SpringBoot自动配置好了SpringMVC
以下是SpringBoot对SpringMVC的默认配置:
Spring Boot provides auto-configuration for Spring MVC that works well with most applications.
The auto-configuration adds the following features on top of Spring’s defaults:
Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
自动配置了ViewResolver(视图解析器:根据返回值得到视图对象(View),视图对象决定如何渲染 (转发?重定向?))
ContentNegotiatingViewResolver :组合所有的视图解析器;
如何定制:我们可以自己给容器中添加一个视图解析器;自动将其组合进来;
@Bean
publicViewResolvermyViewResolver(){
returnnewmyViewResolver();
}
privatestaticclassmyViewResolverimplementsViewResolver{
@Override
publicViewresolveViewName(StringviewName,Localelocale)throwsException{
returnnull;
}
}
在DispatcherServlet的doDispatch方法打断点,调试:
随便访问一个地址:http://localhost:8080/success
通过控制台的variable可以看到我们自己写的视图解析器添加到viewResolver了:
Support for serving static resources, including support for WebJars (covered later in this document)).
静态资源文件夹路径、webjars
Automatic registration of Converter, GenericConverter, and Formatter beans.
Converter:转换器: public String sayHello(User user):类型转换使用;
Formatter:格式化器:2017-12-01===Date;
@Bean
@ConditionalOnProperty(prefix="spring.mvc",name="date-format")//在文件中配置日期格式化规则
publicFormatterdateFormatter() {
returnnewDateFormatter(this.mvcProperties.getDateFormat());//日期格式化组件
}
自己添加的格式化器转换器:我们只要放入容器中即可;
Support for HttpMessageConverters (covered later in this document).
HttpMessageConverters:SpringMVC用来转换Http请求和响应的;User---json;
HttpMessageConverters:是从容器中确定的;获取所有的HttpMessageConverters;自己给容器中添加HttpMessageConverters,只需要注册到容器中即可(@Bean,@Componet);
importorg.springframework.boot.autoconfigure.web.HttpMessageConverters;
importorg.springframework.context.annotation.*;
importorg.springframework.http.converter.*;
@Configuration
publicclassMyConfiguration{
@Bean
publicHttpMessageConverterscustomConverters() {
HttpMessageConverteradditional=...
HttpMessageConverteranother=...
returnnewHttpMessageConverters(additional,another);
}
}
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来替换默认的;(要添加到容器中)
初始化WebDataBinder
请求数据绑定到javabean中
org.springframework.boot.autoconfigure.web:web所有的自动配置场景;
If you want to keep Spring Boot MVC features and you want to add additional MVC configuration (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc. If you wish to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver, you can declare a WebMvcRegistrationsAdapter instance to provide such components.
If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.
5、如何修改Spring Boot的默认配置
模式:
1)SpringBoot在配置很多组件的时候,先看容器中有无用户配置的组件(@Bean、@Component),如果有就用用户配置的,如果没有,才自动配置;如果有些组件可以有多个(ViewResolver)将用户配置的和自己默认的组合起来;
2)、扩展SpringMVC
编写一个配置类(@Configuration),是WebMvcConfigurer 类型的,不能标注EnableWebMvc注解。