Spring Boot |SpringBoot的web开发原理

   日期:2020-05-04     浏览:97    评论:0    
核心提示:本文详细介绍了使用SpringBoot进行web开发的原理。想要将SpringBoot使用的很清楚,java

文章目录

  • 一、SpringBoot对静态资源的映射规则
    • 1.1 /webjars/映射
    • 1.2 staticPathPattern映射
    • 1.3 欢迎页映射
    • 1.4 标题图标映射
  • 二、使用Thymeleaf模板引擎
    • 2.1 Thymeleaf介绍
    • 2.2 语法规则
    • 2.3 表达式
  • 三、SpringMVC自动配置
    • 3.1 SpringMVC auto-configuration
    • 3.2 修改SpringBoot的默认配置
    • 3.3 扩展SpringMVC
    • 3.4 全面接管SpringMVC

使用SpringBoot进行web开发更加简单:

  1. 在创建SpringBoot应用时,选中我们需要的模块。
  2. SpringBoot已经默认将许多场景配置好了,只需要在配置文件中指定少量的配置就可以运行了。
  3. 剩下的就是自己编写业务代码。

想要将SpringBoot使用的很清楚,就需要搞清楚每一个组件SpringBoot是帮我们怎么配置的,用到了配置类的哪些信息,如何修改等。

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

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

SpringBoot中关于SpringMVC的相关配置都在WebMvcAutoConfiguration中。

WebMvcAutoConfiguration源码:
public class WebMvcAutoConfiguration {
		...
		@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("/webjarsfavicon.ico 都是在静态资源文件下找;

  • 即将标题图标

可以手动在application.properties中配置静态资源文件夹的路径:

spring.resources.static-locations=classpath:/mydisk1/,classpath:/mydisk2/

二、使用Thymeleaf模板引擎

2.1 Thymeleaf介绍

模板引擎的思想:页面模板Template中有一些动态的值需要使用到表达式,这些表达式来自我们组装的数据Data。将页面模板Template组装数据Data交给模板引擎Thymeleaf后,模板引擎按照组装数据将页面模板中的表达式解析并填充进而写出。

Thymeleaf是一款用于渲染XML/XHTML/HTML5内容的模板引擎。类似JSPVelocityFreeMaker等,它也可以轻易的与Spring MVC等Web框架进行集成作为Web应用的模板引擎。与其它模板引擎相比,Thymeleaf最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个Web应用。
Spring Boot推荐使用ThymeleafFreemarker等后现代的模板引擎技术;一但导入相关依赖,会自动配置ThymeleafAutoConfigurationFreeMarkerAutoConfiguration

引入Thymeleaf

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

自动渲染

ThymeleafProperties源码:
@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";

只要我们把HTML页面放在classpath:/templates/thymeleaf就能自动渲染。

2.2 语法规则

首先,导入thymeleaf的名称空间:xmlns:th="http://www.thymeleaf.org"

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

  • Controller
    @RequestMapping("/success")
    public String success(Map<String,Object> map){
        map.put("hello","你好");
        return "success";
    }
  • success页面
<body>
    <h1>成功1</h1>
    <div th:text="${hello}">这是欢迎信息</div>
</body>
  • th:text取值成功

除了使用th:text,还可以使用th:任意html属性,来替换原生属性的值。可以在 Thymeleaf官网 查看到属性的优先级。

2.3 表达式

可以在 Thymeleaf官网 的Standard Expression Syntax一栏查看表达式语法。

  • ${…}:获取变量值
		1)、获取对象的属性、调用方法
		2)、使用内置的基本对象:
			#ctx : the context object.
			#vars: the context variables.
			#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).
  • *{…}:选择表达式,当前对象/变量取值
*{}和`${}`在功能上是一样,不过有了改进:
使用
	<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>
替代↓
	<div>
		<p>Name: <span th:text="${session.userfirstName}">Sebastian</span>.</p>
		<p>Surname: <span th:text="${session.userlastName}">Pepper</span>.</p>
		<p>Nationality: <span th:text="${session.usernationality}">Saturn</span>.</p>
	</div>
  • #{...}:国际化消息

  • @{…}:定义url链接

		@{/order/process(execId=${execId},execType='FAST')}
  • ~{…}:片段引用表达式
		<div th:insert="~{commons :: main}">...</div>

举例:

Controller控制器

    @RequestMapping("/success")
    public String success(Map<String,Object> map){
        map.put("hello","<h1>你好</h1>");
        map.put("users", Arrays.asList("张三","李四","王五"));
        return "success";
    }

前台页面

<body>
    <h1>成功1</h1>
    <!--th:text 将div中的文本内容设置为指定值-->
    <div th:text="${hello}">转义</div>
    <div th:utext="${hello}">不转义</div>
    <hr/>
    <!--th:each每次遍历都会生成当前这个标签-->
    <h4 th:text="${user}" th:each="user:${users}"></h4>
    <hr/>
    <h4>
        <span th:each="user:${users}">[[${user}]]</span>
    </h4>
</body>

三、SpringMVC自动配置

3.1 SpringMVC auto-configuration

SpringMVC的自动配置可以参照SpringBoot官网第27节。

Spring Boot 自动配置好了SpringMVC,以下是SpringBoot对SpringMVC的默认配置:WebMvcAutoConfiguration

(1) 包含ContentNegotiatingViewResolverBeanNameViewResolver

  • ①自动配置了ViewResolver(视图解析器:根据方法的返回值得到视图对象(View),视图对象决定如何渲染or转发or重定向)
  • ContentNegotiatingViewResolver:组合所有的视图解析器,选择合适的视图解析器。
  • ③定制:我们可以自己给容器中添加一个视图解析器,ContentNegotiatingViewResolver会自动的将其组合进来。

演示定制视图解析器:

    @Bean
    public ViewResolver myViewResolver(){
        return new MyViewResolver();
    }

    private static class MyViewResolver implements ViewResolver{

        @Override
        public View resolveViewName(String s, Locale locale) throws Exception {
            return null;
        }
    }

(2) 支持提供静态资源,包括对WebJars的支持。上文已经介绍过,这里不做赘述。

(3) 自动注册了 ConverterGenericConverterFormatter 的beans.

  • Converter:类型转换器。
    如果页面带来的数据和Bean中的属性一一对应,SpringMVC就会进行自动封装。但容易出现类型转换问题,如将String文本信息转换为Integer类型。

  • Formatter:格式化器。
    如将页面带来的数据转换为Date类型,2017.12.17===Date。

自己添加的格式化转换器,放在容器中即可。

源码:
public class WebMvcAutoConfiguration {
		...
		@Override
		public void addFormatters(FormatterRegistry registry) {
			ApplicationConversionService.addBeans(registry, this.beanFactory);
		}
		...
}

(4) 配置了消息转换器HttpMessageConverters

  • HttpMessageConverters:消息转换器,SpringMVC用来转换Http请求和响应的。
  • HttpMessageConverters是从容器中确定,底层仍是获取所有的HttpMessageConverter,所以也可以将自己的组件注册到容器(@Bean,@Component)。

(5) MessageCodesResolver:定义错误代码生成规则

(6) ConfigurableWebBindingInitializer:定义错误代码生成规则

可以手动配置一个ConfigurableWebBindingInitializer来替换默认的,添加到容器中。
ConfigurableWebBindingInitializer可以初始化数据绑定器WebDataBinder
请求数据封装为JavaBean时需要用到WebDataBinder(其中涉及类型转换、格式化等)。

除了上面SpringMVC的几种自动配置,web场景还有很多的自动配置在org.springframework.boot.autoconfigure.web包中。

3.2 修改SpringBoot的默认配置

  • SpringBoot在自动配置组件的时候,先看容器中有没有用户自己配置的(@Bean@Component)如果有就用用户配置的;如果没有,才自动配置;如果有些组件可以有多个(如ViewResolver)就会将用户配置的和自己默认的组合起来;
  • 扩展配置:在SpringBoot中会有非常多的xxxConfigurer帮助我们进行扩展配置。
  • 定制配置:在SpringBoot中会有很多的xxxCustomizer帮助我们进行定制配置。

3.3 扩展SpringMVC

实际开发过程中,仅靠SpringBoot的这些自动配置是不够用的。假设现在需要扩展下面两个功能。

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

编写一个继承了WebMvcConfigurationSupport的配置类(@Configuration),不要标注@EnableWebMvc注解。既保留了所有的自动配置,也能用我们扩展的配置。

@Configuration
public class MyMvcConfig extends WebMvcConfigurationSupport {
    @Override
    protected void addViewControllers(ViewControllerRegistry registry) {
        //功能:浏览器发送 /hello请求,也来到 success
        registry.addViewController("/hello").setViewName("success");
    }
}

扩展原理

  • WebMvcAutoConfiguration是SpringMVC的自动配置类
  • ②在做其他自动配置时会导入@Import(EnableWebMvcConfiguration.class)
    即容器中所有的WebMvcConfigurer会一起起作用。
源码:
public class WebMvcAutoConfiguration {
	...
	@Configuration(proxyBeanMethods = false)
	public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {....}
	...
}
EnableWebMvcConfiguration 继承了父类DelegatingWebMvcConfiguration
------------------------------------------------------------------------------------------
@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
	...
	private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();
	//从容器中获取所有的WebMvcConfigurer,添加到configurers中
	@Autowired(required = false)
	public void setConfigurers(List<WebMvcConfigurer> configurers) {
		if (!CollectionUtils.isEmpty(configurers)) {
			this.configurers.addWebMvcConfigurers(configurers);
					//一个参考实现;将所有的WebMvcConfigurer相关的配合都调用一次,
					//@Override
					//public void addViewControllers(ViewControllerRegistry registry) {
					// for (WebMvcConfigurer delegate : this.delegates) {
					// delegate.addViewControllers(registry);
					// }
					//}
		}
	}
	...
}
  • ③扩展配置类也会被调用。

效果:SpringMVC的自动配置和我们的扩展配置都会起作用

3.4 全面接管SpringMVC

只需要在配置类中添加@EnableWebMvc,就可以全面接管SpringMVC。使所有的SpringMVC的自动配置都失效,所有都是我们自己配置。

为什么使用了@EnableWebMvc后,自动配置就失效了?

源码:
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}
-------------------------------------------------------------------
@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
	...
}

WebMvcAutoConfiguration类上有一个@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)注解,该注解作用是:当容器中没有WebMvcConfigurationSupport组件的时候,自动配置才生效。

@EnableWebMvc注解导入了DelegatingWebMvcConfiguration组件,而DelegatingWebMvcConfiguration组件继承了WebMvcConfigurationSupport

导入的WebMvcConfigurationSupport只是SpringMVC最基本的功能。

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
更多>相关资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服