SpirngBopt快速入门(容器)

什么是约定大于配置

在springboot中,只要导入了web-stater,spring mvc、json、spring核心容器等web场景需要的所有依赖都会导入,并控制好版本
spring boot的理念就是约定大于配置,在spring boot中提供了一套默认配置,不需要手动去写xml配置文件,只有默认配置不能满足我们的需求时,才会去修改配置。

Spirng是一个框架开源 2003年兴起的一个轻量级的java开发框架 作者Rod Johnson
Spring是为了解决企业级应用开发的复杂性而创建的,简化开发

Spring是如何简化java开发的

为了降低java开发复杂性,Spring采用了一下四种关键策略:
1.基于POJO的轻量级和最小侵入性编程;2.通过IOC,依赖注入(DI)和面向接口的实现松耦合; 基于切面(AOP)和惯例声明式编程;4.通过切面和模板减少样式代码

什么是SpirngBoot

就是一个javaweb的开发框架,和SpringMVC类似,对比其他的javaweb框架的好处,官方说简化开发,约定大于配置,对于其他框架的开发好处,就是简化开发,约定大于配置,开发接口简单,maven整合jar包,他整合所有框架,

​ SpringBoot本身不提供Spring框架的核心特性以及扩展功能,只是用于快速、敏捷的开发新一代基于Spring框架的应用程序,也就是说他并不是用来代替Spring的解决方案,而是和Spring框架紧密结合用于提升Spring开发者的体验工具。

数据库:Redis、MongDB、Jpa、RabbitMQ、Quratz

微服务架构

image-20201219201949786

1.单体应用架构(all in one )将应用服务封装在一个在一个应用中,
数据库访问,web访问等等各个功能放到一个war包内

一个大型系统的微服务架构,就像一个复杂交织的神经网络,每个神经元素就是一个功能 ,他们各自完成等自己的功能,只需要更新升级其中一个功能服务单元即可

优点:易于开发测试,部署方便,当需要部署时,只需要复制war包放到多个服务器上,负载就可以

缺点:修改摸个地方的时候需要停掉整个服务,重新打包、部署应用war包维护难

2.微服务架构:把功能单元放在一个应用里面,然后部署到服务器上,

优点:把每个功能独立出来,独立出来动态组合,整合多个功能元素,对功能赋值,没有对整个应用复制 高内聚低耦合

MVC MVVM 微服务架构 ==> 模块

controller ==>提供接口

原理初探

自动配置:

  • pom.xml
spring-boot-dependencies  <!--核心依赖在父工程中-->
  • 我们在写或者引入一些SpringBoot一来的时候,不需要指定版本,就因为有这些版本仓库

启动器

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

启动器:就是springboot的启动场景

比如spring-boot-starter-web 他就会自动导入web环境所有的依赖
springboot会将所有的场景,都变成一个个启动器 用什么功能就加入什么启动器

主程序:

image-20210123131021529

注解 :

@SpringBootConfiguration自动配置  
	@Configuration: spring 配置
	@Component: 说明这也是一个spring组件

@EnableAutoConfiguration 自动导入配置 重要
	@AutoConfigurationPackage :自动配置包
		@Import(AutoConfigurationPackage.Registrar.class): 自动配置`包注册`
	@Import(AutoConfigurationImportSelector.class):自动配置导入选择


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

获取候选的配置

Protected List<String> getCandateConfigurations(AnnotationMetadata metadata,AnnotationAttributes attributes){
	List<String> configurations = SpringFactoriesLoader.loadFatoryNames(getSpringFatoriesLoaderFatoryClass(),getBeanCalssLoader());
	Assert.notEmpty(configurations,"No auto configuration classes found in META-INF/spring.factoryies.If you " + "are using a custom packaging, make sure that file is correct.");
	return comfigurations;
} 

META-INF/spirng.factories: 自动配置核心文件

image-20210123133647180

ProPorperties properties = PropertiesLoaderUtils.loadProperties(resource);
//所有资源加载到这个配置类中

SpringBoot所有的自动配置都是在启动的时候扫描并加载:spring.factories所有的自动配置类都在这里,但不一定生效,要判断条件是否成立,只要导入了对应的start,就有了对应的启动器了,有了启动器,我们自动装配就会生效,然后就配置成功!

  1. SpirngBoot在启动发的时候,从类路径下/MATA-INF/Spring.factorise获取指定的值;
  2. 将这些自动配置的类导入容器,自动配置类就会生效,帮我们进行自动配置
  3. 以前我们需要自动配置的东西,现在Spring帮我们做了
  4. 整合了javaEE,解决方案和自动配置的东西Spirng-boot-autoconfigure-2-2.0.RELEASE.jar这个包下
  5. 他会把所有需要导入的组件,以类名的方式返回,这些组件就会被添加到容器;
  6. 容器中也会存在非常多的XXXAutoconfigure的文件(@Bean),就是这些类给容器导入了这个场景需要的 所有的组件,并自动配置,@Configuration,@javaConfig
  7. 有了配置了免去了我们手动编写配置的工作

自动配置包

结论:springboot所有的自动配置都是在启动的时候扫描并加载spring.factories 所有的自动配置类都在这里 不一定生效 要判断条件是否成立,只要导入了对应的start,就有对应的启动器,有了启动器,自动装配就会生效,才会配置成功

1.spirngboot 在启动的时候,在类路径下/META-INF/spring.fatories获取指定的值

2.将这些自动配置的类导入到容器,自动配置就会生效,为我们进行自动配置

3.整合javaEE,解决方案和自动配置的东西都在springboot-autoconfigure.jar包下

4.他会把所有需要导入的组件,以类名的方式返回,这些组件旧就被添加到容器

6.容器中也会攒在非常多的xxxAutoconfiguration的文件(@bean),就是这些类容器中导入了这个场景需要的所有组件,并自动配置,@Configration javaConfig!

主程序类

SpringApplication.run分析

分析该方法主要分两部分:一部分是SpringApplication的实例化。二是run方法的执行;

这个类主要做一下四件事情:

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

init方法加载初始化


image-20210126184855722
image-20210126185137257

yaml配置文件

格式配置 是标记语言也不是标记语言 ,以数据为中心的语言 比较绕

yaml 可以存一个对象

student:
 name: mojiejun  #必须注意格式  空格
 age: 3
 #行内写法
 student: {name: mojiejun,age:3}
 #数组
 pets:
  - cat
  - dog
  - pig
  #数组或者
  pets: [cat,dog,pig]

(key ,value)

yaml 可以直接给实体类赋值

@Configuration(prefix=“Person”)注入相应的属性 配置类的值可以通过配置文件绑定

@ConfigurationProperties作用:自动配置识别(yaml不适用) 需要设置编码

降配置文件中的配置的每一个属性的值,映射到这个组件中;告诉springboot将本类中的所有属性和配置文件中的值进行一一绑定

也可以将在指定的配置文件 需要@value(“${name}”)yaml的高级设置

@ConfigurationProperities(松散绑定)比较yaml

image-20201221234849957

JSR303数据校验

  • cp只需要写一次即可,value则需要每个字段都添加
  • 松散绑定:比如写yml中写的last-name 和lastName是一样的, -后面跟着字母默认是大写的,这就是松散绑定
  • JSP303数据校验,这个就是我们可以在一个字段天剑一层过滤器验证,可以保证数据的合法性
  • 复杂类型封装,yml中可以封装对象,使用@value就不支持

@Validated //数据校验

image-20201221235539588

格式不对 名字不是邮箱

@Email(message=“邮箱格式错误”)消息提示

校验信息 @Validatedimage-20201221235739139

@Validated

image-20201221235847529

@Validated 的 constants源码配置

image-20201222000237518

环境配置和配置文件位置

配置覆盖和选择

优先级:(文件目录下)file:./config/ > file:./ > classpath:/config/ > classpath:/

多种环境用来测试或者开发项目

image-20201222001243678

spring.profile.active spirngboot 多环境配置可以选择激活那个(端口)配置文件

yaml优势 可以在里面写多个环境配置 并可以在port下一行取一个名字区分profiles:dev /testimage-20201222001644390

配置文件原理在理解

@Configuration(表示一个配置类) 包括了所有的有关的带有Configuration的类

根据不同的条件来判断当前配置或者类是否生效 通过@Configuration来加载配置这些类 这个注解非常核心 类之间的配置通过他来配置

我们在这写配置文件中能配置的东西,都存在一个固有的规律 大量的xxxAutoConfiguration 装配 了 xxxPropreies xxxProperies又跟配置文件绑定,就可以使用自定义的配置

(yaml 和其他的类的自定)

如何自定义配置 就是相当于传入对应的参数一样 自定义的参数进行匹配他的类型

按照对应的规则,在配置文件中去配 能跟他匹配上的 对应的值 进行绑定

自动配置类的原理(精髓)

1.SpirngBoot启动会加载大量的自动配置类,我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中;

2.我们再来看这个自动配置类中到底配置了哪些组件(相当于方法)只要我们要用的组件存在在其中,我们就不需要手动配置了

3.给容器中的自动配置类添加组件的时候,会从Properties类中获取某一些属性,我们只需要在配置文件中指定这些属性就可以了

xxxAutoConfiguration :自动配置类;给容器中添加小组件 组件要赋值就要绑定下边的这个类,然后下边的这个类封装了一些默认配置的一些属性

xxxProperties :封装配置文件中相关的属性

debug的调试类 代码debug :true 来测试

生效类 就是定义了使用到了的配置类image-20201222011040207

测试配置类是否生效 测试你的项目中生效的配置类就是你用到的配置类 ,没有用到的就没有生效 例如 下面的图片是没有生效的配置类 某一个还有很多很多的image-20201222010654830

还有没有条件生效的类image-20201222010854339

配置文件到底能写什么 —–联系——- Spring.factories

@Conditional

了解完自动装配以后,我们来关注一些细节问题,自动配置类必须在一定条件下才能生效 ;@Conditional派生注解(Spring注解版原生的@Conditional作用)

作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配在里面的所有内容才会生效

@Conditional扩展注解 作用:判断是否满足当前指定条件
@ConditionalOnjava 系统java版本是否符合要求
@ConditionalOnBean 容器存在指定Bean
@ConditionalOnMissingBean 容器中不存在指定Bean
@ConditionalOnExpression 满足SpEL表达式指定
@ConditionalOnClass 系统中有指定的类
@ConditionalOnMissClass 系统中没有指定的类
@ConditionalOnSingleCandidate 容器中只有一个指定的Bean,或者这个Bean是首选Bean
@ConditionalOnProperty 系统中指定的属性是否存在指定的值
@ConditionalOnResource 类路径下是否存在制定资源文件
@ConditionalOnWebAppcation 当前web环境
@ConditionalOnNotWebApplication 不是Web环境
@ConditionalOnJndi JNDI存在指定项

image-20210127030732464

SpringBoot Web开发应用

静态资源

protected void addResourceHandlers(ResourceHandlerRegistry registry) {
			super.addResourceHandlers(registry);
			if (!this.resourceProperties.isAddMappings()) {
				logger.debug("Default resource handling disabled");
				return;
			}
			ServletContext servletContext = getServletContext();
			addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
			addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
				registration.addResourceLocations(this.resourceProperties.getStaticLocations());
				if (servletContext != null) {
					registration.addResourceLocations(new ServletContextResource(servletContext, SERVLET_LOCATION));
				}
			});
		}

		private void addResourceHandler(ResourceHandlerRegistry registry, String pattern, String... locations) {
			addResourceHandler(registry, pattern, (registration) -> registration.addResourceLocations(locations));
		}

		private void addResourceHandler(ResourceHandlerRegistry registry, String pattern,
				Consumer<ResourceHandlerRegistration> customizer) {
			if (registry.hasMappingForPattern(pattern)) {
				return;
			}
			ResourceHandlerRegistration registration = registry.addResourceHandler(pattern);
			customizer.accept(registration);
			registration.setCachePeriod(getSeconds(this.resourceProperties.getCache().getPeriod()));
			registration.setCacheControl(this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl());
			customizeResourceHandlerRegistration(registration);
		}

总结:

在springboot中,我们可以使用以下处理静态资源

  • webjars localhost:8080/webjars/
  • public ,static ,/** , resources , localhost;8080/

优先级:resources > static (默认使用) >public > /**

Thyeleaf模板引擎

概述:

前端交给我们的页面,是html页面,如果使我们以前的开发,我们需要把他们装化成jsp页面,jsp的好处就是当我们查出一些数据转发到jsp也页面的以后,我们就可以用jsp页面轻松实现数据的显示,以及交互等,jsp支持非常强大的功能,包括能写java代码,但是呢,我们现在的这种情况,SpringBoot这个羡慕首先是jar的方式,不是war,像第二,我们用的还是嵌入式的Tomcat,所以呢,太现在默认的是不支持jsp的,那不支持jsp,如果我们直接用纯静态页面的方式,那我们开发会带来很大的麻烦,那么怎么办呢,SpringBoot推荐你可以使用模板引擎

那么模板引擎,其实jsp就是一个模板引擎,还有已用的比较多的freemarker,包括SpringBoot给我们推荐的Thymeleaf,模板引擎有非常多,但是基本思想都一样

image-20210127152326288

模板引擎的作用就是我们来写一个页面模板,比如有一些值,是动态的,我们写一些表达式,这些值从哪里来呢,我们来组装一些数据,我们把这些数据找到,然后吧这个模板和这个数据交给我们模板引擎,模板引擎按照我们这个数据帮你把这些表达式解析、填充到我们指定的位置。然后把这些数据最终生成一个我们想要的内容给我们写出去,这就是我们这个模板引擎,不管是jsp还是其他模板引擎,都是这个思想,只不过不同模板引擎之间表达的语法存在一点差异,有点语法不一样

第一步

  1. Thymeleaf官网:https//www.thymeleaf.org/
  2. Thymeleaf在Github的主页:https://github.com/thymeleaf/thymeleaf
  3. Spring官方文档:“https://docs.spring.io/spirng-boot/docs/2.1.6.RELEASE/reference/htmlsingle/#using-boot-strarter”找到对应版本

结论:只要需要使用thymeleaf,只需要导入对应的依赖就可以了,导入之后我们将html放在我们的templates目录下即可 根据源码要求放

public static final String DEFAULT_PREFIX = "classpath:/templates/";
	public static final String DEFAULT_SUFFIX = ".html";

Thymeleaf语法

image-20210128231114563

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--所有的html元素都可以被thymeleaf替换接管   th;元素名-->
    <div th:text="${msg}"></div>
    <div th:utext="${msg}"></div>
    <hr>
<h3 th:each="user:${users}" >[[${user}]]</h3>
<!--<h3 th:each="user:${users}" th:text="${user}"></h3>-->
</body>
</html>
@Controller
public class IndexController {
    @RequestMapping("/test")
    public String Test(Model model){
        model.addAttribute("msg","<h1>hello,springboot</h1>");
        model.addAttribute("users", Arrays.asList("qingjaing","kuangshen"));
            return "test";
    }
}

Thymeleaf基本语法

image-20210402142331789

SpringMVC配置原理

image-20210128024956837

修改SpringBoot的默认配置

方式一:这么多的自动配置,原理都是一样的,通过这个WebMVC的自动配置原理分析,我们要学会一种方式,通过源码探究,得出结论,这个结论一定就是属于自己的,而且一通百通。

SpringBoot的底层,大量用到了这些细节设计思想,所以,没事多读读源码,得出结论。SpringBoot在自动配置很多组件的时候,先看容器中有没有自己配置的(如果用户自己配置了@bean),如果有就用用户配置的,如果没有就用自动配置的;如果有些组件可以存在多个,比如我们的视图解析器,就将用户配置的和自己默认的组合起来

为什么自定义的注入到spring容器中不能用@EanbleWebMvc

​ 这个组件就是一个导入类:DelegatingWebMvcConfiguration: 从容器中获取所有的webmvcCofing

在SpringBoot中 有非常多的xxxx Configuration 帮助我们进行扩展配置,只要看见了这个东西,我们就要注意了**

页面国际化

这个WebMVC的自动配置原理分析,我们要学会一种方式,通过源码探究,得出结论,这个结论一定就是属于自己的,而且一通百通。

SpringBoot的底层,大量用到了这些细节设计思想,所以,没事多读读源码,得出结论。SpringBoot在自动配置很多组件的时候,先看容器中有没有自己配置的(如果用户自己配置了@bean),如果有就用用户配置的,如果没有就用自动配置的;如果有些组件可以存在多个,比如我们的视图解析器,就将用户配置的和自己默认的组合起来

为什么自定义的注入到spring容器中不能用@EanbleWebMvc

​ 这个组件就是一个导入类:DelegatingWebMvcConfiguration: 从容器中获取所有的webmvcCofing

在SpringBoot中 有非常多的xxxx Configuration 帮助我们进行扩展配置,只要看见了这个东西,我们就要注意了**

页面国际化

image-20210128231202254


版权声明:本文为lyyibaobao原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/lyyibaobao/article/details/118052821