Springboot笔记(3):Springboot yml/Web场景/雷神

目录

1、最佳实践-SpringBoot应用如何编写

2、最佳实践-Lombok简化开发

3、最佳实践-dev-tools

4、最佳实践-Spring Initailizr

5、配置文件-yaml的用法

数据类型

实例

6、配置文件-自定义类绑定的配置提示

7、web场景-web开发简介

8、web场景-静态资源规则与定制化

8.1、静态资源访问

8.2、web场景-welcome与favicon功能

欢迎页支持

自定义Favicon

9、web场景-【源码分析】-静态资源原理

9.1、

9.2、注意:

9.3、资源处理的默认规则:

9.3、数据缓存设置:

​9.4、访问 /webjars

​9.5、访问 /**

9.6、欢迎页的处理规则:

9.7、根据上述代码,我们可以同过配置禁止所有静态资源规则:

9.8、静态资源规则:


1、最佳实践-SpringBoot应用如何编写

  • 引入场景依赖
    • 官方文档
  • 查看自动配置了哪些(选做)
    • 自己分析,引入场景对应的自动配置一般都生效了
    • 配置文件中debug=true开启自动配置报告。
      • Negative(不生效)
      • Positive(生效)
  • 是否需要修改
    • 参照文档修改配置项
      • 官方文档
      • 自己分析。xxxxProperties绑定了配置文件的哪些。
  • 自定义加入或者替换组件
    • @Bean、@Component…
  • 自定义器 XXXXXCustomizer;

配置文件中debug=true开启自动配置报告:

  • Positive matches    生效的
  • Negative matches   不生效的
  • Unconditional classes。 

============================

CONDITIONS EVALUATION REPORT
============================


Positive matches:
-----------------

   AopAutoConfiguration matched:
      - @ConditionalOnProperty (spring.aop.auto=true) matched (OnPropertyCondition)
 

Negative matches:
-----------------

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


Unconditional classes:
----------------------    org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration

修改启动时的图像

  •  spring.banner.image.location = classpath.2.jpg

2、最佳实践-Lombok简化开发

Lombok用标签方式代替构造器、getter/setter、toString()等鸡肋代码。

spring boot已经管理Lombok。引入依赖:

 <dependency>
     <groupId>org.projectlombok</groupId>
     <artifactId>lombok</artifactId>
</dependency>

IDEA中File->Settings->Plugins,搜索安装Lombok插件。

@NoArgsConstructor
//@AllArgsConstructor
@Data
@ToString
@EqualsAndHashCode
public class User {

    private String name;
    private Integer age;

    private Pet pet;

    public User(String name,Integer age){
        this.name = name;
        this.age = age;
    }
}

简化日志开发

@Slf4j
@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String handle01(@RequestParam("name") String name){
        log.info("请求进来了....");
        return "Hello, Spring Boot 2!"+"你好:"+name;
    }
}

3、最佳实践-dev-tools

热部署,热更新,以后更新完代码后使用command + f9即可

在IDEA中,项目或者页面修改以后:comand +F9(Build Project)。

Restart:实际上这是自动重启,类似于手动点击重启按钮。

JRebel:付费,重新编译。

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

4、最佳实践-Spring Initailizr

Spring Initailizr是创建Spring Boot工程向导。

在IDEA中,菜单栏New -> Project -> Spring Initailizr。

5、配置文件-yml的用法

        同以前的properties用法

        YAML 是 “YAML Ain’t Markup Language”(YAML 不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:“Yet Another Markup Language”(仍是一种标记语言)。

        非常适合用来做以数据为中心的配置文件。

基本语法

  • key: value;kv之间有空格
  • 大小写敏感
  • 使用缩进表示层级关系
  • 缩进不允许使用tab,只允许空格
  • 缩进的空格数不重要,只要相同层级的元素左对齐即可
  • '#'表示注释
  • 字符串无需加引号,如果要加,单引号’’表示字符串内容会被 转义  、双引号""表示字符串内容不转义

数据类型

  • 字面量:单个的、不可再分的值。date、boolean、string、number、null

k: v

  • 对象:键值对的集合。map、hash、set、object

#行内写法:  

k: {k1:v1,k2:v2,k3:v3}

#或

k: 
  k1: v1
  k2: v2
  k3: v3

  • 数组:一组按次序排列的值。array、list、queue

#行内写法:  

k: [v1,v2,v3]

#或者

k:
 - v1
 - v2
 - v3

实例

@Data
public class Person {
    private String userName;
    private Boolean boss;
    private Date birth;
    private Integer age;
    private Pet pet;
    private String[] interests;
    private List<String> animal;
    private Map<String, Object> score;
    private Set<Double> salarys;
    private Map<String, List<Pet>> allPets;
}

@Data
public class Pet {
    private String name;
    private Double weight;
}

用yaml表示以上对象

person:
  userName: zhangsan
  boss: false
  birth: 2019/12/12 20:12:33
  age: 18
  pet: 
    name: tomcat
    weight: 23.4
  interests: [篮球,游泳]
  animal: 
    - jerry
    - mario
  score:
    english: 
      first: 30
      second: 40
      third: 50
    math: [131,140,148]
    chinese: {first: 128,second: 136}
  salarys: [3999,4999.98,5999.99]
  allPets:
    sick:
      - {name: tom}
      - {name: jerry,weight: 47}
    health: [{name: mario,weight: 47}]

6、配置文件-自定义类绑定的配置提示

自定义的类和配置文件绑定一般没有提示。若要提示,添加如下依赖:

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

<!-- 下面插件作用是工程打包时,不将spring-boot-configuration-processor打进包内,让其只在编码的时候有用 -->
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <excludes>
                    <exclude>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-configuration-processor</artifactId>
                    </exclude>
                </excludes>
            </configuration>
        </plugin>
    </plugins>
</build>

7、web场景-web开发简介

  • 大多场景我们都无需自定义配置
  • 内容协商视图解析器和BeanName视图解析器
  • 静态资源(包括webjars)
  • 自动注册 Converter,GenericConverter,Formatter
  • 支持 HttpMessageConverters (后来我们配合内容协商理解原理)
  • 自动注册 MessageCodesResolver (国际化用)
  • 静态index.html 页支持
  • 自定义 Favicon
    • 自动使用 ConfigurableWebBindingInitializer (DataBinder负责将请求数据绑定到JavaBean上)

不用@EnableWebMvc注解。使用 @Configuration + WebMvcConfigurer 自定义规则

声明 WebMvcRegistrations 改变默认底层组件

使用 @EnableWebMvc+@Configuration+DelegatingWebMvcConfiguration 全面接管SpringMVC

8、web场景-静态资源规则与定制化

8.1、静态资源访问

  • 存放位置:只要静态资源放在类路径下: /static ( /public 、 /resources 、 /META-INF/resources
  • 访问 : 当前项目根路径/ + 静态资源名
  • 原理: 静态映射/**

访问:http://localhost:8888/4.jpeg    http://localhost:8888/1.jpeghttp://localhost:8888/2.jpeg

http://localhost:8888/3.jpeg

处理原理:请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器,到静态资源路径下找。静态资源也找不到则响应404页面。

静态资源访问前缀

application.yml 

spring:
  mvc:
    static-path-pattern: /res/**
  • *  代表一层目录或目录下的一个文件
  • ** 任意层目录任意文件

        访问路径:当前项目 + static-path-pattern + 静态资源名 = 静态资源文件夹下找

      http://localhost:8888/res/1.jpeg

        也可以改变默认的静态资源路径,/static、/public/resources/META-INF/resources失效。只有/haha/下的资源有效

spring:
  resources:
    static-locations: [classpath:/haha/]

8.2、web场景-welcome与favicon功能

官方文档







欢迎页支持

  • 静态资源路径(resources路径)下 index.html。 

    • 可以配置静态资源路径
    • 但是不可以配置静态资源的访问前缀。否则导致 index.html不能被默认访问
    • controller能处理/index。
spring:
#  mvc:
#    static-path-pattern: /res/**   这个会导致welcome page功能失效
  resources:
    static-locations: [classpath:/haha/]

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>欢迎你</title>
</head>
<body>

    <h1>欢迎你</h1>
</body>
</html>

自定义Favicon

指网页标签上的小图标。

favicon.ico 放在静态资源目录下即可。

spring:
#  mvc:
#    static-path-pattern: /res/**   这个会导致 Favicon 功能失效

9、web场景-【源码分析】-静态资源原理

9.1、

  • SpringBoot启动默认加载 xxxAutoConfiguration 类(自动配置类)
  • SpringMVC功能的自动配置类WebMvcAutoConfiguration,生效

@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
		ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
    ...
}
  • 给容器中配置的内容:
    • 注意@EnableConfigurationProperties 代表绑定配置文件
    • 配置文件的相关属性的绑定:WebMvcProperties==spring.mvc、ResourceProperties==spring.resources
    • WebMvcProperties和ResourceProperties注册到容器中

public class WebMvcAutoConfiguration {
        
        @Configuration(proxyBeanMethods = false)
        @Import(EnableWebMvcConfiguration.class)
        @EnableConfigurationProperties({ WebMvcProperties.class,         ResourceProperties.class })
        @Order(0)
public static class WebMvcAutoConfigurationAdapter implements         WebMvcConfigurer {

        有参构造器所有参数的值都会从容器中确定
        public WebMvcAutoConfigurationAdapter(WebProperties webProperties,         WebMvcProperties mvcProperties,
        ListableBeanFactory beanFactory,         ObjectProvider<HttpMessageConverters> messageConvertersProvider,
        ObjectProvider<ResourceHandlerRegistrationCustomizer>         resourceHandlerRegistrationCustomizerProvider,
        ObjectProvider<DispatcherServletPath> dispatcherServletPath,
        ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {
    this.mvcProperties = mvcProperties;
    this.beanFactory = beanFactory;
    this.messageConvertersProvider = messageConvertersProvider;
    this.resourceHandlerRegistrationCustomizer =          resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
    this.dispatcherServletPath = dispatcherServletPath;
    this.servletRegistrations = servletRegistrations;
    this.mvcProperties.checkConfiguration();
    }

  }
}
@ConfigurationProperties(prefix = "spring.mvc")
public class WebMvcProperties {
}
@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
public class ResourceProperties {
}

9.2、注意:

一个配置类只有一个有参构造器,那有参构造器所有参数的值都会默认从容器中确定。

则WebMvcAutoConfigurationAdapter会从容器中获取以下参数

  • ResourceProperties resourceProperties:获取和spring.resources绑定的所有的值的对象
  • WebMvcProperties mvcProperties :获取和spring.mvc绑定的所有的值的对象
  • ListableBeanFactory beanFactory :Spring的beanFactory
  • HttpMessageConverters :找到所有的HttpMessageConverters
  • ResourceHandlerRegistrationCustomizer :找到 资源处理器的自定义器
  • DispatcherServletPath 
  • ServletRegistrationBean 给应用注册Servlet、Filter…

9.3、资源处理的默认规则:

public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {
            
        @Override
		public 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));
			}
		}

}

WebMvcAutoConfigurationAdapterl里的addResourceHandlers:

代表加载资源的路径。

  • 拿到ResourceProperties配置文件里绑定的所有内容,即能获取addMappings属性,默认true。
  • 如果addMappings属性设置为false,则直接返回,则不会走下面获取静态资源的代码,则静态资源无论放哪都不会被访问到。
  •  当Cache 和 Cachecontrol 返回304给客户端,让客户端缓存该页面内容一段时间
  • 当访问/webjars/**下面的所有请求时,她会到 classpath:/META-INF/resources/webjars/ 路径下找资源。

9.3、数据缓存设置:

@Override
public 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();

}

resources:
  cache:
    period: 332536000


9.4、访问 /webjars

会自动到classpath:/META-INF/resources/webjars中找资源

http://localhost:8888/webjars/jquery/3.5.1/jquery.min.js

9.5、访问 /**

staticLoscations就是

private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
      "classpath:/resources/", "classpath:/static/", "classpath:/public/" };

9.6、欢迎页的处理规则:

handlerMapping:处理器映射器,保存了每一个handler能处理那些请求。

...
public class WebMvcAutoConfiguration {
    ...
	public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {
        ...
		@Bean
		public 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;
		}
    

WelcomePageHandlerMapping的构造方法如下:

WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders,
                          ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) {
    if (welcomePage != null && "/**".equals(staticPathPattern)) {
        //要用欢迎页功能,必须是/**
        logger.info("Adding welcome page: " + welcomePage);
        setRootViewName("forward:index.html");
    }
    else if (welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {
        //调用Controller /index
        logger.info("Adding welcome page template: index");
        setRootViewName("index");
    }
}

要用欢迎页功能,必须将index.xml放到 /** 下。

 这构造方法内的代码也解释了web场景-welcome与favicon功能中配置static-path-pattern了,welcome页面和小图标失效的问题。
 

9.7、根据上述代码,我们可以同过配置禁止所有静态资源规则:

application.yaml中

spring:
  resources:
    add-mappings: false   #禁用所有静态资源规则

9.8、静态资源规则:

@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
public class ResourceProperties {

    private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {                       "classpath:/META-INF/resources/",
              "classpath:/resources/", "classpath:/static/", "classpath:/public/"

   };
    private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
    ...
   }

}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值