要理解Spring Boot的倒退背景,还得从2004年Spring Framework1.0版本公布开始说起,不过大家都是从开始学习Java就应用Spring Framework了,所以就不做过多开展。
随着应用Spring Framework进行开发的企业和集体越来越多,Spring 也缓缓从一个繁多简洁的小框架编程了一个大而全的开源软件,Spring Framework的边界一直进行扩张,到了当初Spring 简直能够做任何事件。目前市面上绝大部分的开源组件和中间件,都有Spring对应组件的反对,
你们如果去关注Spring目前的官网,你会发现他的slogan是:Spring makes Java 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
在整个过程中,咱们发现只有一个货色和Hello Word性能相干,那就是控制器(controller),剩下的都是Spring 开发的Web应用程序必须要的通用模版,既然所有Spring Web应用程序都要用到他们,那为什么还要你来提供这些货色呢?
所以,直到2012年10月份,一个叫Mike Youngstrom(扬斯特罗姆)在Spring Jira中创立了一个性能申请,要求在Spring Framework中反对无容器Web应用程序体系结构,他谈到了在主容器疏导 spring 容器内配置 Web 容器服务。
https://jira.spring.io/browse…
<code class="txt">I think that Spring's 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 Anything
Spring Boot被官网定位为“BUILD ANYTHING”,Spring Boot官网的概述是这么形容Spring Boot的。
<code class="java">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包依赖
<code class="xml"><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文件
<code class="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文件
<code class="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="/"/> <property name="suffix" value=".jsp"/> </bean>
-
创立一个Controller
<code class="java">@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表达式的解析
<code class="html"><%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" isELIgnored="false" %> ${key}
- 运行我的项目
Spring Boot搭建过程
间接基于start.spring.io这个脚手架搭建即可。
思考和总结
咱们再回到最开始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
这个过程如果不相熟,很可能须要1~2个小时,如果是老手,可能须要更长时间。然而spring boot,不论是老手还是新手,都可能分分钟解决问题。
了解约定优于配置
咱们晓得,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可能方便快捷的构建一个Web利用的机密。当然Spring Boot的约定优于配置还不仅体现在这些中央,在后续的剖析中还会看到Spring Boot中约定优于配置的体现。
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依赖
<code class="xml"><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>
创立数据库表
<code class="sql">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;
配置数据库连贯
<code class="yaml">spring: datasource: url: jdbc:mysql://192.168.13.106:3306/test_springboot username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver
开发数据库拜访层
创立实体对象
<code class="java">public class User { private int id; private String name; private String address; }
创立Mapper
<code class="java">//@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文件,内容如下
<code class="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及实现
<code class="java">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
<code class="java">@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文件
<code class="java">@MapperScan("com.example.demo.mapper")
-
配置Mapper配置文件的地址,在application.yml中
<code class="yml">mybatis: mapper-locations: classpath:*Mapper.xml
id int,
name varchar(20),
address varchar(20)
)
我的项目打包
- mvn -Dmaven.test.skip -U clean install
- java -jar xxx.jar
简略总结
这个代码,我想,大家应该写过无数遍了,而在基于Spring Boot集成Mybatis这个案例中,外围的业务逻辑并没有缩小,它只缩小了一些繁琐的配置,使得咱们更聚焦在业务开发层面。
简略来说,基于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 团队全新研发的框架,它只是把一些比拟优良的解决微服务架构中常见问题的开源框架基于 Spring Cloud 标准进行了整合,通过 Spring Boot 这个
框架进行再次封装后屏蔽掉了简单的配置,给开发者提供良好的开箱即用的微服务开发体验。不难看出,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的个性去说,那么只能去说Spring Boot的四大外围机制,别离是@EnableAutoConfiguration 、 Starter开箱即用组件、Actuator利用监控、Spring Boot CLI 命令行工具。
EnableAutoConfiguration
Starter
通知Spring Boot须要什么性能,它就能引入须要的库。
Actuator
让你可能深刻运行中的Spring Boot应用程序
Spring Boot CLI
Spring Boot CLI 为Spring Cloud 提供了Spring Boot 命令行性能。咱们能够通过编写groovy脚本来运行Spring Cloud 组件应用程序。步骤如下、
-
下载spring-boot-cli
Spring Boot CLI:https://repo.spring.io/releas…
- 配置环境变量
- 在控制台
spring --version
查看CLI版本 - 应用CLI运行利用。咱们能够应用run命令编译和运行Groovy源代码。Spring Boot CLI中蕴含所有运行Groovy所须要的依赖。
-
创立一个
hello.groovy
文件<code class="groovy">@RestController class HelloController { @GetMapping("/hello") String hello(){ return "Hello World"; } }
-
在控制台执行
spring run hello.groovy
,如果须要传递参数,比方端口,和JVM参数相似<code class="shell">spring run hello.groovy -- --server.port=9000
Spring Boot的四大外围个性
- EnableAutoConfiguration
- Starter
- Actuator
-
Spring Boot CLI
Spring Boot CLI 为Spring Cloud 提供了Spring Boot 命令行性能。咱们能够通过编写groovy脚本来运行Spring Cloud 组件应用程序。步骤如下、
-
下载spring-boot-cli
Spring Boot CLI:https://repo.spring.io/releas…
- 配置环境变量
- 在控制台
spring --version
查看CLI版本 - 应用CLI运行利用。咱们能够应用run命令编译和运行Groovy源代码。Spring Boot CLI中蕴含所有运行Groovy所须要的依赖。
-
创立一个
hello.groovy
文件<code class="groovy">@RestController class HelloController { @GetMapping("/hello") String hello(){ return "Hello World"; } }
-
在控制台执行
spring run hello.groovy
,如果须要传递参数,比方端口,和JVM参数相似<code class="shell">spring run hello.groovy -- --server.port=9000
-
版权申明:本博客所有文章除特地申明外,均采纳 CC BY-NC-SA 4.0 许可协定。转载请注明来自
Mic带你学架构
!
如果本篇文章对您有帮忙,还请帮忙点个关注和赞,您的保持是我一直创作的能源。欢送关注同名微信公众号获取更多技术干货!