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
微服务架构
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会将所有的场景,都变成一个个启动器 用什么功能就加入什么启动器
主程序:
注解 :
@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: 自动配置核心文件
ProPorperties properties = PropertiesLoaderUtils.loadProperties(resource);
//所有资源加载到这个配置类中
SpringBoot所有的自动配置都是在启动的时候扫描并加载:spring.factories
所有的自动配置类都在这里,但不一定生效,要判断条件是否成立,只要导入了对应的start,就有了对应的启动器了,有了启动器,我们自动装配就会生效,然后就配置成功!
- SpirngBoot在启动发的时候,从类路径下/MATA-INF/
Spring.factorise
获取指定的值; - 将这些自动配置的类导入容器,自动配置类就会生效,帮我们进行自动配置
- 以前我们需要自动配置的东西,现在Spring帮我们做了
- 整合了javaEE,解决方案和自动配置的东西Spirng-boot-autoconfigure-2-2.0.RELEASE.jar这个包下
- 他会把所有需要导入的组件,以类名的方式返回,这些组件就会被添加到容器;
- 容器中也会存在非常多的XXXAutoconfigure的文件(@Bean),就是这些类给容器导入了这个场景需要的 所有的组件,并自动配置,@Configuration,@javaConfig
- 有了配置了免去了我们手动编写配置的工作
自动配置包
结论: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方法的执行;
这个类主要做一下四件事情:
- 推断应用的类型是普通的项目还是Web项目
- 查找并加载所有可用的初始化器,设置到initializers属性中
- 找出所有的应用程序监听器,设置到listeners属性中
- 推断并设置mian方法的定义类,找到运行的主类
init方法加载初始化
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
JSR303数据校验
- cp只需要写一次即可,value则需要每个字段都添加
- 松散绑定:比如写yml中写的last-name 和lastName是一样的, -后面跟着字母默认是大写的,这就是松散绑定
- JSP303数据校验,这个就是我们可以在一个字段天剑一层过滤器验证,可以保证数据的合法性
- 复杂类型封装,yml中可以封装对象,使用@value就不支持
@Validated //数据校验
格式不对 名字不是邮箱
@Email(message=“邮箱格式错误”)消息提示
校验信息 @Validated
@Validated
@Validated 的 constants源码配置
环境配置和配置文件位置
配置覆盖和选择
优先级:(文件目录下)file:./config/ > file:./ > classpath:/config/ > classpath:/
多种环境用来测试或者开发项目
spring.profile.active
spirngboot 多环境配置可以选择激活那个(端口)配置文件
yaml优势 可以在里面写多个环境配置 并可以在port下一行取一个名字区分profiles:dev /test
配置文件原理在理解
@Configuration(表示一个配置类) 包括了所有的有关的带有Configuration的类
根据不同的条件来判断当前配置或者类是否生效 通过@Configuration来加载配置这些类 这个注解非常核心 类之间的配置通过他来配置
我们在这写配置文件中能配置的东西,都存在一个固有的规律 大量的xxxAutoConfiguration 装配 了 xxxPropreies xxxProperies又跟配置文件绑定,就可以使用自定义的配置
(yaml 和其他的类的自定)
如何自定义配置 就是相当于传入对应的参数一样 自定义的参数进行匹配他的类型
按照对应的规则,在配置文件中去配 能跟他匹配上的 对应的值 进行绑定
自动配置类的原理(精髓)
1.SpirngBoot启动会加载大量的自动配置类,我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中;
2.我们再来看这个自动配置类中到底配置了哪些组件(相当于方法)只要我们要用的组件存在在其中,我们就不需要手动配置了
3.给容器中的自动配置类添加组件的时候,会从Properties类中获取某一些属性,我们只需要在配置文件中指定这些属性就可以了
xxxAutoConfiguration :自动配置类;给容器中添加小组件 组件要赋值就要绑定下边的这个类,然后下边的这个类封装了一些默认配置的一些属性
xxxProperties :封装配置文件中相关的属性
debug的调试类 代码debug :true 来测试
生效类 就是定义了使用到了的配置类
测试配置类是否生效 测试你的项目中生效的配置类就是你用到的配置类 ,没有用到的就没有生效 例如 下面的图片是没有生效的配置类 某一个还有很多很多的
还有没有条件生效的类
配置文件到底能写什么 —–联系——- 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存在指定项 |
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,模板引擎有非常多,但是基本思想都一样
模板引擎的作用就是我们来写一个页面模板,比如有一些值,是动态的,我们写一些表达式,这些值从哪里来呢,我们来组装一些数据,我们把这些数据找到,然后吧这个模板和这个数据交给我们模板引擎,模板引擎按照我们这个数据帮你把这些表达式解析、填充到我们指定的位置。然后把这些数据最终生成一个我们想要的内容给我们写出去,这就是我们这个模板引擎,不管是jsp还是其他模板引擎,都是这个思想,只不过不同模板引擎之间表达的语法存在一点差异,有点语法不一样
第一步
- Thymeleaf官网:https//www.thymeleaf.org/
- Thymeleaf在Github的主页:https://github.com/thymeleaf/thymeleaf
- 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语法
<!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基本语法
SpringMVC配置原理
修改SpringBoot的默认配置
方式一:这么多的自动配置,原理都是一样的,通过这个WebMVC的自动配置原理分析,我们要学会一种方式,通过源码探究,得出结论,这个结论一定就是属于自己的,而且一通百通。
SpringBoot的底层,大量用到了这些细节设计思想,所以,没事多读读源码,得出结论。SpringBoot在自动配置很多组件的时候,先看容器中有没有自己配置的(如果用户自己配置了@bean),如果有就用用户配置的,如果没有就用自动配置的;如果有些组件可以存在多个,比如我们的视图解析器,就将用户配置的和自己默认的组合起来
为什么自定义的注入到spring容器中不能用@EanbleWebMvc
:
这个组件就是一个导入类:DelegatingWebMvcConfiguration: 从容器中获取所有的webmvcCofing
在SpringBoot中 有非常多的xxxx Configuration 帮助我们进行扩展配置,只要看见了这个东西,我们就要注意了**
页面国际化
这个WebMVC的自动配置原理分析,我们要学会一种方式,通过源码探究,得出结论,这个结论一定就是属于自己的,而且一通百通。
SpringBoot的底层,大量用到了这些细节设计思想,所以,没事多读读源码,得出结论。SpringBoot在自动配置很多组件的时候,先看容器中有没有自己配置的(如果用户自己配置了@bean),如果有就用用户配置的,如果没有就用自动配置的;如果有些组件可以存在多个,比如我们的视图解析器,就将用户配置的和自己默认的组合起来
为什么自定义的注入到spring容器中不能用@EanbleWebMvc
:
这个组件就是一个导入类:DelegatingWebMvcConfiguration: 从容器中获取所有的webmvcCofing
在SpringBoot中 有非常多的xxxx Configuration 帮助我们进行扩展配置,只要看见了这个东西,我们就要注意了**