如何基于Spring Boot搭建一个完整的项目
前言
使用Spring Boot做后台项目开发也快半年了,由于之前有过基于Spring开发的项目经验,相比之下觉得Spring Boot就是天堂,开箱即用来形容是绝不为过的。在没有接触Spring Boot 之前,以为Spring Boot 是一个新的框架体系。正好Spring Boot出现先的时候,也是微服务特别火的时候,大家不约而同把Spring Boot 和微服务等同起来了,但其实并不是如此,那么到底什么是Spring Boot ? 基于Spring Boot 又是如何开发的呢 ? 带着这两个问题,大家继续往下看。
Spring Boot 特点
Our primary goals are:
- Provide a radically faster and widely accessible getting started experience for all Spring development.
- Be opinionated out of the box, but get out of the way quickly as requirements start to diverge from the defaults.
- Absolutely no code generation and no requirement for XML configuration.
上述是从Spring Boot官方文档上摘录的,简述言之Spring Boot框架的目的就是开箱即用、去除配置。Spring Boot并不是重复去造就一个轮子,它的出现是为Spring的开发带来一种全新的体验,从而大大的降低Spring框架的使用门槛。
下面主要从几个特性介绍Spring Boot是如何简化开发的。
Spring Boot启动器
使用过Spring Boot的同学都知道,快速编写一个Spring Boot的Web Demo需要在pom文件中加入如下:
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
</dependencies>
Spring Boot 提供了很多像spring-boot-starter-web这样的启动器,名称都是spring-boot-starter-* 。
截图部分来自Spring Boot官网,只是Spring Boot启动器中小部分,更多启动器可以到官网上查找。
启动器为何物? 以spring-boot-starter-web 这个web开发用到的启动器为例。
从上图可以看出spring-boot-starter-web.jar包里面没有任何代码,对没有任何代码。只有一个pom文件。what ? 其中包中pom.xml的内容如下所示:
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></dependency><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-validator</artifactId></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId></dependency>
</dependencies>
以前在基于Spring框架下进行web开发通常需要在模块的pom文件中引入spring-webmvc、spring-web、jackson、tomcat等依赖模块。如果使用Spring Boot的启动器,只需要引入spring-boot-starter-web模块就可以。看到这里聪明的读者应该明白了为嘛启动器的包中没有代码只有pom文件了吧。 简言之Spring Boot的启动器就是将不同的第三方组件依赖进行了套件封装,为开发Spring应用提供了一个易用的套件库。开发者再也不用在pom中引入那么多模块了,一个套件搞定一个相关的功能所需要的所有依赖库,这个体验很棒吧。
继续解锁下一个Spring Boot的牛逼特性。
内嵌Web容器(Tomcat或者Jetty)
早期基于Spring框架开发的时候,Web容器是不可以缺少的一个步骤。通常把代码编译成war包,然后扔到tomcat容器中进行运行。 这时候需要单独的下载tomcat容器,有点小麻烦。Spring Boot直接把通过内嵌web容器,直接运行。 那么Spring Boot是如何内嵌的web容器的呢? 其中以tomcat容易为例。
上面介绍启动器的时候,有介绍spring-boot-starter-web启动器,这是进行web开发的时候需要在pom中引入的模块。进入到这个启动器的内部pom文件,如下描述:
<description>
Starter for building web, including RESTful, applications using
Spring MVC. Uses Tomcat as the default embedded container
</description><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
看了spring-boot-starter-web启动器的内部pom描述,很容易明白。tomcat是通过spring-boot-starter-web启动器引入的,并且在Spring Boot 中默认的Web容器是tomcat,当然也可以换成更轻量级的Jetty,这里不做介绍 。关键在于spring-boot-starter-tomcat 这个tomcat启动器,引入它之后,所有tomcat相关的jar包都引入进来了。在启动Spring Boot服务的时候,就会调用tomcat容器的启动。为了提高点文章的逼格来点源码分析。
在启动Spring Boot的时候,控制台的日志打印其实很好的告知了我们Spring Boot在启动的时候,框架做了哪些事情。选出两条和Tomcat相关的日志:
s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8094 (http)
s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8094 (http)
通过日志发现了一个类 TomcatEmbeddedServletContainer,搜寻到这个类属spring-boot.jar包里面的。通过下图所示的spring-boot-1.5.9.RELEASE.jar包目录结构和包名很容易猜测到Web容器的启动就是这个包来控制的。
核心接口 EmbeddedServletContainer,其中三个容器分别对接口进行了实现,对方法进行了重写。 接口代码如下:
public interface EmbeddedServletContainer {
/*** Starts the embedded servlet container.*/
void start() throws EmbeddedServletContainerException;/*** Stops the embedded servlet container*/
void stop() throws EmbeddedServletContainerException;/*** Return the port this server is listening on.*/
int getPort();
}
其实除了内嵌web容器的启动和spring-boot包有关外,整个Spring Boot的服务启动,都是在这个包中实现的,感兴趣的同学可以跟这个包死磕到底,深入下去。
完全去配置文件化
Spring Boot之所以号称降低了Spring的开发门槛其实是有杀手锏的,完全去配置化就是重量级的杀手锏。 早起完成Spring的开发,最烦的就是各种xml配置文件。在Spring Boot的项目工程中确实看不到了那些烦人的xml,它们到哪去了?
回到Spring Boot的项目工程,其中还有两处变化的没有介绍。
- Resource资源文件下的四个属性文件。application.properties 、application-dev.properties、application-prd.properties、application-stg.properties。
- spring-boot-autoconfigure-*.jar(省去了版本号).
属性文件这里就不介绍了,配置相关的属性的地方,根据不同的环境(测试、开发、生产)提供了不同名称的属性文件。
spring-boot-autoconfigure-*.jar 很明显从名字就知道,自动配置相关的jar包。没错,Spring Boot的属性自动配置全部都是由这个包实现的。
打开spring-boot-autoconfigure-*.jar,包名称就告诉了我们一切。在这个包中集成了我们大部分平时开发需要的中间件,比方说: amqp 消息中间件、cache缓存中间件、data数据持久化相关的中间件。基于Spring的框架,如果要集成各种常用中间件, 少不了一个使用了 @Configuration注解的配置类和各种属性配置。但是使用Spring Boot框架,@Configuration注解的配置类,全部不需要了。只要在application.properties 配置属性值就可以直接使用。
这里把集成Redis作为一个例子。查看spring-boot-autoconfigure-*.jar 中data包目录下的redis包可以看到几个类,其中重点在于RedisAutoConfiguration 和 RedisProperties 这两个类。
- RedisProperties类
通过 @ConfigurationProperties(prefix = "spring.redis")注解,把在application.properties 中配置的redis 相关的名称为spring.redis.*的属性全部注入到 RedisProperties类的属性变量中。
- RedisAutoConfiguration类
在这个类中主要定义了几个Bean, 主要是JedisConnectionFactory 和 JedisPoolConfig、StringRedisTemplate等。以前我们基于Spring框架,需要自己定义Bean全部都被Spring Boot框架自己定义了,其他的中间件也是如此。 再结合Spring Boot中使用的是3.0+版本的Servlet包,使用注解完成各种Listener、Filter、Servlet 以及Bean的定义,让无xml化不是梦了。
思考: 如何修改基于框架下的自动配置的属性值?
完全依赖框架的自动配置,其实也是件蛮不安全的事情。有次生产环境上,redis一直抛出一个异常。但是没多久又好了,持续了很多天。从异常可以判断是客户端使用了redis连接池提供的无效链接。通过Jedis的源码可以知道,使用的连接池是apache-common-pool2组件。其中相关的参数有BaseObjectPoolConfig类中的
private boolean testOnBorrow = false;
private boolean testWhileIdle = false;
这两个参数值默认都是false。其中testOnBorrow 代指获取连接池的连接前,检查链接的有效性。 testWhileIdle 是空闲的时候检查链接的有效性。 需要把这两个参数都设置为true。因为默认的自动配置值都是false,但是这两个属性值又不在RedisProperties类中,所以不能通过application.properties文件来修改。那怎么修改呢? 现在项目重写了JedisConnectionFactory 和 JedisPoolConfig、StringRedisTemplate这三个Bean,通过重写Bean来修改属性值。异常没有了,但是总觉得这不是最好的方式,大家如果有更好的方式,欢迎留言,谢谢!
等等: 说好的是工程介绍,怎么全是文字,自己都不想看了。好吧,回到正题,搭建基于Spring Boot的工程项目需要哪些东西?
整个项目的结构
<modules><module>pa-market-update</module><module>pa-market-delete</module><module>pa-market-common</module><module>pa-market-add</module><module>pa-market-schedule</module>
</modules>
完整的项目一般都是根据业务进行功能划分的。上面是主pom文件的内容,common是公共模块,schedule是定时任务模块(每个项目应该都少不了定时任务吧),其他的各自业务模块,名字随便取的。
单个模块下包目录结构
在前后端分离的项目中,通常要求基于Restful风格编写接口,基于这种风格,项目每个子模块的包目录结构其实是可以固定。
- aspect 包: 基于AOP的拦截器一般都放在这个包。
- consts包 : 常量包
- dto包:表现层和业务层的中间产物
- entity包: 对应表结构的实体类
- service包: 业务层,主要实现业务逻辑的Service类
- utils包: 工具类
- web包: Controller控制层,也是一个项目的入口,通过它可以知道有多少接口
- Application 类: Spring Boot的启动类,注意它放的位置是有讲究的
集成Mybatis框架
DAO层在一个项目中是必不可以少的,在这里采用常用的ORM框架Mybatis。 在pom文件中需要加入的模块。
<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
mybatis-spring-boot-starter这个启动器不是Spring Boot官方提供的,是Mybatis团队自己集成的,所以名字跟官方的启动器名字不一样。
再加上 @Mapper注解的Mapper类和Mapper.xml文件,就可以了。当然少不了在application.properties中配置数据库的基本信息。使用ORM框架就这么简单。其他第三方框架也是如此,这里就不重复了。
日志框架
日志打印是一个项目必不可少的部分,在这里介绍log4j2的日志框架。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId></dependency>
log4j2不支持属性文件,只支持xml文件或者json文件。这里介绍xml文件的配置。
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="INFO" packages="com.pa.market" >
<appenders><!--这个输出控制台的配置 --><Console name="Console" target="SYSTEM_OUT"><PatternLayout pattern="%d{HH:mm:ss} %-5p - %msg%n" /><!-- 设置级别 --><ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="NEUTRAL" /><ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/><ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY" /><ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/></Console><RollingFile name="RollingFile" fileName="/data/logs/market/market-inquiry.log"filePattern="/data/logs/market/market-inquiry.%d{yyyy-MM-dd}.%i.log"><PatternLayout><charset>UTF-8</charset><Pattern>%d{HH:mm:ss} %-5p - %msg%n</Pattern></PatternLayout><Policies><TimeBasedTriggeringPolicy /><SizeBasedTriggeringPolicy size="256 MB" /></Policies></RollingFile>
</appenders>
<loggers><!-- 将业务dao接口填写进去,并用控制台输出即可 --> <logger name="com.pa.market.common.mapper" level="DEBUG" additivity="false"> <appender-ref ref="Console"/> <appender-ref ref="RollingFile" /></logger><AsyncRoot level="info"><appender-ref ref="Console" /><appender-ref ref="RollingFile" /></AsyncRoot>
</loggers>
</configuration>
如果需要打印Mybatis框架中的日志,可以配置 loggers 标签。每个标签的含义,在官网上可以查询到,这里不做介绍。
打包部署
Spring Boot 框架下如果想打包相应的模块代码,需要在资源文件下添加一个assembly.xml文件。文件内容如下:
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>release</id>
<formats> <format>tar.gz</format>
</formats>
<fileSets> <fileSet> <directory>${project.basedir}\src\main\resources</directory> <outputDirectory>conf</outputDirectory> </fileSet> <fileSet> <directory>${project.basedir}\src\script</directory> <outputDirectory>script</outputDirectory> <fileMode>0755</fileMode> </fileSet>
</fileSets> <dependencySets> <dependencySet> <useProjectArtifact>true</useProjectArtifact> <outputDirectory>lib</outputDirectory> <!-- 将scope为runtime的依赖包打包到lib目录下。 --> <scope>runtime</scope> </dependencySet>
</dependencySets>
</assembly>
通过这个xml文件,maven执行mvn package命令的时候,会出现一个release包,其中包含conf、lib两个文件夹。其中conf中存放的是模块下Resource目录下存放的资源文件,lib包下是模块所有依赖的jar包。在部署到linux服务器的时候,这两个文件很重要。
maven的很多功能是通过插件来实现的,所以基于assembly.xml的打包功能,需要在pom文件中配置如下插件。
<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><configuration><excludes><exclude>*</exclude></excludes></configuration></plugin><plugin><artifactId>maven-assembly-plugin</artifactId><executions> <!--执行器 mvn assembly:assembly --><execution><id>make-zip</id><!--名字任意 --><phase>package</phase><!-- 绑定到package生命周期阶段上 --><goals><goal>single</goal><!-- 只运行一次 --></goals><configuration><descriptors> <!--描述文件路径 --><descriptor>src/main/resources/assembly.xml</descriptor></descriptors></configuration></execution></executions></plugin></plugins>
</build>
总结
通过后面介绍如何搭建工程的大篇幅粘贴,终于把文章的篇幅给填充上去了, 哈哈,这里再多唠叨几句。Spring Boot 框架的出现,让Spring 开发变得异常的简单,对于开发者来说是好事也是坏事。好处,开发门槛低了,可以更多的关注业务代码的书写。坏处,框架封的越简单,框架层面出现问题后越傻眼,对底层的框架原理的理解也越少。所以作为有技术追求的你,懂得应该怎么做吧。小编在使用框架的时候,遇到了不少疑问,大部分也都记录下来了。待把疑问解决后,后续会和大家继续分享,敬请期待! 从Spring 到 Spring Boot 再到 Spring Cloud ,东西太多,大家一起加油!
转载于:https://www.cnblogs.com/1024Community/p/8643467.html
如何基于Spring Boot搭建一个完整的项目相关推荐
- 使用spring boot实现一个简单的项目——⽤户管理功能
Spring Boot之用户管理功能 趁着这几天有时间跟大家分享一个使用spring boot实现的一个简单的项目,也开启了我第一次在CSDN上面写博客,相信这是个新的篇章.好了,废话不多说,直接上真 ...
- 一个基于 Spring Boot 的开源社区
一款基于 Spring Boot 的开源社区:forum-java,类似于微信开放社区.头条开发者社区等等.forum-java 是一个 100% 开源的面向内容的社区论坛. 开源社区有用户端和管理端 ...
- 基于 Spring Security 搭建用户权限系统(二) - 自定义配置
说明 本文的目的是如何基于 Spring Security 去扩展实现一个基本的用户权限模块, 内容会覆盖到 Spring Security 常用的配置. 文中涉及到的业务代码是不完善的, 甚至会存在 ...
- 6个基于 Spring Boot 的开源社区项目!功能强大,界面炫酷
整理了 6 个不错的基于 Spring Boot 开发的社区类项目,每个都非常不错! 你可以参考这些项目用来作为自己的项目经验,或者你可以基于这些项目搭建一个自己的知识社区. 原创不易,如果本文对你有 ...
- Spring boot 搭建个人博客系统(二)——登录注册功能
Spring boot 搭建个人博客系统(二)--登录注册功能 一直想用Spring boot 搭建一个属于自己的博客系统,刚好前段时间学习了叶神的牛客项目课受益匪浅,乘热打铁也主要是学习,好让自己熟 ...
- 真的简单,单手用Spring Boot 开发一个微信小程序
前言 嗨,大家好,现在微信使用的用户很多,作为开发人员也可以建立一个自己的微信小程序,本期与大家分享一下作者建立微信小程序的开发流程. 申请 百度搜索微信公众号平台,然后扫码登录注册一个微信公 ...
- 自荐Mall4j项目一个基于spring boot的Java开源商城系统
前言 Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样 ...
- 保姆级的一个基于spring boot开发的前后端分离商城教程
前言 推荐一个基于spring boot开发前后端分离商城,有完整的代码笔记和视频教程,希望对正在找项目练手的同学有所帮助 本文资料文档领取(在文末) 一.项目背景 5中常见的电商模式 B2B .B2 ...
- sku设计mysql_基于spring boot拥有完整sku和下单流程的完全商城
一个基于spring boot.spring oauth2.0.mybatis.redis的轻量级.前后端分离.防范xss攻击.拥有分布式锁,为生产环境多实例完全准备,数据库为b2b2c设计,拥有完整 ...
- 一个不错的基于Spring boot+Security+Redis+MySql实现权限登录和反爬虫的脚手架
介绍 一个基于Spring boot 2.4.2.JDK 1.8.Security.防恶意请求技术实现的前后端分离的脚手架,可以为开发人员省去前期框架调研和搭建的成本. 软件架构 Spring boo ...
最新文章
- php读取不到指定的php.ini配置
- CUMCM之2006B:2006之B题: 艾滋病疗法的评价及疗效的预测
- Linq to XML的练习
- android自动退出对话框,Android开发 在用EditText对话框Dialog退出后实现输入盘的退出...
- 设计模式学习笔记——建造者(Builder)模式
- 关于Socket通讯时通讯协议的制定
- 轻松学c语言编程.pdf等,轻松学编程 轻松学C语言编程pdf
- 升级ipython_Linux服务器python升级
- Javascript 时间操作汇总
- DataUml Design 介绍11 - DataUML 1.5版本功能-支持无Oracle客户端
- ssas报表项目数据集_处理SSAS多维OLAP多维数据集的有效方法
- python无法打开txt_在Python中打开“.txt”文件
- umask 文件预设权限掩码
- 计算机语言学汉语言文学,汉语言文学本科通关宝典-《语言学概论》.pdf
- dell笔记本触摸板没反应怎么办,戴尔笔记本触摸面板用不了
- 什么是等保(信息安全等级保护)?
- centos 7 JDK 环境部署
- 端口复用技术简单了解;重用端口;socket复用端口
- 罗斯柴尔德投资公司增加对GBTC的投资
- ‘annotationProcessor‘ dependencies won‘t be recognized as kapt annotation processors. Please change