SpringBoot1.x与2.x区别
Spring Boot依赖于Spring,而Spring Cloud又依赖于Spring Boot,因此Spring Boot2.0的发布正式整合了Spring5.0的很多特性,同样后面Spring Cloud最新版本的发布也需要整合最新的Spring Boot2.0内容。
SpringBoot2新特性
-
基于 Java 8,支持 Java 9
也就是说Spring Boot2.0的最低版本要求为JDK8 -
响应式编程
使用 Spring WebFlux/WebFlux.fn提供响应式 Web 编程支持, Webflux 是一个全新的非堵塞的函数式 Reactive Web 框架,可以用来构建异步的、非堵塞的、事件驱动的服务,在伸缩性方面表现非常好,此功能来源于Spring5.0。Spring Boot2.0也提供对响应式编程的自动化配置,如:Reactive Spring Data、Reactive Spring Security 等 -
HTTP/2支持
在Tomcat, Undertow 和 Jetty 中均已支持 HTTP/2 -
对Kotlin支持
引入对 Kotlin 1.2.x 的支持,并提供了一个 runApplication 函数,让你通过惯用的 Kotlin 来运行 Spring Boot 应用程序。 -
全新的执行器架构
全新的执行器架构,支持 Spring MVC, WebFlux 和 Jersey -
支持 Quartz
Spring Boot1.0并没有提供对 Quartz 的支持,之前出现了各种集成方案,Spring Boot2.0给出了最简单的集成方式。 -
Security
大大的简化了安全自动配置 -
Metrics
Metrics 方面,Spring Boot 2引入了Micrometer,来统一metrics的规范,使得开发人员更好的理解和使用metrics的模块,而不需要关心对接的具体存储是什么。 -
监控方面
Spring Boot 2 增强了对 Micrometer 的集成。RabbitMQ、JVM 线程和垃圾收集指标会自动进行 instrument 监控,异步控制器(controller)也会自动添加到监控里。通过集成,还可以对 InfluxDB 服务器进行监控。 -
数据方面
db方面,默认引入了HikariCP,替代了之前的tomcat-pool作为底层的数据库连接池, 对比于tomcat-pool, HikariCP拥有更好的性能,总而言之就是提高了db的访问速度,JOOQ的支持,Redis方面, 默认引入了Lettuce, 替代了之前的jedis作为底层的redis链接方式MongoDB\Hibernate优化 -
Thymeleaf3
Spring Boot 2支持了Thymeleaf 3,Thymeleaf 3相对于Thymeleaf 2性能提升可不是一点点,因为2.0的性能确实不咋地,同时也使用了新的页面解析系统。 -
OAuth 2.0
同时也加入了 对于OAuth 2.0的支持, 使得开发人员更加友好的使用spring-security来完成权限模块的开发
设计理念
完全采用注解形式
核心理念
- 能够帮助开发者实现快速整合第三方框架 (原理:Maven依赖封装,starter)
- 去除xml配置 完全采用注解化 (原理:Spring体系中内置注解方式)
- 无需外部Tomcat、内部实现服务器(原理:Java语言支持创建Tomcat服务器,然后将本地的class文件交给tomcat加载)
我们先来了解内置的tomcat服务器怎么去手写吧。(SpringMVC+Tomcat注解启动)
我们先创建一个SpringBoot项目,找到其中的spring-boot-starter-web的maven依赖,我们点击进去可以查看到
这里面有一个关于tomcat的starter。我们看看内部引入了什么配置
里面会有这么一个核心包。那么我们也引入这个核心包,即可。
在手动启动tomcat之前,我们需要先配置注解形式启动MVC,在SpringMVC源码分析------基础知识(二)提到过,这里就不再复述了。直接上代码。
SpringMVC+Tomcat注解启动项目代码:SpringMVC_Tomcat
SpringMVCConfig.java
package com.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
/**
* @author 龙小虬
* @date 2021/3/20 17:31
*/
@Configuration
@EnableWebMvc
@ComponentScan("com.controller")
public class SpringMVCConfig {
}
MyWebApplicationInitializer.java
package com.initializer;
import com.config.SpringMVCConfig;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
/**
* @author 龙小虬
* @date 2021/3/20 17:34
*/
public class MyWebApplicationInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext annotationConfigWebApplicationContext = new AnnotationConfigWebApplicationContext();
annotationConfigWebApplicationContext.register(SpringMVCConfig.class);
DispatcherServlet dispatcherServlet = new DispatcherServlet(annotationConfigWebApplicationContext);
ServletRegistration.Dynamic dynamic = servletContext.addServlet("dispatcherServlet", dispatcherServlet);
dynamic.addMapping("/");
dynamic.setLoadOnStartup(1);
}
再自己写一个controller用于访问
MyController.java
package com.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author 龙小虬
* @date 2021/3/20 17:44
*/
@RestController
public class MyController {
@RequestMapping("/test")
public String test(){
return "tesat";
}
}
现在我们开始配置tomcat
创建Application.java并写入main函数
package com;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.WebResourceRoot;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.webresources.DirResourceSet;
import org.apache.catalina.webresources.StandardRoot;
import java.io.File;
/**
* @author 龙小虬
* @date 2021/3/20 18:20
*/
public class Application {
public static void main(String[] args) throws Exception {
//创建Tomcat服务器
Tomcat tomcatServer = new Tomcat();
//指定端口号
tomcatServer.setPort(8080);
//读取项目路径
StandardContext ctx = (StandardContext) tomcatServer.addWebapp("/", new File("src/main").getAbsolutePath());
//禁止重新载入
ctx.setReloadable(false);
//class文件读取地址
File additionWebInfClasses = new File("target/classes");
//创建webroot
WebResourceRoot resources = new StandardRoot(ctx);
//tomcat内部读取class执行
resources.addPreResources(new DirResourceSet(resources, "/target/classes", additionWebInfClasses.getAbsolutePath(), "/"));
tomcatServer.start();
//异步等待请求执行
tomcatServer.getServer().await();
}
}
注释全在上面,我们只需要了解即可。
运行,会发现如下报错
大概的意思就是没有支持jsp,那我们直接在pom中加入配置
<!-- Tomcat对jsp支持 -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper</artifactId>
<version>8.5.16</version>
</dependency>
再次运行即可。
可以看到这个文件夹,就是tomcat的运行数据。
好了,我们了解了怎么springboot内置tomcat的方法,我们再来了解一下,是怎么快速整合第三方框架,也就是自定义starter。
在自定义starter之前,说一下starter自定义的规则,在命名规范中spring-boot-starter-XXX,为SpringBoot官方定义的starter,若XXX-spring-boot-starter就是第三方定义的starter,非官方的。比如mybatis的starte
现在我们来自己定义一个token-redis-spring-boot-starter
项目地址:token-redis-spring-boot-starter
创建SpringBoot项目。并引入pom配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
创建TokenProperties.java
package com.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author 龙小虬
* @date 2021/3/20 18:32
*/
@ConfigurationProperties(prefix = "lxq")
public class TokenProperties {
private String host;
private String pwd;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
@Override
public String toString() {
return "TokenProperties{" +
"host='" + host + '\'' +
", pwd='" + pwd + '\'' +
'}';
}
}
TokenService.java
package com.service;
import com.properties.TokenProperties;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @author 龙小虬
* @date 2021/3/20 18:36
*/
public class TokenService {
@Autowired
TokenProperties tokenProperties;
public String getToken(){
return "result:" + tokenProperties.toString();
}
}
TokenAutoConfiguration.java
package com.config;
import com.properties.TokenProperties;
import com.service.TokenService;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author 龙小虬
* @date 2021/3/20 18:34
*/
@EnableConfigurationProperties(TokenProperties.class)
@Configuration
public class TokenAutoConfiguration {
@Bean
public TokenService tokenService(){
return new TokenService();
}
}
写完之后会发现
有这样一个警告。他的大概意思就是没有找到processor,而这个processor是用于在application.yml中的提示作用。我们引入这个配置
<!-- 能够给开发者引入该jar包后 有一定提示 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
他的作用也就类似于
这种提示。
解决完这个提示,我们还需要配置一个EnableAutoConfiguration,
加入数据org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.config.TokenAutoConfiguration
基于这里我们就写完了自定义starter。
命令窗口到本项目下,运行命令mvn clean install
假如提示找不到mvn这个命令,我们就得找到自己的maven文件夹,配置全局变量,path环境变量中配置maven的bin目录,如
即可解决。
现在我们就可以直接引入
创建新项目。引入即可使用。
SpringBoot启动初步了解
我们使用SpringBoot的时候,都会使用到@SpringBootApplication
这个注解。进去可以看到
我们看看@SpringBootConfiguration
没有看到什么特殊的,就有一个@Configuration
,为什么要在@SpringBootConfiguration
中包装呢?
其实只是为了方便在main加入第三方jar包,并且好进行管理。