目录
查看自动配置了哪些组件:
dev-tools:对于静态页面来说,一个ctrl+F9重新编译就行,相当于重新启动,速度较快;
Spring Initailizr:
Yaml:
Web开发:
欢迎页:
静态资源配置原理分析:
补:@Bean一般是与@Configuration进行联用的;
debug=true:Negative配置生效,postive:配置生效;并且具有原因
是否需要修改:
1.可以参考文档进行修改配置项:比如说在application.properties中对要修改的组件内容进行设置:设置springboot 启动时图片加载的位置;
spring.banner.image.location=classpath:banner.jpg
2.自定义添加或者替换组件@Bean、@Component
也可以自定义器XXXCustomizer,将原来的组件行为进行修改;
JRebel:
springboot中的重加载reload:当你的后端代码发生变化时,一个重加载就行,速度非常快;
!-- build快捷方式-->
org.springframework.boot
spring-boot-devtools
true
好处:帮助用户将boot架构全部搭建好了,starter-XXX(这种场景你都可以自己去配)
还有项目结构resource下的static静态资源+Template页面存放地+application.properties配置文件;
其实我觉得这玩意也就帮你项目结构多配了几个文件,然后pom.xml里帮你配了几个依赖罢了;
yet another Markup language:仍然是一种标记语言
适合以数据为中心的配置文件;
层级关系的表示:利用缩进,空格表示,相同层级左对齐即可;
对象:键值对集合
注意:当Properties与yaml同时存在时,@Configuration(prefix="")优先Properties文件的加载,这个我们到后面再说;
如果要利用文件对属性进行赋值那么不要忘记将实体类注册到容器中@Component,如果是第三方的bean,则不要忘记在配置类中+@EnableConfigurationProperties;
实体类:
package com.atguigu.boot.springboot02.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author diao 2022/1/28
*/
@ConfigurationProperties(prefix = "person")
@Component
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
private String userName;
private Boolean boss;
private Date birth;
private Integer age;
private Pet pet;
private String[] interests;
private List animal;
// 在yml中,String的内容为键,Object为对应值 score为prefix下的内容
private Map score;
private Set salarys;
// 分为两种宠物health与sick(第一个参数),每一种具有自己的list
private Map> allPets;
}
controller层,这里@restController返回json字符串:
@RestController//返回json字符串
public class HelloController {
@Autowired//将组件person注入
Person person;
@RequestMapping("/hello")
public Person hello(){
String userName = person.getUserName();
System.out.println(userName);
return person;
}
}
语法:
person:
userName: "Fairy \n legion"
# 单引号会将\n作为字符串输出,单引号会将\n进行转义
# 双引号不会进行转义,像\n就直接解释换行(\n本身就是转义字符)
boss: true
birth: 2002/5/14
age: 19
# interest: [篮球,足球] 行内写法
# 数组写法
interest:
- 篮球
- 足球
- 编程
animal: [阿猫,阿狗]
# Json字符串写法
score: {english: 60,Java: 99}
# 数组写法
salarys:
- 11111
- 9000
# 单个属性,没有集合这种的
pet:
name: 阿衰
weight: 99.99
allPets:
sick:
- {name: 阿构,weight: 99.99}
- name: 阿猫
weight: 88.88
- name: 阿冲
weight: 99.99
health:
# json写法
- {name: 阿构,weight:99.9}
- name: 阿猫
weight: 88
# yaml好处:层次分明,更好的区分功能
像这种单个属性用户名字之类的,我们直接键值对映射就好(userName: Fairy)如果值用了字符串表示,那么里面的转义字符就不会被转义,单引号的话就会将转义字符转义;比如说\n,转义的话就会变成\n,不转义就换行;
数组写法:
interest:
- 篮球
- 足球
- 编程
行内写法:
animal: [阿猫,阿狗]
json字符串写法:
score: {english: 60,Java: 99}
Yaml提示:
spring-boot-configuration-processor;配置处理器
org.springframework.boot
spring-boot-configuration-processor
true
静态资源访问:
只要静态资源放在类路径下:/static,/public,/resources,/META/resources,都可以访问;但是像我们如果配置了拦截器的话就要注意,是否静态资源会被拦截,一般我们可以加一个static-path-pattern:
访问流程:
首先你在网页中作出请求,按理说是先寻找controller的url,如果没有找到,就去静态资源里面找;
webJar:
将jquery,bootstrap这些前端框架变成jar包,当你把他的依赖导入之后,他可以被映射;
org.webjars.bower
jquery
3.2.1
打包后,在maven中,你可以看见他的jar包下具有resources文件,下面有webjars,然后你按照下面的路径访问就可以得到他的资源文件
欢迎页配置有两种:1、在静态资源下配置一个index页面,他会被默认为静态资源;2、用controller层下写一个方法,(处理index请求)用来返回index页面;
配置静态资源访问路径:访问任何静态资源都需要加设定好的前缀:spring.mvc.static-path-pattern:(*:但是它会影响欢迎页以及favicon的显示)
# 配置静态资源访问路径,欢迎页会失效
#spring:
# mvc:
# static-path-pattern: /res/**
设置静态资源访问的根路径:只有在设置好的根路径下,静态资源才会被扫描到并加载;
web.resources.static-location:/xxx/
#静态资源根路径的配置,那么你的静态资源只会在你配置好了的资源根路径下寻找
# web:
# resources:
# static-locations: /static/
当类中有一个含参构造器时,所有参数值会从容器中找
WebMvcAutoConfiguration(web下自动配置)中的构造器:
WebMvcAutoConfigurationAdapter()//自动配置的自定义适配器
webProperties:获取spring.web绑定的所有的值的对象;
mvcProperties:获取和spring.mvc绑定的所有属性的值;
ListableBeanFactory:spring的bean工厂beanFactory
servletRegisterationBean:给应用注册Servlet、Filter...等组件
public WebMvcAutoConfigurationAdapter(WebProperties webProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory, ObjectProvider messageConvertersProvider, ObjectProvider resourceHandlerRegistrationCustomizerProvider, ObjectProvider dispatcherServletPath, ObjectProvider> servletRegistrations) {
this.resourceProperties = webProperties.getResources();
this.mvcProperties = mvcProperties;
this.beanFactory = beanFactory;
this.messageConvertersProvider = messageConvertersProvider;
this.resourceHandlerRegistrationCustomizer = (WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer)resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
this.dispatcherServletPath = dispatcherServletPath;
this.servletRegistrations = servletRegistrations;
this.mvcProperties.checkConfiguration();
}
WebMvcAutoConfiguration(web下自动配置)类中,还导入很多的bean,根据条件注解可知,如果没有就给你配上(根据类的名字,可以判断基本上都是根视图与controller层方面相关的)
@Bean
@ConditionalOnMissingBean
public InternalResourceViewResolver defaultViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix(this.mvcProperties.getView().getPrefix());
resolver.setSuffix(this.mvcProperties.getView().getSuffix());
return resolver;
}
可以发现他其实就是个配置类,具有@EnableConfigurationProperties(xxx.class)注解,说明它将 xxx类注册到了容器中,并且配置了对应组件的功能;
@EnableConfigurationProperties({WebProperties.class})
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {
private final Resources resourceProperties;
private final WebMvcProperties mvcProperties;
private final WebProperties webProperties;
private final ListableBeanFactory beanFactory;
private final WebMvcRegistrations mvcRegistrations;
private ResourceLoader resourceLoader;
public EnableWebMvcConfiguration(ResourceProperties resourceProperties, WebMvcProperties mvcProperties, WebProperties webProperties, ObjectProvider mvcRegistrationsProvider, ListableBeanFactory beanFactory) {
this.resourceProperties = (Resources)(resourceProperties.hasBeenCustomized() ? resourceProperties : webProperties.getResources());
this.mvcProperties = mvcProperties;
this.webProperties = webProperties;
this.mvcRegistrations = (WebMvcRegistrations)mvcRegistrationsProvider.getIfUnique();
this.beanFactory = beanFactory;
}
资源处理默认规则:
里面可以发现webjar的配置方法
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
} else {
this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
registration.addResourceLocations(this.resourceProperties.getStaticLocations());
if (this.servletContext != null) {
ServletContextResource resource = new ServletContextResource(this.servletContext, "/");
registration.addResourceLocations(new Resource[]{resource});
}
});
点入resourceProperties后进入WebProperties中,里面有判断isAddMappings()方法;如果是true则下面webjars之类的可以使用,如果为false则警用功能;
@ConfigurationProperties("spring.web")
public class WebProperties {
private Locale locale;
private WebProperties.LocaleResolver localeResolver;
private final WebProperties.Resources resources;
public WebProperties() {
this.localeResolver = WebProperties.LocaleResolver.ACCEPT_HEADER;
this.resources = new WebProperties.Resources();
}
public Locale getLocale() {
return this.locale;
}
public void setLocale(Locale locale) {
this.locale = locale;
}
public WebProperties.LocaleResolver getLocaleResolver() {
return this.localeResolver;
}
public void setLocaleResolver(WebProperties.LocaleResolver localeResolver) {
this.localeResolver = localeResolver;
}
public WebProperties.Resources getResources() {
return this.resources;
}
public static class Resources {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"};
private String[] staticLocations;
private boolean addMappings;
private boolean customized;
private final WebProperties.Resources.Chain chain;
private final WebProperties.Resources.Cache cache;
public Resources() {
this.staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
this.addMappings = true;
this.customized = false;
this.chain = new WebProperties.Resources.Chain();
this.cache = new WebProperties.Resources.Cache();
}
这里从webProperties(也就是WebAutoConfiguration中的resourceProperties属性)可以知道,很多配置比如:缓存cache、视图解析等等;
public static class Cache {
private boolean customized = false;
@DurationUnit(ChronoUnit.SECONDS)
private Duration period;
private final WebProperties.Resources.Cache.Cachecontrol cachecontrol = new WebProperties.Resources.Cache.Cachecontrol();
private boolean useLastModified = true;
public Cache() {
}
如果在yaml中配置spring.web.resources.add-mapping为false,那么静态资源被禁用
#禁用静态资源
spring:
web:
resources:
add-mappings: false
可以发现WebProperties中有一个内部类Resouces设置静态资源的路径;
public static class Resources {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"};
private String[] staticLocations;
private boolean addMappings;
private boolean customized;
private final WebProperties.Resources.Chain chain;
private final WebProperties.Resources.Cache cache;
}
欢迎页:
在WebMvcAutoConfiguration下的欢迎页设置,里面用到了WelcomePageHandlerMapping这个类;
首先你先明白handlerMapping的作用:处理器映射,每一个handler能处理哪些请求,找到之后,根据反射处理那些找到了的请求方法;
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
welcomePageHandlerMapping.setInterceptors(this.getInterceptors(mvcConversionService, mvcResourceUrlProvider));
welcomePageHandlerMapping.setCorsConfigurations(this.getCorsConfigurations());
return welcomePageHandlerMapping;
}
然后欢迎页的配置你可以发现:它弄了个含参构造器,里面进行了欢迎页的处理判断:当欢迎页不为空, 并且默认路径为/**就找到index.html,所以说在yml中,你不能设置spring.mvc.static-path-pattern: 不然就会覆盖原来的默认路径;
else if从controller层中找到index的页面请求,也可以得到欢迎页;
final class WelcomePageHandlerMapping extends AbstractUrlHandlerMapping {
private static final Log logger = LogFactory.getLog(WelcomePageHandlerMapping.class);
private static final List MEDIA_TYPES_ALL;
WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders, ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) {
if (welcomePage != null && "/**".equals(staticPathPattern)) {
logger.info("Adding welcome page: " + welcomePage);
this.setRootViewName("forward:index.html");
} else if (this.welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {
logger.info("Adding welcome page template: index");
this.setRootViewName("index");
}
}