SpringBoot 学习笔记

SpringBoot 学习笔记


文章目录

  • SpringBoot 学习笔记
    • 原理分析
    • 启动器
    • 主程序
    • 注解
    • SpringApplication作用
    • SpringBoot 配置
    • JSR303校验
    • SpringBoot 配置
    • SpringBoot Web开发
      • 资源处理器源码
      • 首页相关源码
      • 模板引擎介绍
      • Thymeleaf 相关语法
        • 命名空间
        • 变量表达式
        • 超链接
        • 循环遍历数组
        • 组件语法
      • 扩展装配SpringMVC
      • 首页跳转
      • 国际化
        • 相关源码
        • 自定义区域化解析
        • 页面效果
      • 其他
      • 其他

原理分析

pom.xml配置文件下

<parent>
		<groupId>org.springframework.bootgroupId>
		<artifactId>spring-boot-starter-parentartifactId>
		<version>2.4.5version>
		<relativePath/> 
parent>

进入spring-boot-started-parent之后,spring-boot-dependencies 核心依赖在父工程中.

<parent>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-dependenciesartifactId>
    <version>2.4.5version>
parent>

在写或者引入一些SpringBoot依赖的时候,不需要指定版本,核心依赖中有版本仓库

启动器

<dependency>
	<groupId>org.springframework.bootgroupId>
	<artifactId>spring-boot-starter-webartifactId>
dependency>

SpringBoot 的 启动场景

SpringBoot 会将所有的功能场景变成一个个启动器,需要什么功能,只需找到对应的启动器即可。

主程序

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication //标注这个类是一个SpringBoot的应用  不可缺少
public class DemoApplication 
{
	public static void main(String[] args) 
	{
		SpringApplication.run(DemoApplication.class, args);
	}
}

注解

@SpringBootConfiguration   //SpringBoot配置
	@Configuration         //Spring配置类
	@Conponent			  // 说明是Spring的一个组件
@EnableAutoConfiguration   //自动装配
	@AutoConfigurationPackage   //自动配置包
		@Import(AutoConfigurationPackages.Register.class)   //自动配置  包注册
	@Import(AutoConfigurationImportSelector.class)  //自动配置  导入选择

//获取所有配置
List<String> configurations = getCandidateConfigurations(annotationMetadata,attributes);

// SpringBoot所有的自动配置都在启动的时候被扫描并加载
// 扫描 META-INF/spring.factotories (自动配置的核心文件)
// 所有的配置类都在spring.factories中,但是不一定生效,需要判断条件是否成立
// 只有加入了对应的start,有了对应的启动器,自动装配才能生效

SpringApplication作用


  1. 推断应用类型是普通项目还是Web项目
  2. 查找并加载所有可用初始化器,设置到 initializers 属性中
  3. 找出所有的应用程序监听器,设置到 listeners 属性中
  4. 推断并设置main方法的定义类,找到运行的主类

SpringBoot 配置


SpringBoot采用yaml配置文件来代替xml文件

  1. 通过 yaml 配置文件来给实体类赋值( 推荐 )

SpringBoot 学习笔记_第1张图片
通过 @ConfigurationProperties注解 来实现配置文件映射赋值

  1. 通过 properties 配置文件来赋值
    SpringBoot 学习笔记_第2张图片

通过 @PropertySource注解 来绑定配置文件,并通过@Value注解 来给属性赋值

JSR303校验


给字段增加一层过滤器验证,保证字段合法性。

SpringBoot 学习笔记_第3张图片
SpringBoot 学习笔记_第4张图片

SpringBoot 配置


SpringBoot 学习笔记_第5张图片

项目 yaml 配置文件优先级

Spring底层注解:根据不同的条件,来判断当前配置或者文件是否生效
SpringBoot 学习笔记_第6张图片

XXXAutoConfiguration:默认值 XXXproperties 和 配置文件绑定 , 可以使用自定义的配置

SpringBoot Web开发


资源处理器源码

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    //如果有自动配置则退出
	if (!this.resourceProperties.isAddMappings()) {
		logger.debug("Default resource handling disabled");
		return;
	}
    //在webjars网站上通过maven依赖导入相关jar
	addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
  	//对应下方五个路径下的资源文件
	addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
	registration.addResourceLocations(this.resourceProperties.getStaticLocations());
	if (this.servletContext != null) {
		ServletContextResource resource = new ServletContextResource(this.servletContext, SERVLET_LOCATION);
		registration.addResourceLocations(resource);
	}
	});
}
//分别对应resources目录下的resources资源文件夹、public资源文件夹、static资源文件夹
//优先级为 rescoures > static > public
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
				"classpath:/resources/", "classpath:/static/", "classpath:/public/" };
private String staticPathPattern = "/**";

首页相关源码

private Resource getWelcomePage() 
{
    //通过 CLASSPATH_RESOURCE_LOCATIONS 来获取四个路径下的首页
    //注意: 如果已经在配置文件里修改过路径 则 无效
	for (String location : this.resourceProperties.getStaticLocations()) {
        //通过路径来获取相关资源
		Resource indexHtml = getIndexHtml(location);
        //如果四个路径下存在首页就返回
		if (indexHtml != null) {
			return indexHtml;
		}
	}
    //如果在springboot自带的路径下没有找到
	ServletContext servletContext = getServletContext();
	if (servletContext != null) {
        //找到自定义路径并调用下面第一个getIndexHtml方法
		return getIndexHtml(new ServletContextResource(servletContext, SERVLET_LOCATION));
	}
	return null;
}

private Resource getIndexHtml(String location) {
    //通过路径参数来获取相关资源并调用第二个getIndexHtml方法
	return getIndexHtml(this.resourceLoader.getResource(location));
}

private Resource getIndexHtml(Resource location) {
	try {
        //获取index.html页面
		Resource resource = location.createRelative("index.html");
		if (resource.exists() && (resource.getURL() != null)) {
            //资源存在并且路径不为空就返回
			return resource;
		}
	}
	catch (Exception ex) {
	}
	return null;
}

模板引擎介绍

模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档

JSP、Freemarker、Thymeleaf等都是一些常用的模板引擎

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

Github 地址 : https://github.com/thymeleaf/thymeleaf

Thymeleaf 相关依赖

<dependency>
    <groupId>org.thymeleafgroupId>
    <artifactId>thymeleaf-spring5artifactId>
dependency>
<dependency>
    <groupId>org.thymeleaf.extrasgroupId>
    <artifactId>thymeleaf-extras-java8timeartifactId>
dependency>

**Thymeleaf 配置文件 **

//默认字符编码
private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;
//默认前缀  thymeleaf默认写在templates文件夹下
public static final String DEFAULT_PREFIX = "classpath:/templates/";
//默认后缀
public static final String DEFAULT_SUFFIX = ".html";
//在templates下的所有页面只能通过 controller 跳转
//这个需要模板引擎的支持 而SpringBoot不支持JSP 所以采用Thymeleaf
@Controller
public class IndexController
{
    //通过 localhost:8080/index 来跳转到相关页面
    @RequestMapping("/index")
    public String index()
    {
        //返回的文件名会被thymeleaf进行拼接
        return "test";
    }
}

Thymeleaf 相关语法

命名空间


<html lang="en" xmlns:th="http://www.thymeleaf.org">html>

变量表达式


<div th:text="'这里是要替换的文字'+${session.title}+'......'">
        前端开发展示所用的内容
div>

超链接



<div th:href="@{/eps/**}">div>

循环遍历数组


<h3 th:each="user:${users}" th:text="${user}">h3>
<h3 th:each="user:${users}">[[ ${user} ]]h3>


<tr th:each="emp:${emps}">
	<td th:text="${emp.getId()}">td>
	<td th:text="${emp.getLastName()}">td>
	<td th:text="${emp.getEmail()}">td>
	<td th:text="${emp.getGender()==0?'':''}">td>
	<td th:text="${emp.department.getDepartName()}">td>
	<td th:text="${#dates.format(emp.getBitrh(),'yyyy-MM-dd HH:mm:ss')}">td>
tr>

组件语法


<nav class="col-md-2 d-none d-md-block bg-light sidebar" th:fragment="sidebar">nav>



<div th:insert="~{dashboard::sidebar}">div>


<div th:replace="~{dashboard::siderbar}">div>


<div th:replace="~{dashboard::siderbar(active='list')}">div>


div>

扩展装配SpringMVC

@Configuration
public class MyMvcConfig implements WebMvcConfigurer
{
    //ViewResolver 实现了视图解析器接口的类  可以看作视图解析器
    @Bean
    public ViewResolver myViewResolver()
    {
        return new MyViewResolver();
    }
    //自定义一个视图解析器 MyViewResolver
    public static class MyViewResolver implements ViewResolver
    {
        @Override
        public View resolveViewName(String s, Locale locale) throws Exception
        {
            return null;
        }
    }
}

首页跳转

// 1. 首页控制器
// 注意: 需要导入thymeleaf依赖
@Controller
public class IndexController 
{
    //通过localhost:8080/ 或者 localhost:8080/index.html 皆可访问index主页
    @RequestMapping({"/","/index.html"})
    public String index()
    {
        return "index";
    }
}
// 2. 扩展MVC
@Configuration
public class MyMvcConfig implements WebMvcConfigurer
{
    //视图跳转
    @Override
    public void addViewControllers(ViewControllerRegistry registry)
    {
        //跳转主页
        //通过localhost:8080/ 或者 localhost:8080/index.html 皆可访问index主页
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/index.html").setViewName("index");
    }
}

国际化

相关源码

//消息自动配置部分源码
@Bean
@ConfigurationProperties(prefix = "spring.messages")
public MessageSourceProperties messageSourceProperties() 
{
	return new MessageSourceProperties();
}
//本地解析源码
@Bean
@ConditionalOnMissingBean( name = {"localeResolver"} )
public LocaleResolver localeResolver() {
    //如果用户配置的有本地区域化信息 则返回用户的配置
      if (this.webProperties.getLocaleResolver() == 							           org.springframework.boot.autoconfigure.web.WebProperties.LocaleResolver.FIXED) {
                return new FixedLocaleResolver(this.webProperties.getLocale());
            } else if (this.mvcProperties.getLocaleResolver() == org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties.LocaleResolver.FIXED) {
                return new FixedLocaleResolver(this.mvcProperties.getLocale());
            } else {
                AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
                Locale locale = this.webProperties.getLocale() != null ? this.webProperties.getLocale() : this.mvcProperties.getLocale();
                localeResolver.setDefaultLocale(locale);
                return localeResolver;
            }
}
//接收头本地解析
@Override
public Locale resolveLocale(HttpServletRequest request) 
{
	Locale defaultLocale = getDefaultLocale();
    //如果接收的语言为空 则采用默认语言
	if (defaultLocale != null && request.getHeader("Accept-Language") == null) {
		return defaultLocale;
	}
    //不为空时接收进行配置并返回
	Locale requestLocale = request.getLocale();
	List<Locale> supportedLocales = getSupportedLocales();
	if (supportedLocales.isEmpty() || supportedLocales.contains(requestLocale)) {
		return requestLocale;
	}
	Locale supportedLocale = findSupportedLocale(request, supportedLocales);
	if (supportedLocale != null) {
		return supportedLocale;
	}
	return (defaultLocale != null ? defaultLocale : requestLocale);
}

自定义区域化解析

#默认  login.properties
login.password=密码
login.remember=记住密码
login.sign=登录
login.tip=请登录
login.username=用户名
#中文  login_zh_CN.properties
login.password=密码
login.remember=记住密码
login.sign=登录
login.tip=请登录
login.username=用户名
#英文  login_en_US.properties
login.password=Password
login.remember=Remember me
login.sign=Sign in
login.tip=Please sign in
login.username=Username
public class MyLocalResolver implements LocaleResolver 
{
    //解析请求
    @Override
    public Locale resolveLocale(HttpServletRequest request) 
    {
        //获取请求中的语言参数
        String language = request.getParameter("language");
        //如果参数为空采用默认格式
        Locale locale = Locale.getDefault();
        //不为空时
        if(!StringUtils.isEmpty(language))
        {
            //分解国际化参数
            // zh_CN  en_US  国家_地区
            String[] languages = language.split("_");
            locale = new Locale(languages[0],languages[1]);
        }
        return locale;
    }
}
//将自定义配置类注入Bean
@Configuration
public class MyMvcConfig implements WebMvcConfigurer
{
    //视图跳转
    @Override
    public void addViewControllers(ViewControllerRegistry registry)
    {
        //跳转主页
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/index.html").setViewName("index");
    }
    //注入Bean
    @Bean
    public LocaleResolver localeResolver()
    {
        return new MyLocalResolver();
    }
}

<a  th:href="@{/index.html(language='zh_CN')}">中文a>
<a  th:href="@{/index.html(language='en_US')}">Englisha>

页面效果

SpringBoot 学习笔记_第7张图片
SpringBoot 学习笔记_第8张图片

其他

//通过Controller跳转的页面 URL 可能会很复杂,为了方便我们可以自己配置视图跳转
@Override
public void addViewControllers(ViewControllerRegistry registry)
{
     //跳转页面
     //需要通过Controller 重定向到/main.html路径并跳转到dashboard页面
     // return "redirect:/main.html";
     //此时URL为  localhost:8080/main.html(默认配置文件中没有配上下文路径)
     registry.addViewController("/main.html").setViewName("dashboard");
}

src="…/AppData/Roaming/Typora/typora-user-images/image-20210730120324009.png" alt=“image-20210730120324009” style=“zoom:50%;” />

其他

//通过Controller跳转的页面 URL 可能会很复杂,为了方便我们可以自己配置视图跳转
@Override
public void addViewControllers(ViewControllerRegistry registry)
{
     //跳转页面
     //需要通过Controller 重定向到/main.html路径并跳转到dashboard页面
     // return "redirect:/main.html";
     //此时URL为  localhost:8080/main.html(默认配置文件中没有配上下文路径)
     registry.addViewController("/main.html").setViewName("dashboard");
}

你可能感兴趣的:(java,web,spring,boot)