SpringBoot
一、SpringBoot介绍
1.1 引入
Spring是为了解决企业级应用开发的复杂性而创建的,简化开发。
- 基于POJO的轻量级和最小侵入性编程,所有东西都是bean
- 通过IOC,依赖注入(DI)和面向接口实现松耦合
- 基于切面(AOP)和惯例进行声明式编程
- 通过切面和模版减少样式代码,RedisTemplate,xxxTemplate
But!,随着 Spring 不断的发展,涉及的领域越来越多,项目整合开发需要配合各种各样的文件,慢慢变得不那么易用简单,违背了最初的理念,人称配置地狱。
Spring Boot 正是在这样的一个背景下被抽象出来的开发框架,目的为了让大家更容易的使用 Spring 、更容易的集成各种常用的中间件、开源软件;
Spring Boot 基于 Spring 开发,Spirng Boot 本身并不提供 Spring 框架的核心特性以及扩展功能,只是用于快速、敏捷地开发新一代基于 Spring 框架的应用程序。
SpringBoot并不是用来替代 Spring 的解决方案,而是和 Spring 框架紧密结合用于提升 Spring 开发者体验的工具。
1.2 简介
Spring Boot 来简化Spring应用开发,约定大于配置,去繁从简,just run 就能创建一个独立的,产品级别的应用
背景
J2EE笨重的开发,繁多的配置,底下的开发效率、复杂的部署流程、第三方技术集成难度大。
解决
-
Spring全家桶时代
-
Spring Boot -> J2EE一站式解决方案
-
Spring Cloud -> 分布式整体解决方案
1.3 优点
- 快速创建独立运行的Spring项目以及与主流框架集成
- 使用嵌入式的Servlet容器,应用无需打成War包
- starters自动依赖与版本控制
- 大量的自动配置,简化开发,可以修改默认值
- 无需配置XML,无代码生成,开箱即用
- 准生产环境的运行时应用监控
- 与云计算的天然集成
1.4 微服务
微服务是一种风格、要求我们在开发一个应用时,这个应用必须构建成一系列小服务的组合,可以通过http的方式进行互通
单体应用架构
指我们将一个应用中的所有应用服务器都封装在一个应用中。
无论ERP、CRM、或其他系统,都把数据库访问、web访问,等等各个功能放到一个war包内。
- 好处是,易于开发和测试:也十分方便部署;当需要扩展时,只需要将war复制多份,然后放到多个服务器上,再做个负载均衡即可。
- 缺点是,修改一个小地方,都需要停掉整个服务,重新打包、部署这个应用war包。
微服务架构
all in one的架构方式,我们把所有的功能单元放在一个应用里面。然后我们把整个应用部署到服务器上。如果负载能力不行,我们将整个应用进行水平复制,进行扩展,然后在负载均衡。
所谓微服务架构,就是打破之前all in one的架构方式,把每个功能元素独立出来。把独立出来的功能元素的动态组合,需要的功能元素才去拿来组合,需要多一些时可以整合多个功能元素。所以微服务架构是对功能元素进行复制,而没有对整个应用进行复制。
这样做的好处是:
- 节省了调用资源。
- 每个功能元素的服务都是一个可替换的、可独立升级的软件代码。
构建微服务
一个大型系统的微服务架构,就像一个复杂交织的神经网络,每一个神经元就是一个功能元素,它们各自完成自己的功能,然后通过http相互请求调用。比如一个电商系统,查缓存、连数据库、浏览页面、结账、支付等服务都是一个个独立的功能服务,都被微化了,它们作为一个个微服务共同构建了一个庞大的系统。如果修改其中的一个功能,只需要更新升级其中一个功能服务单元即可。
但是这种庞大的系统架构给部署和运维带来很大的难度。于是,spring为我们带来了构建大型分布式微服务的全套、全程产品:
- 构建一个个功能独立的微服务应用单元,可以使用springboot,可以帮我们快速构建一个应用;
- 大型分布式网络服务的调用,这部分由spring cloud来完成,实现分布式;
- 在分布式中间,进行流式数据计算、批处理,我们有spring cloud data flow。
- spring为我们想清楚了整个从开始构建应用到大型分布式应用全流程方案。
二、Hello,SpringBoot
功能:浏览器发送Hello请求,服务器接收请求并处理,响应HelloWorld字符串
@Controller
public class HelloController {
@ResponseBody
@RequestMapping("/hello")
public String hello() {
return "Hello,World";
}
}
简化部署(打包)
java -jar hellospringboot-0.0.1-SNAPSHOT.jar
2.1 Hello,Spring探究
父项目
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!-- 真正管理SpringBoot应用里面所有依赖版本的地方,SpringBoot的版本控制中心-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
它来真正的管理Spring boot应用里面所有依赖版本!
以后导入依赖不需要写版本;但是如果导入的包没有在依赖中管理着就需要手动配置版本了;
导入的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
2.2 原理探究
1. 启动器 spring-boot-starter
spring-boot-starter-web
spring-boot-starter:springboot场景启动器,帮助我们导入web模块正常运行所依赖的组件
Springboot将所有的功能场景都抽取出来,做成一个一个的starter(启动器),只需要在项目中引入starter相关场景的依赖都会导入进来。要用什么功能就导入什么场景启动器。
2. 主程序类
@SpringBootApplication
public class HellospringbootApplication {
public static void main(String[] args) {
SpringApplication.run(HellospringbootApplication.class, args);
}
}
**@SpringBootApplication:**Springboot应用标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot就应该运行这个类的main方法来启动SpringBoot应用
SpringApplication.run分析:一部分是SpringApplication的实例化,二是run方法的执行
主程序类完成了四件事情:
- 推断应用的类型是普通的项目还是Web项目
- 查找并加载所有可用初始化器 , 设置到initializers属性中
- 找出所有的应用程序监听器,设置到listeners属性中
- 推断并设置main方法的定义类,找到运行的主类
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
@ComponentScan:对应XML配置中的元素
@SpringBootConfiguration:Springboot的配置类,标注在某个类上,表示这是一个SpringBoot配置类
@Configuration:配置类上标注这个注解,对应Spring中的xml文件
**@Component:**启动类本身也是Spring中的一个组件而已,负责启动应用!
@EnableAutoConfiguration:开启自动配置功能
以前需要配置的东西,Springboot帮我们配置;@EnableAutoConfiguration告诉Springboot开启自动配置功能,这样自动配置才能生效。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
@AutoConfigurationPackage:自动配置包
@Import(AutoConfigurationPackages.Registrar.class):Spring的底层注解@Import,给容 器中导入一个组件;导入的组件由AutoConfigurationPackages.Registrar.class
将主配置类(@SpringBootConfiguration标注的类)的所在包及下面所有子包里面的所有 组件扫描到Spring容器。
@Import(AutoConfigurationImportSelector.class):给容器中导入组件,导入哪些组件的选 择器
将所有需要导入的组件以全类名的方式返回;这些组件就会被添加到容器中。
会给容器中导入非常多的自动配置类(xxxAutoConfiguration);给容器中导入这个场景的所 有组件,并配置好这些组件
有了自动配置类,免去了我们收到编写配置注入功能组件等工作
SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class, classLoader)
Spring Boot 在启动的时候从类路径下的META-INF/spring.factories中获取 EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中,
自动配置类就生效,帮我们进行自动配置工作
J2EE的整体整合解决方案和自动配置都在spring-boot-autoconfigure-2.2.5.RELEASE.jar下
3.总结
- SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值
- 将这些值作为自动配置类导入容器 , 自动配置类就生效 , 帮我们进行自动配置工作
- 它会给容器中导入非常多的自动配置类 (xxxAutoConfiguration), 就是给容器中导入这个场景需要的所有组件 , 并配置好这些组件
2.3 使用Spring Initializer快速创建Spring Boot项目
选择我们需要的模块,会自动联网创建Spring Boot 项目
默认生成的Spring Boot项目:
- 主程序自动生成
- resources文件中的目录结构
- static:保存所有的静态资源:css,image
- templates:保存所有的模板页面(SpringBoot嵌入Tomcat,默认不支持jsp,可以使用模板引擎)
- application.properties:springboot应用的配置文件;可以修改一些默认设置
2.4 彩蛋
到项目下的 resources 目录下新建一个banner.txt 即可。