胸怀万里世界, 放眼无限未来。这篇文章主要讲述#yyds干货盘点# Spring Boot的前世今生以及它和Spring Cloud的关系详解。相关的知识,希望能为你提供帮助。
要了解Spring Boot的发展背景,还得从2004年Spring Framework1.0版本发布开始说起,不过大家都是从开始学习java就使用Spring Framework了,所以就不做过多展开。
随着使用Spring Framework进行开发的企业和个人越来越多,Spring 也慢慢从一个单一简洁的小框架编程了一个大而全的开源软件,Spring Framework的边界不断进行扩张,到了现在Spring 几乎可以做任何事情。目前市面上绝大部分的开源组件和中间件,都有Spring对应组件的支持,
你们如果去关注Spring目前的官网,你会发现他的slogan是:Spring makesJava Simple。它让Java的开发变得更加简单。
虽然Spring的组件代码是轻量级的,但是它的配置却是重量级的,Spring 每集成一个开源软件,就需要增加一些基础配置,慢慢的随着我们开发的项目越来越庞大,往往需要集成很多开源软件,因此后期使用 Spirng 开发大型项目需要引入很多配置文件,太多的配置非常难以理解,并容易配置出错,这个给开发人员带来了不少的负担。
大家想象一个场景,就是假如你需要用spring开发一个简单的Hello World Web应用程序,应该要做哪些动作呢?
- 创建一个项目结构,必然包含依赖Maven或者Gradle的构建文件。
- 至少需要添加spring mvc和servlet api的依赖
- 一个web.xml,声明spring的DispatcherServlet
- 一个启用了Spring MVC的spring 配置
- 一个控制器类,“以HelloWord”为响应的http请求
- 一个用于部署应用程序的web应用服务器,比如Tomcat
所以,直到2012年10月份,一个叫Mike Youngstrom(扬斯特罗姆)在Spring Jira中创建了一个功能请求,要求在Spring Framework中支持无容器Web应用程序体系结构,他谈到了在主容器引导 spring 容器内配置 Web 容器服务。
https://jira.spring.io/browse/SPR-9888
I think that Springs web application architecture can be significantly simplified if it were to provided tools and a reference architecture that leveraged the Spring component and configuration model from top to bottom. Embedding and unifying the configuration of those common web container services within a Spring Container bootstrapped from a simple main() method.
我认为,如果要提供从上到下充分利用Spring组件和配置模型的工具和参考体系结构,则可以大大简化Spring的Web应用程序体系结构。在通过简单main()方法引导的Spring容器中嵌入和统一那些通用Web容器服务的配置。
而且Spring 开发团队也意识到了这些问题,急需要一套软件来解决这个问题,而这个时候微服务的概念也慢慢的起来,快速开发微小独立的应用也变得很急迫。
而Spring恰好处在这样一个交叉点上,所以顺势而为在2013年初的时候,开始投入Spring Boot项目的研发,直到2014年4月,Spring Boot1.0版本发布。从那以后,Spring Boot开启了一些列的迭代和升级的过程。
经过7年时间的发展,到目前为止,Spring Boot最新稳定版为2.6.0版本。
Spring Boot的发展Spring Boot刚出生的时候,引起了很多开源社区的关注,并且也有个人和企业开始尝试使用Spring Boot。 其实直到2016年,Spring Boot才真正在国内被使用起来。我之前在挖财的时候,2015年公司就开始采用Spring Boot来构建基于Dubbo的微服务架构。到现在,Spring Boot几乎是所有公司的第一选择。
Build AnythingSpring Boot被官方定位为“BUILD ANYTHING”,Spring Boot官方的概述是这么描述Spring Boot的。
Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run".
// 通过Spring Boot可以轻松的创建独立的、生产级别的基于Spring 生态下的应用,你只需要运行即可。
We take an opinionated view of the Spring platform and third-party libraries so you can get started with minimum fuss. Most Spring Boot applications need minimal Spring configuration.
//对于Spring平台和第三方库,我们提供了一个固化的视图,这个视图可以让我们在构建应用是减少很多麻烦。大部分spring boot应用只需要最小的Spring 配置即可。
如果大家不习惯看英文文档,可能理解起来比较复杂,翻译成人话就是:Spring Boot能够帮助使用Spring Framework生态的开发者快速高效的构建一个基于Spring以及spring 生态体系的应用。
为了让大家对这句话的理解更加深刻,我们来做两个小实验,一个是基于传统的Spring MVC框架构建一个项目、另一种是使用Spring Boot。
Spring MVC With Spring Boot通过Spring MVC项目搭建过程来对比Spring Boot的差异和优势。
Spring MVC项目搭建过程
- 创建一个maven-webapp项目
- 添加jar包依赖
< dependency> < groupId> org.springframework< /groupId> < artifactId> spring-beans< /artifactId> < version> 5.2.5.RELEASE< /version> < /dependency> < dependency> < groupId> commons-logging< /groupId> < artifactId> commons-logging< /artifactId> < version> 1.2< /version> < /dependency>
spring-context spring-context-support spring-core spring-expression spring-web spring-webmvc
- 修改web.xml文件
< context-param> < !--配置上下文配置路径--> < param-name> contextConfigLocation< /param-name> < param-value> classpath:applicationContext.xml< /param-value> < /context-param> < !--配置监听器--> < listener> < listener-class> org.springframework.web.context.ContextLoaderListener< /listener-class> < /listener> < listener> < listener-class> org.springframework.web.util.IntrospectorCleanupListener< /listener-class> < /listener> < !--配置Spring MVC的请求拦截--> < servlet> < servlet-name> springmvc< /servlet-name> < servlet-class> org.springframework.web.servlet.DispatcherServlet< /servlet-class> < init-param> < param-name> contextConfigLocation< /param-name> < param-value> classpath:dispatcher-servlet.xml< /param-value> < /init-param> < /servlet> < servlet-mapping> < servlet-name> springmvc< /servlet-name> < url-pattern> /< /url-patter> < /servlet-mapping>
- 在resources目录下添加dispatcher-servlet.xml文件
< ?xml version="1.0" encoding="UTF-8"?> < beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> < !-- 扫描 controller --> < context:component-scan base-package="com.gupaoedu.controller" /> < !--开启注解驱动--> < mvc:annotation-driven/> < !-- 定义视图解析器 --> < bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> < property name="prefix" value="https://www.songbingjia.com/"/> < property name="suffix" value="https://www.songbingjia.com/android/.jsp"/> < /bean>
- 创建一个Controller
@Controller public class HelloController {@RequestMapping(method = RequestMethod.GET,path = "/index") public String index(Model model){ model.addAttribute("key","Hello Gupao"); return "index"; } }
- 修改默认的index.jsp,设置el表达式的解析
< %@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" isELIgnored="false" %> ${key}
- 运行项目
思考和总结咱们再回到最开始Spring Boot的定义部分,Spring Boot能够帮助使用Spring Framework生态的开发者快速高效的构建一个基于Spring以及spring 生态体系的应用。
再对比两种构建过程,似乎也能够理解Spring Boot的作用了吧。当然它的作用不仅于此,后续会逐步揭开它的真实面目。
通过上面这个案例我们发现,如果没有spring boot,要去构建一个Spring MVC的web应用,需要做的事情很多
- 引入jar包
- 修改web.xml,添加监听和拦截
- 创建spring mvc核心配置文件dispatcher-servlet.xml
- 创建controller
- 部署到tomcat
理解约定优于配置我们知道,Spring Boot是约定由于配置理念下的产物,那么什么是约定由于配置呢?
约定优于配置是一种软件设计的范式,主要是为了减少软件开发人员需做决定的数量,获得简单的好处,而又不失灵活性。
简单来说,就是你所使用的工具默认会提供一种约定,如果这个约定和你的期待相符合,就可以省略那些基础的配置,否则,你就需要通过相关配置来达到你所期待的方式。
约定优于配置有很多地方体现,举个例子,比如交通信号灯,红灯停、绿灯行,这个是一个交通规范。你可以在红灯的时候不停,因为此时没有一个障碍物阻碍你。但是如果大家都按照这个约定来执行,那么不管是交通的顺畅度还是安全性都比较好。
而相对于技术层面来说,约定有很多地方体现,比如一个公司,会有专门的文档格式、代码提交规范、接口命名规范、数据库规范等等。这些规定的意义都是让整个项目的可读性和可维护性更强。
Spring Boot Web应用中约定优于配置的体现那么在前面的案例中,我们可以思考一下,Spring Boot为什么能够把原本繁琐又麻烦的工作省略掉呢? 实际上这些工作并不是真正意义上省略了,只是Spring Boot帮我们默认实现了。
而这个时候我们反过来思考一下,Spring Boot Web应用中,相对Spring MVC框架的构建而言,它的约定由于配置体现在哪些方面呢?
- Spring Boot的项目结构约定,Spring Boot默认采用Maven的目录结构,其中
src.main.java 存放源代码文件
src.main.resource 存放资源文件
src.test.java 测试代码
src.test.resource测试资源文件
target 编译后的class文件和jar文件
- 内置了嵌入式的Web容器,在Spring 2.2.6版本的官方文档中3.9章节中,有说明Spring Boot支持四种嵌入式的Web容器
Tomcat
Jetty
Undertow
Reactor
- Spring Boot默认提供了两种配置文件,一种是application.properties、另一种是application.yml。Spring Boot默认会从该配置文件中去解析配置进行加载。
- Spring Boot通过starter依赖,来减少第三方jar的依赖。
Spring Boot整合Mybatis实际上Spring Boot的本质就是Spring,如果一定要从技术发展的过程中找到一些相似的对比的话,你们可以对比一下Jsp/Servlet和Spring MVC, 两者都可以用来开发Web项目,但是在使用上,Spring MVC的使用会更加简单。
而Spring Boot和Spring 就相当于当年的JSP/Servlet和Spring MVC的关系。所以它本身并没有所谓新的技术,接下来,我带着大家来通过Spring Boot整合Mybatis实现数据的基本操作的案例,来继续认识一下Spring Boot。
创建Spring Boot 应用创建一个Web项目
引入项目中需要的starter依赖
<
dependency>
<
groupId>
mysql<
/groupId>
<
artifactId>
mysql-connector-java<
/artifactId>
<
/dependency>
<
dependency>
<
groupId>
org.mybatis.spring.boot<
/groupId>
<
artifactId>
mybatis-spring-boot-starter<
/artifactId>
<
version>
2.1.2<
/version>
<
/dependency>
<
dependency>
<
groupId>
org.springframework.boot<
/groupId>
<
artifactId>
spring-boot-starter-thymeleaf<
/artifactId>
<
/dependency>
创建数据库表
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
`address` varchar(80) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
配置数据库连接
spring:
datasource:
url: jdbc:mysql://192.168.13.106:3306/test_springboot
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
开发数据库访问层
文章图片
创建实体对象
public class User {
private int id;
private String name;
private String address;
}
创建Mapper
//@Repository可以支持在你的持久层作为一个标记,可以去自动处理数据库操作产生的异常
@Repository
@Mapper
public interface UserMapper {User findById(int id);
List<
User>
list();
int insert(User user);
int delete(int id);
int update(User user);
}
编写mapper文件
在resource文件目录下创建UserMapper.xml文件,内容如下
<
?xml version="1.0" encoding="utf-8" ?>
<
!DOCTYPE mapper PUBLIC
"-//mybatis.org//DTD com.example.Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<
mapper namespace="com.example.demo.mapper.UserMapper">
<
resultMap id="resultMap" type="com.example.demo.entity.User">
<
id property="id" column="id"/>
<
result property="name" column="name"/>
<
result property="address" column="address"/>
<
/resultMap>
<
select id="findById" resultMap="resultMap" parameterType="java.lang.Integer">
select * from t_user where id=#{id}
<
/select>
<
select id="list" resultMap="resultMap">
select * from t_user
<
/select>
<
insert id="insert" parameterType="com.example.demo.entity.User" keyProperty="id" useGeneratedKeys="true">
insert into t_user(name,address) values(#{name,jdbcType=VARCHAR},#{address,jdbcType=VARCHAR})
<
/insert>
<
delete id="delete" parameterType="java.lang.Integer">
delete from t_user where id=#{id}
<
/delete>
<
update id="update" parameterType="com.example.demo.entity.User">
update t_user set name=#{name,jdbcType=VARCHAR},address=#{address,jdbcType=VARCHAR} where id=#{id,jdbcType=INTEGER}
<
/update>
<
/mapper>
定义service及实现
public interface IUserService {User findById(int id);
List<
User>
list();
int insert(User user);
int delete(int id);
int update(User user);
}@Service
public class UserServiceImpl implements IUserService {
@Autowired
private UserMapper userMapper;
}
创建Controller
@RestController
public class Controller {@Autowired
private IUserService userService;
@GetMapping("/user/{id}")
public User user(@PathVariable("id") int id){
return userService.findById(id);
}@GetMapping("/users")
public List<
User>
users(){
return userService.list();
}@PostMapping("/user")
public String insertUser(User user){
int row=userService.insert(user);
return row>
0?"SUCCESS":"FAILED";
}@PutMapping("/user")
public String updateUser(User user){
int row=userService.update(user);
return row>
0?"SUCCESS":"FAILED";
}
@DeleteMapping("/user/{id}")
public String deleteUser(@PathVariable("id") int id){
return userService.delete(id)>
0?"SUCCESS":"FAILED";
}}
修改配置
- 在Spring 的Main方法上增加以下注解,用来扫描Mybatis的Mapper文件
@MapperScan("com.example.demo.mapper")
- 配置Mapper配置文件的地址,在application.yml中
mybatis: mapper-locations: classpath:*Mapper.xml
idint,
name varchar(20),
address varchar(20)
项目打包
- mvn -Dmaven.test.skip -U clean install
- java -jar xxx.jar
简单来说,基于Spring Boot的项目中,我们只需要写Controlelr、Service、Dao即可。甚至很多情况下我们dao都不需要管,比如使用mybatis-plus这个插件,就可以省去很多固定的dao层逻辑。
所以实际上,Spring Boot并没有新鲜的东西,因此你看到市面上大部分讲spring boot的书,这些书我几乎都看过,基本上都是讲解Spring Boot的应用,以及Spring Boot的一些特性分析。因为一旦你想讲Spring Boot的原理,就必然会回归到Spring这块的内容上。比如小马哥的Spring Boot编程思想着本书,大篇幅的都是在讲Spring Framework。因为Spring Boot的内核还是Spring Framework。
Spring Boot与微服务接下来,给大家讲讲spring boot与微服务这块的内容。
什么是Spring Cloud首先,我们要简单了解一下什么是微服务,按照我的理解来说,微服务就是微粒度的服务,它是面向服务架构(SOA)的进一步优化。如果大家不是很好理解,翻译成白话就是
一个业务系统,原本是在一个独立的war包中。现在为了更好的维护和提高性能,把这个war包按照业务纬度拆分成了一个个独立的业务子系统,每个子系统提供该业务领域相关的功能,并暴露API接口。
这些服务彼此之间进行数据交换和通信来实现整个产品的功能。
而这些业务子系统,实际上代表的就是一个服务,那么所谓的微服务,说的是这个服务的粒度。至于服务的粒度什么样才叫微,其实没有一个固定的衡量标准。更多的还是在每个公司具体的业务粒度的把控上。
微服务化遇到的问题在为服务化之后,会面临很多的问题,比如服务注册、服务路由、负载均衡、服务监控等等。这些问题都需要有相应的技术来解决,这个时候,Spring Cloud就出现了。
简单来说,Spring Cloud 提供了一些可以让开发者快速构建微服务应用的工具,比如配置管理、服务发现、熔断、智能路由等,这些服务可以在任何分布式环境下很好地工作。Spring Cloud 主要
致力于解决如下问题:
- Distributed/versioned configuration,分布式及版本化配置。
- Service registration and discovery,服务注册与发现。
- Routing,服务路由。
- Service-to-service calls,服务调用。
- Load balancing,负载均衡。
- Circuit Breakers,断路器。
- Global locks,全局锁。
- Leadership election and cluster state,Leader 选举及集群状态。
- Distributed messaging,分布式消息。
框架进行再次封装后屏蔽掉了复杂的配置,给开发者提供良好的开箱即用的微服务开发体验。不难看出,Spring Cloud 其实就是一套规范,而 Spring Cloud Netflix、Spring Cloud Consul、Spring CloudAlibaba 才是 Spring Cloud 规范的实现。
为什么Spring Cloud是基于Spring Boot那为什么Spring Cloud会采用Spring Boot来作为基础框架呢?原因很简单
- Spring Cloud它是关注服务治理领域的解决方案,而服务治理是依托于服务架构之上,所以它仍然需要一个承载框架
- Spring Boot 可以简单认为它是一套快速配置Spring应用的脚手架,它可以快速开发单个微服务
文章图片
Spring Boot的四大核心机制如果一定要基于Spring Boot的特性去说,那么只能去说Spring Boot的四大核心机制,分别是@EnableAutoConfiguration 、 Starter开箱即用组件、Actuator应用监控、Spring Boot CLI 命令行工具。
EnableAutoConfiguration Starter告诉Spring Boot需要什么功能,它就能引入需要的库。
Actuator让你能够深入运行中的Spring Boot应用程序
Spring Boot CLISpring Boot CLI 为Spring Cloud 提供了Spring Boot 命令行功能。我们可以通过编写groovy脚本来运行Spring Cloud 组件应用程序。步骤如下、
- 下载spring-boot-cli
Spring Boot CLI:https://repo.spring.io/release/org/springframework/boot/spring-boot-cli/2.2.6.RELEASE/spring-boot-cli-2.2.6.RELEASE-bin.zip
- 配置环境变量
- 在控制台
spring --version
查看CLI版本
- 使用CLI运行应用。我们可以使用run命令编译和运行Groovy源代码。Spring Boot CLI中包含所有运行Groovy所需要的依赖。
- 创建一个
hello.groovy
文件
@RestController class HelloController {@GetMapping("/hello") String hello(){ return "Hello World"; } }
- 在控制台执行
spring runhello.groovy
,如果需要传递参数,比如端口,和JVM参数类似
spring run hello.groovy -- --server.port=9000
- EnableAutoConfiguration
- Starter
- Actuator
- Spring Boot CLI
Spring Boot CLI 为Spring Cloud 提供了Spring Boot 命令行功能。我们可以通过编写groovy脚本来运行Spring Cloud 组件应用程序。步骤如下、
- 下载spring-boot-cli
- 配置环境变量
- 在控制台
spring --version
查看CLI版本
- 【#yyds干货盘点# Spring Boot的前世今生以及它和Spring Cloud的关系详解。】使用CLI运行应用。我们可以使用run命令编译和运行Groovy源代码。Spring Boot CLI中包含所有运行Groovy所需要的依赖。
- 创建一个
hello.groovy
文件
@RestController class HelloController {@GetMapping("/hello") String hello(){ return "Hello World"; } }
- 在控制台执行
spring runhello.groovy
,如果需要传递参数,比如端口,和JVM参数类似
spring run hello.groovy -- --server.port=9000
推荐阅读
- 22张图带你了解IP地址有什么作用
- Jenkins安装部署
- ES6学习 第二章 变量的解构赋值
- #yyds干货盘点#Java ASM系列((094)查找相关的指令)
- openstack的扩展#私藏项目实操分享#
- 千呼万唤,web人脸识别登录完整版来了,这样式我爱了
- 掌握Java的内存模型,你就是解决并发问题最靓的仔
- 在WordPress主题中禁用页脚会停止粘性导航
- 在WordPress Customizer上禁用WordPress自定义CSS seciton