本文主要介绍SpringBoot
本文较长,分为 上中下 三篇(可收藏,勿吃尘)
如有需要,可以参考
如有帮助,不忘 点赞 ❥
相关文章:
文章目录
一、前期预热
官方:Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”.
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 Boot,可以轻松地创建独立的,基于生产级别的基于Spring的应用程序,您可以“运行”它们。
我们对Spring平台和第三方库持固执己见的观点,因此您可以以最小的麻烦开始使用。大多数Spring Boot应用程序需要最少的Spring配置。
1)背景
J2EE笨重的开发、繁多的配置、低下的开发效率、复杂的部署流程、第三方技术集成难度大。
2)优点
快速创建独立运行的Spring项目以及与主流框架集成
使用嵌入式的Servlet容器,应用无需打成WAR包
starters自动依赖与版本控制
大量的自动配置,简化开发,也可修改默认值
无需配置XML,无代码生成,开箱即用
准生产环境的运行时应用监控
与云计算的天然集成
二、正文接入
1) 配置嵌入式Servlet容器
1、定制和修改Servlet容器的相关配置
法1:修改和server有关的配置
server.tomcat.uri-encoding=UTF-8
//通用的Servlet容器设置
server.xxx
//Tomcat的设置
server.tomcat.xxx
法2:编写一个EmbeddedServletContainerCustomizer:嵌入式的Servlet容器的定制器;来修改Servlet容器的配置
2、注册Servlet三大组件
- Servlet
- Filter
- Listener
由于SpringBoot默认是以jar包的方式启动嵌入式的Servlet容器来启动SpringBoot的web应用,所以没有web.xml文件。
注册三大组件用以下方式
ServletRegistrationBean
FilterRegistrationBean
ServletListenerRegistrationBean
3、替换为其他嵌入式Servlet容器
默认支持以下容器
- Tomcat
<!-- 引入web模块默认就是使用嵌入式的Tomcat作为Servlet容器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
- Jetty
<!-- 先排除内置默认容器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<!--引入其他的Servlet容器-->
<dependency>
<artifactId>spring-boot-starter-jetty</artifactId>
<groupId>org.springframework.boot</groupId>
</dependency>
- Undertow
<!-- 先排除内置默认容器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<!--引入其他的Servlet容器-->
<dependency>
<artifactId>spring-boot-starter-undertow</artifactId>
<groupId>org.springframework.boot</groupId>
</dependency>
4、嵌入式Servlet容器自动配置原理
EmbeddedServletContainerAutoConfiguration
- EmbeddedServletContainerFactory(嵌入式Servlet容器工厂)
public interface EmbeddedServletContainerFactory { //获取嵌入式的Servlet容器 EmbeddedServletContainer getEmbeddedServletContainer( ServletContextInitializer... initializers); } }
- EmbeddedServletContainer:(嵌入式的Servlet容器)
- 以TomcatEmbeddedServletContainerFactory为例
- 嵌入式容器的配置修改怎么生效
- 方法1: ServerProperties
- 方法2: EmbeddedServletContainerCustomizer :定制器帮我们修改了Servlet容器的配置
修改原理:
容器中导入了EmbeddedServletContainerCustomizerBeanPostProcessor
ServerProperties也是定制器
- SpringBoot根据导入的依赖情况,给容器中添加相应的EmbeddedServletContainerFactory【TomcatEmbeddedServletContainerFactory】
- 容器中某个组件要创建对象就会惊动后置处理器:EmbeddedServletContainerCustomizerBeanPostProcessor(只要是嵌入式的Servlet容器工厂,后置处理器就工作)
- 后置处理器,从容器中获取所有的EmbeddedServletContainerCustomizer,调用定制器的定制方法
5、使用外置的Servlet容器
嵌入式Servlet容器:应用打成可执行的jar
优点: 简单、便携;
缺点: 默认不支持JSP、优化定制比较复杂
相关文章
步骤:
- 创建一个war项目
- 将嵌入式的Tomcat指定为provided
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency>
- 编写一个SpringBootServletInitializer的子类,并调用configure方法
public class ServletInitializer extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { //传入SpringBoot应用的主程序 return application.sources(SpringBoot04WebJspApplication.class); } }
- 启动服务器就可以使用
原理:
- jar包:执行SpringBoot主类的main方法,启动ioc容器,创建嵌入式的Servlet容器
- war包:启动服务器,服务器启动SpringBoot应用SpringBootServletInitializer,启动ioc容器
2) 数据访问
对于数据访问层,无论是SQL还是NOSQL,Spring Boot默认采用整合Spring Data的方式进行统一处理,添加大量自动配置,屏蔽了很多设置。引入 各种xxxTemplate,xxxRepository来简化我们对数据访问层的操作。对我们来说只需要进行简单的设置即可。
1、整合基本JDBC与数据源
- 引入starter : spring-boot-starter-jdbc
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
- 配置application.yml
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://192.168.15.22:3306/test
driver-class-name: com.mysql.jdbc.Driver
结论:
- 默认使用org.apache.tomcat.jdbc.pool.DataSource作为数据源
- 数据源的相关配置都在DataSourceProperties里面
自动配置原理:
-
参考DataSourceConfiguration,根据配置创建数据源,默认使用Tomcat连接池;可以使用spring.datasource.type指定自定义的数据源类型
-
SpringBoot默认可以支持:
- org.apache.tomcat.jdbc.pool.DataSource
- HikariDataSource
- BasicDataSource
-
自定义数据源类型
@ConditionalOnMissingBean(DataSource.class) @ConditionalOnProperty(name = "spring.datasource.type") static class Generic { @Bean public DataSource dataSource(DataSourceProperties properties) { //使用DataSourceBuilder创建数据源,利用反射创建响应type的数据源,并且绑定相关属性 return properties.initializeDataSourceBuilder().build(); } }
-
DataSourceInitializer:ApplicationListener
作用:- runSchemaScripts();运行建表语句
- runDataScripts();运行插入数据的sql语句
默认只需要将文件命名为:
schema-.sql、data-.sql
默认规则:schema.sql,schema-all.sql;
可以使用
schema: - classpath:department.sql
指定位置 -
操作数据库:自动配置了JdbcTemplate操作数据库
2、整合Druid数据源
- 引入druid数据源
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.8</version>
</dependency>
- 配置文件
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://192.168.15.22:3306/jdbc
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
- 配置数据源
@Configuration
public class DruidConfig {
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource druid(){
return new DruidDataSource();
}
//配置Druid的监控
//1、配置一个管理后台的Servlet
@Bean
public ServletRegistrationBean statViewServlet(){
ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
Map<String,String> initParams = new HashMap<>();
initParams.put("loginUsername","admin");
initParams.put("loginPassword","123456");
initParams.put("allow","");//默认就是允许所有访问
initParams.put("deny","192.168.15.21");
bean.setInitParameters(initParams);
return bean;
}
//2、配置一个web监控的filter
@Bean
public FilterRegistrationBean webStatFilter(){
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new WebStatFilter());
Map<String,String> initParams = new HashMap<>();
initParams.put("exclusions","*.js,*.css,/druid/*");
bean.setInitParameters(initParams);
bean.setUrlPatterns(Arrays.asList("/*"));
return bean;
}
}
3、整合MyBatis
- 引入依赖:
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
步骤:
1)配置数据源相关属性
2)给数据库建表
3)创建JavaBean
4)注解使用
自定义MyBatis的配置规则:
- 在容器中添加一个ConfigurationCustomizer
- 在启动类中添加MapperScan注解批量扫描所有的Mapper接口
5)配置文件使用
mybatis:
#指定全局配置文件的位置
config-location: classpath:mybatis/mybatis-config.xml
#指定sql映射文件的位置
mapper-locations: classpath:mybatis/mapper/*.xml
4、整合SpringData JPA
相关文章
SpringData简介
Spring Data是一个用于简化数据库访问,并支持云服务的开源框架。其主要目标是使得对数据的访问变得方便快捷。
可以极大的简化JPA的写法,可以在几乎不用写实现的情况下,实现对数据的访问和操作。除了CRUD外,还包括如分页、排序等一些常用的功能。
SpringData整合
- 编写一个实体类(bean)和数据表进行映射,并且配置好映射关系
- 编写一个Dao接口来操作实体类对应的数据表(Repository)
- 配置JpaProperties
spring:
jpa:
hibernate:
#更新或者创建数据表结构
ddl-auto: update
#控制台显示SQL
show-sql: true
5、启动配置原理
相关文章
6、事件监听机制
以下是配置在META-INF/spring.factories
- ApplicationContextInitializer
- SpringApplicationRunListener
以上两个需要配置在(META-INF/spring.factories)
org.springframework.context.ApplicationContextInitializer=\
com.atguigu.springboot.listener.HelloApplicationContextInitializer
org.springframework.boot.SpringApplicationRunListener=\
com.atguigu.springboot.listener.HelloSpringApplicationRunListener
以下两个只需要放在ioc容器中
- ApplicationRunner
- CommandLineRunner
3) 自定义starter
自动装配使用配置类(@Configuration)结合Spring4 提供的条件判断注解:
- @Conditional
- Spring Boot的派生注解如 @ConditionOnClass 完成;
将标注@Configuration的自动配置类,放在classpath下 META- INF/spring.factories 文件中
在特定自动装配Class之前 :@AutoConfigureBefore
在特定自动装配Class之后 :@AutoConfigureAfter
指定顺序 :@AutoConfigureOrder
启动器模块是一个空 JAR 文件,仅提供辅助性依赖管理,这些依赖可能用于自动装配或者其他类库
命名规约:
官方命名空间:
- 前缀:“spring-boot-starter-”
- 模式:spring-boot-starter-模块名
- 例子:spring-boot-starter-web、spring-boot-starter-actuator、spring-boot-starter-jdbc
自定义命名空间:
- 后缀:“-spring-boot-starter”
- 模式:模块-spring-boot-starter
- 举例:mybatis-spring-boot-starter
编写自动配置
@Configuration //指定这个类是一个配置类
@ConditionalOnXXX //在指定条件成立的情况下自动配置类生效
@AutoConfigureAfter //指定自动配置类的顺序
@Bean //给容器中添加组件
@ConfigurationPropertie //结合相关xxxProperties类来绑定相关的配置
@EnableConfigurationProperties //让xxxProperties生效加入到容器中
自动配置类要能加载,将需要启动就加载的自动配置类,配置在META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
模式:
- 启动器只用来做依赖导入
- 可以专门来写一个自动配置模块
- 启动器依赖自动配置;别人只需要引入启动器(starter)
启动器模块:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cbuc.life.starter</groupId>
<artifactId>cbuc-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
<!--启动器-->
<dependencies>
<!--引入自动配置模块-->
<dependency>
<groupId>cbuc.life.starter</groupId>
<artifactId>cbuc-spring-boot-starter-autoconfigurer</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
自动配置模块:
- 步骤1:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cbuc.life.starter</groupId>
<artifactId>cbuc-spring-boot-starter-autoconfigurer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--引入spring-boot-starter;所有starter的基本配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>
- 步骤2:
@ConfigurationProperties(prefix = "cbuc.hello")
public class HelloProperties {
private String prefix;
private String suffix;
//省略get/set方法
}
- 步骤3:
public class HelloService {
HelloProperties helloProperties;
public HelloProperties getHelloProperties() {
return helloProperties;
}
public void setHelloProperties(HelloProperties helloProperties) {
this.helloProperties = helloProperties;
}
public String sayHellAtguigu(String name){
return helloProperties.getPrefix()+"-" +name + helloProperties.getSuffix();
}
}
- 步骤4:
@Configuration
@ConditionalOnWebApplication //web应用才生效
@EnableConfigurationProperties(HelloProperties.class)
public class HelloServiceAutoConfiguration {
@Autowired
HelloProperties helloProperties;
@Bean
public HelloService helloService(){
HelloService service = new HelloService();
service.setHelloProperties(helloProperties);
return service;
}
}