在pom.xml文件中添加依赖之前需要先添加spring-boot-starter-parent. spring-boot-starter-parent主要提供了如下默认配置
@Spring BootApplication注解是加在项目的启动类上的。
@Spring BootApplication实际上是一个组合注解,这个注解有由3个注解组成
@Spring BootConfiguration
表明这是一个配置类,开发者可以在这个类中配置Bean。从这个角度讲,这个类所扮演的角色有点类似于Spring中的applicationContext.xml文件中的角色。
@EnableAutoConfiguration
表示开启自动化配置。
@ComponentScan
完成包扫描,也是Spring中的功能。由于@ComponentScan注解默认扫描的类都位于当前类所在包的下面,因此建议在实际项目开发中把项目启动类放在根包中。
虽然项目的启动类也包含@Configuration注解,但是开发者可以创建一个新的类专门用来配置Bean,这样便于配置的管理。这个类只需要加上@Configuration注解即可。代码如下:
@Configuration
public class MyConfig{
}
项目启动类中的@ComponentScan注解,除了扫描@Service,@Repository,@Component,@Controller和@RestController等之外,也会扫描@Configuration注解的类。
Spring Boot项目在启动时会打印一个banner
这个banner是可以定制的。具体定制的方法可以参考原著。
但是想关闭banner也是可以的,修改项目启动类的main方法,代码如下:
public static void main(String...args)
{
SpringApplicationBuilder builder = new SpringApplicationBuilder(Chapter012Application.class);
builder.bannerMode(Banner.Mode.OFF).run(args);
}
通过SpringApplicationBuilder来设置bannerMode为OFF,这样启动时banner就消失了。
在Spring Boot项目中,可以内置Tomcat等容器。当开发者添加了spring-boot-starter-web依赖之后,默认为使用Tomcat作为Web容器。如果需要对Tomcat做进一步的配置,可以在application.properties中进行配置。
server.port = 8081 // 配置了Web容器的端口号
server.error.path = /error # 配置了当项目出错时跳转去的页面
server.servlet.session.timeout = 30m
server.servlet.context-path = /chapter02 #表示项目名称,不配置时默认为/。如果配置了,就要在访问路径中加上配置的路径
server.tomcat.uri-encoding = utf-8
server.tomcat.max-threads = 500
server.tomcat.basedir = /home/sang/tmp
在实际项目中不可避免会有一些需要自己手动配置,承载这些自定义配置的文件就是resources目录下的application.properties文件。(也可以使用YAML配置来替代application.properties)配置。
Spring Boot项目中的application.properties配置文件一共可以出现在如下4个位置
如果这4个位置都有application.properties文件,那么加载的优先级从1到4依次降低。
SpringBoot将按照这个优先级查找配置信息,并加载到Spring Environment中。
Spring提供了@Value注解以及EnvironmentAware接口来将Spring Environment中的数据注入到属性中,SpringBoot对此进一步提出了类型安全配置属性(Type-safe Configuration Properties)
这样即使在数据量非常庞大的情况下,也可以更加方便地将配置文件中的数据注入到Bean中。考虑在appliation.properties中添加如下一段配置。
book.name = 三国演义
book.author = 罗贯中
book.price = 30
将这一段配置数据注入如下Bean中:
@Component
@ConfigurationProperties(prefix = "book") //描述了要加载的配置文件的前缀
public class Book{
private String name;
private String author;
private Float price;
//省略getter/setter
}
其他的请参考原书
YAML是JSON的超集,是一种专门用来写配置文件的语言,可以替代application.
YAM使用简单,利用缩进表示层级关系,大小写敏感。
在Spring Boot项目中使用YAML只需要在resouces目录下创建一个application.yml文件即可,然后向application.yml中添加如下配置。
server:
port:80
servlet:
context-path:/chapter02
tomcat:
uir-encoding:utf-8
这一段配置等效于application.properties中的如下配置
server.port = 80
server.servlet.context-path = /chpater02
server.tomcat.uri-encoding = utf-8
此时可以将resources目录下的application.properties文件删除,完全使用YAML完成文件的配置。
YAML不仅可以配置常规属性,也可以配置复杂属性
在Spring Boot中使用YAML虽然方便,但是YAML也有一些缺陷,例如无法使用@PropertySource注解加载YAML文件。如果项目中有这些需求,还是需要使用Properties的配置文件。
开发者在项目发布之前,一般需要频繁地在开发环境、测试环境以及生产环境之间进行切换,这个时候需要大量的配置需要频繁更改。例如数据库配置,redis配置,mongodb配置等。频繁修改带来了巨大的工作量,Spring对此提供了解决方案(@Profile注解),SpringBoot则更进一步提供了更加简洁的解决方案,SpringBoot中约定的不同环境下配置文件名称规则为application-{profile}.properties,profile占位符表示当前环境的名称。暂不研究。
在目前的企业级应用开发中,前后端分离是趋势,但是视图层技术还占有一席之地。SpringBoot对视图层技术提供了很好的支持,官方推荐使用的模板引擎是Thymeleaf,jsp技术不推荐。
Thymeleaf是新一代java模板引擎,与传统Java模板引擎不同的是,Thymeleaf支持HTML原型,既可以让前端工程师在浏览器中直接打开查看样式,也可以让后端工程师结合真实数据查看显示效果。同时,Spring Boot提供了Thymeleaf自动化配置解决方案。
JSON是目前主流的前后端数据传输方式。
例如,现在有一个实体类Book实体类:
public class Book{
private String name;
private String author;
@JsonIgnore
private Float price;
@JsonFormat(pattern = "yyyy-MM-dd")
private Date publicationDate;
//getter,setter方法我就不写了。
然后创建BookController,返回Book对象即可。
@Controller
public class BookController{
@GetMapping("/book")
@ResponseBody
public Book book(){
Book book = new Book();
book.setAuthor("Luo Guanzhong")
book.setName("San Guo Yan Yi");
book.setPrice(30f);
book.setPublicationDate(new Date());
return book;
}
@Controller注解表示这个类BookController是一个控制器。
@ResponseBody表明会将book()方法的返回值转化为json字符串。@ResponseBody注解仅仅能够用在@Controller注解的类中。
当我们运行springboot后端项目后,我们在浏览器中输入地址htt://localhost:8080/book
我们就会在浏览器的界面看到json数据,如下图所示:
可以看到,这个json文件存在3个key, 3个value,有同学就要问了,为什么Book中有4个属性,现在只有3个key?因为在Book类的定义中price属性被@JsonIgnore给注解了,所以json中就没有这个key了,前端拿到的json数据中也就没有这个key了。
对于前后端分离的项目来说,后端只需要负责提供数据,因此@Controller注解的类中的所有方法都是返回数据的,都需要转换成json格式(如果前后端是以json来交换数据的话)。那么就需要再每个方法的前面添加注解@ResponseBody,就很烦呀。
所以我们就可以将@Controller和@ResponseBody这两个注解合并起来写,写成@RestController。
那有同学要问了?为什么我方法的返回值是一个Book类,从Book类编程json数据,是谁来完成的呢?这中间是怎么对应的呢?
SpringMVC中使用消息转换器HttpMessageConverter对JSON的转换提供了很好的支持,在Spring Boot中,只需要添加Web依赖即
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
这个依赖中默认加入了jackson-databind作为JSON处理器,此时不需要添加额外的JSON处理器就能返回一段JSON了。
我还没有搞清楚。至少从这个例子中,我们可以看出,一个类编程了一个json对象。java对象的属性成了json对象的key,java对象的属性值成了json对象的value字符串.
springboot默认有消息转换器jackson-databind,如果我们有一些特殊的需求jackson-databind满足不了,我们可以自定义我们想要的消息转换器。但是一般都是可以满足我们的需求的,我们就不需要自定义了。
暂不研究。
在Spring MVC中,对于静态资源都需要开发者手动配置静态资源过滤。Spring Boot中对此也提供了自动化配置,可以简化静态资源过滤配置。
细节的去看书。我这里只讲解重要的结论:
SpringBoot默认会过滤所有的静态资源,而静态资源的配置一共有5个,分别是classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/, classpath:/public/以及/,也就是说,开发者可以将静态资源放到这5个位置中的任意一个。5个静态资源位置的优先级依次降低。但是一般情况下,Spring Boot项目不需要Webapp目录,所以第5个"/"可以暂时不考虑。
此时,如果在浏览器中输入"http://localhost:8080/p1.png",即可看到classpath:/META-INF/resources/目录下的p1.png。如果将classpath:/META-INF/resources/目录下的p1.png删除,就会访问到classpath:/resources/目录下的p1.png
如果开发者使用Intellij IDEA创建Spring Boot项目,就会默认创建出classpath:/static/目录,静态资源一般放在这个目录下即可。
暂不研究
Java中的文件上传一共涉及两个组件,
CommonsMultipartResolver
使用commons-fileupload来处理multipart请求
StandardServletMultipartResolver
基于Servlet 3.0来处理multipart请求
因此,若使用StandardServletMultipartResolver,则不需要添加额外的Jar包。在SpringBoot提供的文件上传自动化配置类MultipartAutoConfiguration中,默认也是采用StandardServletMulipartResolver. 所以,在Springboot中上传文件甚至可以做到零配置。
暂不研究
在处理异常时,开发者可以根据实际情况返回不同的页面,但是这种异常处理方式一般用来处理应用级别的异常,有一些容器级别的错误就处理不了。
在Spring Boot中,默认情况下,如果用户在发起请求时发生了404错误,Spring Boot会有一个默认的页面展示给用户。
看status就可以了
同理,如果发生了500错误,status = 500
自定义错误页暂未研究
CORS(Cross-Origin Resource Sharing)是由W3C制定的一种跨域资源共享技术标准。其目的就是为了解决前端的跨域请求。
在JavaEE开发中,最常见的前端跨域请求解决方案是JSONP,但是JSONP只支持GET请求,这是一个很大的缺陷,而CORS则支持多种HTTP请求方法。
无论是简单请求,还是需要先进行探测的请求,前端的写法都是不变的,额外的处理都是在服务器端来完成的。 在传统的Java EE开发中,可以通过过滤器统一配置,而Spring Boot中对此则提供了更加简洁的解决方案。
后期更新
SpringBoot推荐使用Java来完成相关的配置工作。在项目中,不建议将所有的配置放在一个配置类中,可以根据不同的请求提供不同的配置类。
这些配置类都需要添加@Configuration注解
@ComponentScan注解会扫描所有的Spring组件,也包括@Configruation。
@ComponentScan在项目入中的@SpringBootApplication注解中已经提供,因此在实际项目中只需要按需提供相关的配置类即可。
暂不研究
暂不研究
一般情况下,使用Spring、SpringMVC这些框架之后,基本上就告别Servlet,Filter以及Listener了,但是有时在整合一些第三方框架时,可能还是不得不使用Servlet。比如在整合某报表插件时,就需要使用Servlet。SpringBoot对于整合这些基本的Web组件也提供了良好的支持。
一般情况下,使用了页面模板之后,用户需要通过控制器才能访问页面。有一些页面只需要在控制中加载数据,然后渲染,才能显示出来;还有一些页面在控制器中不需要加载数据,只是完成简单的跳转,对于这种页面,可以直接配置路径映射,提高访问速度。
例如,有两个Thymeleaf做模板的页面login.html和index.html,可以直接在MVC配置中重写addViewControllers方法配置映射关系即可。
@Configuration
public class WebMvcConfig implements WebMvcConfigurer{
@override
public void addViewControllers(ViewControllerRegistry registry)
{
registry.addViewController("/login").setViewName("login");
registry.addViewController("/index).setViewName("index");
}
}
配置完成后,就可以直接访问http://localhost:8080/login等地址了。
AOP(Aspect-Oriented Programming,AOP)面向切面编程。需要读者首先考虑这样一个场景:公司有一个人力资源管理系统目前已经上线,但是系统运行不稳定,有时运行的慢,为了检测出到底是哪个环节出问题了,开发人员想要监控每一个方法的执行时间,再根据这些执行时间判断出问题所在。当问题解决后,再把这些监控移除掉。系统目前已经运行,如果手动修改系统中成千上万个方法,那么工作量未免太大,而且这些监控方法以后还有移除掉;如果能够在系统运行过程中动态添加代码,就能很好地解决这个需求。
这种在系统运行时动态添加代码的方式称为面向切面编程(AOP)
Spring框架对AOP提供了很好的支持。
细节暂不研究
Springboot项目在启动之后,首先会去静态资源路径下查找index.html作为首页文件。若查找不到,则会去查找动态的index文件作为首页文件。
例如:
@RequestMappin("/index")
public String hello()
{
return "index";
}
favicon.ico是浏览器选项卡左上角的图标,可以放在静态资源路径下或者类路径下,静态资源下路径下的favicon.ico优先级高于类路径下的favicon.ico.
可以使用在线转换网站https://jinaconvert.com/cn/convert-to-ico.php将一张普通图片转为.ico图片,转换陈宫后,将文件重命名为favicon.ico,然后复制到resources/static目录下。
暂不研究
持久层是Java EE中访问数据库的核心操作,SpringBoot中对常见的持久层框架都提供了自动化配置,例如JdbcTemplate,JPA等,MyBatis的自动化配置则是MyBatis官方提供的。接下来分别向读者介绍SpringBoot整合这几种持久层技术。
JdbcTemplate是Spring提供的一套JDBC模板框架,利用AOP技术来解决直接使用JDBC时大量重复代码的问题。JdbcTemplate虽然没有MyBatis那么灵活,但是比直接使用JDBC要方便很多。
MyBatis是一款优秀的持久层框架,原名叫做iBatis.
MyBatis支持定制化SQL、存储过程以及高级映射。MyBatis几乎避免了所有的JDBC代码手动设置参数以及获取结果集。在传统的SSM框架整合中,使用MyBatis需要大量的XML配置,而在SpringBoot中,MyBatis官方提供了一套自动化配置方案,可以做到MyBatis开箱即用。
create database 'chapter05' DEFAULT CHARACTER SET utf8;
USE 'chapter05'
CREATE TABLE 'book'
(
'id' int(11) NOT NULL AUTO_INCREMENT,
'name' varchar(128) DEFAULT NULL,
'author' varchar(64) DEFAULT NULL,
'PRIMARY KEY('id')
)ENGINE = InnoDB DEFAULT CHARSET = utf8;
insert into 'book'('id','name','author') values(1,'三国演义','罗贯中'),(2,'水浒传','施耐庵');
创建chapter05数据库,在库中创建book表,同时添加两条测试语句。
创建Spring Boot项目,添加MyBatis依赖,数据局驱动依赖以及数据库连接池依赖,依赖如下:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>1.3.2version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.1.9version>
dependency>
在application.properties中配置数据库基本连接信息:
spring.datasource.type = com.alibaba.druid.pool.DruidDataSource
spring.datasource.url = jdbc:mysql:///chapter05
spring.datasource.username = root
spring.datasource.password = 123
public class Book{
private Integer id;
private String name;
private String author;
//省略getter/setter
}
BookMapper
@Mapper
public interface BookMapper{
int addBook(Book book);
int deleteBookById(Integer Id);
int updateBookById(Book book);
Book getBookById();
List<Book> getAllBooksI();
}
JPA(Java Persistence API)和Spring Data是两个范畴的概念。
作为一名Java EE工程师。
暂不研究
暂不研究
暂不研究
REST(Representational State Transfer)是一种Web软件架构风格,它是一种风格,而不是标准,匹配或者兼容这种架构风格的网络服务称为Rest服务。
在前后端分离项目中,一个设计良好的Web软件架构必然要满足REST风格。
在SpringMVC框架中,开发者可以通过**@RestController**注解开发一个RestFul服务,不过SpringBoot对此提供了自动化配置方案,开发者只需要添加相关依赖就能快速构建一个RestFul服务。
Spring 3.1中开始对缓存提供支持,核心思路是对方法的支持,当开发者调用一个方法时,将方法的参数和返回值作为key/value缓存起来,当再次调用该方法时,如果缓存中有数据,就直接从缓冲中后去,否则再去执行该方法。但是Spring中并未提供缓存的实现,而是提供了一套缓存API,开发者可以自由选择缓存的实现,目前SpringBoot支持的缓存有以下几种:
Jache
EhCache
Hazelcast
Infinispan
Couchbase..
目前最常用的是Ehcache2.x和Redix。 由于Spring早已经将缓存领域统一,因此不论是用哪种缓存实现,不同的只是缓存配置,开发者使用的缓存注解是一致的(Spring缓存注解和各种缓存的实现的关系就像JDBC和各种数据库驱动的关系一样)
在HTTP协议中,所有的请求都是由客户端发起的,由服务端进行响应,服务器端无法向客户端推送消息,但是在一些需要即时通信的应用中,又不可避免地需要服务器端向客户端推送消息,传统的解决方案主要有以下几种。
传统的暂不研究
WebSocket是一种在单个TCP连接上进行全双工通信的协议,已经被W3C定位标准。使用WebSocket可以使得客户端和服务器之间的数据交换变得更加简单,它允许服务端主动向客户端推送数据。
在WebSocket协议中,浏览器和服务器只需要完成一次握手,两者之间就可以直接创建持久性的连接,并进行双向数据传输。
WebSocket有很多优势。
WebSocket的使用场景非常广泛。
例如:在线聊天网站,即时聊天,多人在线游戏,应用集群通信,系统性能实时监控。
本章主要想读者介绍了SpringBoot整合WebSocket,整体来说,经过SpringBoot自动化配置之后的WebSocket使用起来是非常方便的。通过@MessageMapping注解配置消息接口,通过@SendTo或者SimpMessagingTemplate进行消息转发,通过简单的几行配置,就能实现点对点、点对面的消息发送。在企业信息管理系统中,一般即时通信、通告发布等功能时都会用到WebSocket.
消息队列(Message Queue)是一种进程间或者线程间的异步通信方式,使用消息队列,消息生产者在产生消息后,会将消息保存在消息队列中,直到消息消费者来取走它,即消息的发送者和接收者不需要同时与消息队列交互。使用消息队列可以有效实现服务解耦,并提高系统的可靠性以及可扩展性。
目前,开源的消息队列非常多,如Apache ActiveMQ,RabbitMQ等,这些产品就是常说的消息中间件。
邮件发送是一个非常常见的功能,注册时的身份认证、重要通知发送等都会用到邮件发送。
Sun公司提供了JavaMail用来实现邮件发送,但是配置繁琐,
Spring中提供了JavaMailSender用来简化邮件配置,
SpringBoot则提供了MailSenderAutoConfiguration对邮件的发送做了进一步的简化。
定时任务是企业级开发中最常见的功能之一,如定时统计订单数,数据库备份,定时发送短信和邮件,定时统计博客访问等,简单的定时任务可以直接通过Spring中的@Scheduled注解来实现,复杂的定时任务则可以通过集成Quartz来实现,分别进行介绍。
在前后端分离开发中,为了减少与其他团队的沟通成本,一般构建一份RESTful API文档来描述所有的接口信息,但是这种做法弊端很大。不好用!
Swagger 2是一个开源软件框架,可以帮助开发人员设计、构建、记录和使用REStful Web服务,它将代码和文档融为一体,可以完美地解决上面描述的问题,使得开发人员将大部分精力集中到业务中,而不是繁杂琐碎的文档中。
Swagger2可以非常轻松地整合到SpringBoot项目中。
数据校验是开发过程中国一个常见的环节,一般来说,为了提高系统运行效率,都会在前端进行数据校验,但是这并不意味着不必在后端做数据校验了,因为用户还是可能在获取数据接口后手动传入非法数据,所以后端还是需要做数据校验。SpringBoot对此也提供了相关的自动化配置解决方案。
当一个SpringBoot项目运行时,开发者需要对SpringBoot项目进行实时监控,获取项目的运行情况,在项目出错时能够实现自动报警等。SpringBoot提供了actuator来帮助开发者获取应用程序的实时运行数据。开发者可以选择使用HTTP端点或者JMX来管理和监控应用程序,获取应用程序的运行数据,包括健康状况、应用信息、内存使用情况等。
暂不研究
SpringBoot项目可以内嵌Servlet容器,因此它的部署变得极为方便,可以直接打成可执行JAR包部署在有Java运行环境的服务器上,也可以像传统的JavaWeb应用程序那样打成WAR包运行。
使用Spring-boot-maven-plugin插件可以创建一个可执行的JAR应用程序,前提是应用程序的parent为spring-boot-starter-parent.配置方式如下。
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
要将Spring Boot项目打包成可执行JAR,一般需要一些配置文件,例如application.properties或者application.yml等,但是如果将SpringBoot项目打包成一个可以依赖JAR,这些配置文件很多时候又不需要,此时可以在打包时排除配置文件。
在一些特殊情况下,需要开发者将Spring Boot项目打成WAR包,然后使用传统的方式部署。
人事管理系统是一种常见的企业后台管理系统。
本项目采用当下流行的前后端分离的方式开发,后端使用spring Boot开发,前端使用Vue + ElementUI来构建SPA。
SPA是指Single-Page Application,即单页面应用。SPA应用通过动态重写当前页面来与用户交互,而非传统的从服务器重新加载整个新页面。这种方法避免了页面之间切换打断用户体验,使得应用程序更像一个桌面应用程序。
在SPA中,所有的HTML,javascript,和css都通过单个页面的加载来检索,或者根据用户操作动态装载适当的资源并添加到页面。
在SPA中,前端将通过Ajax与后端通信。
对于开发者而言,SPA最直观的感受就是项目开发完成后,只有一个HTML页面,所有页面的跳转都通过路由导航。
前后端分离的另一个好处是一个后端可以对应多个前端,由于后端只负责提供数据,前后端的交互都是通过Json数据完成的,因此后端开发成功之后,前端可以是PC端页面,也可以是Android,Ios以及微信小程序等。
强烈建议初学者看官方文档学习vue
https://cn.vuejs.org/v2/guide
Vue桌面端组件库非常多,比较流程的有Element等。
本项目采用Element作为前端页面组件库。Element在Github上的star数已达29000,接近30000,出了问题容易找到解决方案。
强烈建议通过官方文档学习:
http://element-cn.eleme.io/#/zh-CN/component
除了前端技术点外,后端用到的技术主要就是第1-15章提到的技术,这里即不详细展开了。
Vue项目使用webpack来构建。首先确保本地已经安装了NodeJS,。。。
后端使用SpringBoot创建一个SpringBoot工程,添加Spring-boot-starter-web依赖即可。
最后,由于前端项目和后端项目在不同的端口下启动,前端的网络请求无法直接发送到后端,因此需要配置请求转发。
后端返回了菜单数据,前端请求该接口获取菜单数据,这里的步骤很简单,主要分两步
完成登录模块和菜单加载模块之后,一个前后端分离的项目框架基本上就搭建成功了。接下来是业务的开发,主要是后端提供接口,前端提供页面并请求数据。
员工基本资料数据的展示,后端只需要提供一个分页查询+条件查询的接口即可。
确认后端接口可以调通之后,接下来就可以开发前端页面了。
将员工资料导出为EXcel是一个非常常见的需求,后端提供导出接口,前端下载导出数据即可。
既然有员工资料导出需求,当然也有导入需求。
对前端而言,员工资料导入就是文件上传。
对后端而言,则是获取上传的文件进行解析,并将解析出来的数据保存到数据库中。
后端主要是获取前端上传文件的流,然后进行解析。
前端主要是一个Excel表格的上传,这里直接采用Element的文件上传控件。
在线聊天是一个为了方便HR进行快速沟通提高工作效率而开发的功能,考虑到一个公司中的HR并不多,并发量并不大,因此这里直接使用最基本的WebSocker来完成该功能。
当前端项目开发完成之后,执行如下命令对项目进行打包
npm run build
打包完成之后,在当前工作目录下生成一个dist文件夹
OK!