SpringBoot介绍
SpringBoot,本质上就是Spring,SpringBoot是在Spring的基础上发展而来了,解决了Spring的配置繁琐性
约定大于配置
约定大于配置:提供一些默认值,如果没有指定,则采用默认值;如果指定了,则以指定的为准。
做了大量的默认配置,做了非常繁琐的默认配置。默认配置主要是默认的组件。
SpringBoot应用还有其他的特点
启动SpringBoot速度很快
内置了tomcat,以Jar包的方式启动 java -jar xxx.jar(main方法)
服务器里不需要安装tomcat,只需要有jdk
构建SpringBoot应用
官网start.spring.io
.mvn、mvnw、mvnw.cmd都是maven的相关文件,避免你的环境没有装maven
.gitignore是git的配置文件 → 用来做忽略管理
IDEA直接创建
其实就是在IDEA中选择一些配置项,然后从start.spring.io下载压缩包,然后呢解压到指定目录
pom.xml
maven工程
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<!--版本号-->
<!--<version>2.6.2</version>-->
<version>2.1.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
当前版本的SpringBoot中的JUnit和之前版本的JUnit不通过,如果修改SpringBoot的版本号,要同时修改引入的JUnit
import org.junit.Test;//修改引用
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class Demo2ApplicationTests {
@Test
void contextLoads() {
}
}
在创建项目的时候选择的依赖会被引入到dependencies标签里
<!--如果没有引入web,还会有一个spring-boot-starter-->
<!--引入的web的同时,也引入了spring-boot-starter依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
SpringBoot应用中的依赖
有些的依赖没有写版本号,这些版本号是从父工程中引入的
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.5.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
父工程还有一个父工程
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.5.RELEASE</version>
有一些依赖没有写版本号仍然也可以引入对应的默认版本,这就是约定大于配置
starter依赖的特点
spring-boot-starter-xxx 官方
xxx-spring-boot-starter 第三方
通常使用一个框架的话,我们只需要引入这个框架的starter依赖,我们就可以以一个极低的成本使用该框架
- 引入该框架所必须的依赖
- 引入autoconfigure依赖,约定大于配置的内容都是在这个依赖中
***自动配置的原理
JavaConfig
是因为给我们提供了大量的自动配置类
→ 找autoconfigure依赖 → /META-INF/spring.factories
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
TransactionManagerAutoConfiguration
自动配置的生效是有条件
@ConditionalOnXXX → 有XXX的时候生效
@ConditionalOnMissingXXX → 没有xxx的时候生效
@Configuration(
proxyBeanMethods = false
)
//有对应的类的时候生效 → 引入依赖
@ConditionalOnClass({JdbcTemplate.class, TransactionManager.class})
//自动配置的顺序,通常可有可无
@AutoConfigureOrder(2147483647)
//引入参数类中的值
@EnableConfigurationProperties({DataSourceProperties.class})
public class DataSourceTransactionManagerAutoConfiguration {
@Configuration(
proxyBeanMethods = false
)
//容器中只有一个这个类型的组件的时候生效
@ConditionalOnSingleCandidate(DataSource.class)
static class JdbcTransactionManagerConfiguration {
//如果@Bean生效,会向容器中注册一个DataSourceTransactionManager组件
@Bean
//如果容器中没有这个组件的时候生效
@ConditionalOnMissingBean({TransactionManager.class})
DataSourceTransactionManager transactionManager(Environment environment, DataSource dataSource, ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
DataSourceTransactionManager transactionManager = this.createTransactionManager(environment, dataSource);
transactionManagerCustomizers.ifAvailable((customizers) -> {
customizers.customize(transactionManager);
});
return transactionManager;
}
}
}
@ConditionalOnMissingBean就是约定大于配置,如果有自己注册的这个组件,那默认的就不生效,按照自己配置的来。
配置文件
能够为自动配置类提供参数
配置文件的名称
application(-xxx).properties
application(-xxx).y(a)ml
放在resources目录下就会自动读取
tomcat相关相关配置
端口号:server.port
context-path:server.servlet.context-path
Tomcat started on port(s): 8090 (http) with context path ‘/demo2’
# 表达的是key=value
server.port=8090
server.servlet.context-path=/demo2
yml语法
表达的也是key=value,只不过和properties配置文件的语法上有一点点区别
点 → 冒号、换行、空格缩进
等于 → 冒号、空格
相同前缀可以复用
缩进的话缩进几个都可以,同一级要对齐
#server.port=8082
#server.servlet.context-path=/demo3
server:
port: 8082
servlet:
context-path: /demo3
缩进必须要用空格,不能用tab键!
容器中的组件获得配置文件中的值
组件注册的扫描包
启动类所在的包目录
方式一 @Value
通过该注解引入SpringBoot配置文件中的key所对应的value
@RestController
public class FileController {
@Value("${file.path}")
String path;
}
file:
path: d:/spring/
不足的地方:主要是用起来比较繁琐
@Value("${druid.datasource.driver}")
String className;
@Value("${druid.datasource.url}")
String url;
@Value("${druid.datasource.username}")
String username;
@Value("${druid.datasource.password}")
String password;
@Bean
public DruidDataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(className);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
方式二 @ConfigurationProperties
建立组件中的成员变量和配置文件中的key的对应关系
prefix属性值 + 成员变量名(set方法) = 配置文件中的key
@Configuration
@Data //用到了set方法
@ConfigurationProperties(prefix = "druid.datasource")
public class DruidDataSourceConfiguration {
String driver;
String url;
String username;
String password;
@Bean
public DruidDataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
方式三 中间状态
/**
* 注册一个DruidDataSource 3.0
* @author stone
* @date 2022年1月4日16:14:09
*/
@Configuration
public class DruidDataSourceConfiguration {
//@Autowired
DataSourceProperties properties;
//通常通过有参构造方法来引入对应成员变量
//如果组件中没有无参构造方法,会使用有参构造 → 形参会自动按照类型从容器中取出组件
public DruidDataSourceConfiguration(DataSourceProperties properties) {
this.properties = properties;
}
@Bean
public DruidDataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(properties.getDriver());
dataSource.setUrl(properties.getUrl());
dataSource.setUsername(properties.getUsername());
dataSource.setPassword(properties.getPassword());
return dataSource;
}
}
@Component
@Data
@ConfigurationProperties(prefix = "druid.datasource")
public class DataSourceProperties {
String driver;
String url;
String username;
String password;
}
方式四 ***@EnableConfigurationProperties
在配置类中引入参数类
@Configuration
@EnableConfigurationProperties(DataSourceProperties.class)//引入参数类组件
public class DruidDataSourceConfiguration {
//@Autowired
DataSourceProperties properties;
//通常通过有参构造方法来引入对应成员变量
//如果组件中没有无参构造方法,会使用有参构造 → 形参会自动按照类型从容器中取出组件
public DruidDataSourceConfiguration(DataSourceProperties properties) {
this.properties = properties;
}
}
//参数类上没有@Component注解了
@Data
@ConfigurationProperties(prefix = "druid.datasource")
public class DataSourceProperties {
String driver;
String url;
String username;
String password;
}
配置文件中的值的提示
提示信息的来源
autoconfigure依赖 → /META-INF/xxxx-metadata.json
{
"name": "server.port",
"type": "java.lang.Integer",
"description": "Server HTTP port.",
"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties",
"defaultValue": 8080
}
引入依赖提供json文件
configuration-processor能够提供对应的json文件
有时候会失效
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
会在classpath路径下编译一个json文件
{
"name": "druid.datasource.username",
"type": "java.lang.String",
"sourceType": "com.cskaoyan.config4.DataSourceProperties"
}
有的时候它生成不了 → 如果它没有给你自动生成 → 在resources目录下新增一个文件夹/META-INF
默认值
默认值的提示可以通过json文件提示,但不能赋值,如果想要赋值,那么只能在参数类中给成员变量赋值
@Data
@ConfigurationProperties(prefix = "druid.datasource")
public class DataSourceProperties {
String driver;
String url;
String username = "root";
String password;
}
不同类型的成员变量的写法
@EnableConfigurationProperties让参数类中的成员变量能够获得配置文件中的值
基本类型、包装类、String
List或数组 → 在配置文件中的写法是一样的
Map或Java → 在配置文件中的写法是一样的
引入一个参数类,在参数类中增加这些类型的成员变量,并且提供set方法 → 我们通过配置文件给参数类组件的成员变量赋值
properties配置文件写法
@Data
@ConfigurationProperties(prefix = "custom")
public class CustomProperties {
String username; //字符串
int age; //基本类型
Boolean flag; //包装
List list1;
List list2;
String[] array1;
String[] array2;
Map map1;
Map map2;
User user1;
User user2;
}
custom.username=songge
custom.age=30
custom.flag=true
#数组或list的话写法是一样的,有两种写法
# 1.可以使用逗号分隔
# 2.使用中括号里的下标
custom.list1=data1,data2,data3
custom.list2[0]=data4
custom.list2[1]=data5
custom.list2[2]=data6
custom.array1=data1,data2,data3
custom.array2[0]=data4
custom.array2[1]=data5
custom.array2[2]=data6
#map或JavaBean写法是一样的,有两种写法
# 1.多写一级,这一级作为map的key或者Javabean的成员变量
# 2.把key或成员变量写到中括号里
custom.map1.key1=value1
custom.map1.key2=value2
custom.map1.key3=value3
custom.map2[key4]=value4
custom.map2[key5]=value5
custom.map2[key6]=value6
custom.user1.username=songge
custom.user1.password=niupi
custom.user2[username]=ligenli
custom.user2[password]=daqi
yml文件的写法
custom:
username: songge
age: 31
flag: false
# list或数组也可以通过逗号分隔
list1: data1,data2,data3
# 另外一种写法 → 换行、缩进、-、空格
list2:
- data4
- data5
- data6
# 数组和list的写法是完全一样的
array1: data1,data2,data3
# 另外一种写法 → 换行、缩进、-、空格
array2:
- data4
- data5
- data6
# map或JavaBean有一种写法和properties一样,写下一级
map1:
key1: value1
key2: value2
key3: value3
# 可以通过大括号写一个类似于json的格式
map2: {key4: value4,key5: value5,key6: value6}
# user1和user2和上面写法一样
user1:
username: ligenli
password: daqi
user2: {username: songge,password: niupi}
打开debug模式
调试模式在配置文件中直接写
debug=true
设置启动图
banner → SpringBoot应用默认的banner
resources目录下新增一个banner.txt或banner.png
SpringBoot整合web
流程
引入starter依赖
spring-boot-starter-web
扫描包配置:启动类所在的包目录
配置
配置文件中配置
两个前缀:spring.web和spring.mvc
如果你用的是之前版本的SpringBoot,spring.resources
当前版本已经合并到spring.web,变为spring.web.resources
默认配置
默认的静态资源映射的location:spring.web.resources.static-locations
放在了resource目录下的static文件夹中,默认的mapping是/**
自定义配置:
spring:
web:
resources:
# location
static-locations: file:d:/spring/
mvc:
# mapping
static-path-pattern: /pic/**
这里要注意使用2.6.2的版本可以这么写,如果是2.1.5的话不能直接写在web里面
Converter配置
SpringBoot应用只需要注册为容器中的组件就行了(自动配置类)
容器取出了所有的Converter组件,遍历 → addFormatters里执行遍历 → registry.addConverter
public static void addBeans(FormatterRegistry registry, ListableBeanFactory beanFactory) {
Set<Object> beans = new LinkedHashSet();
//把所有的converter组件都取出 → 放入到set里
beans.addAll(beanFactory.getBeansOfType(Converter.class).values());
Iterator var3 = beans.iterator();
while(var3.hasNext()) {
Object bean = var3.next();
if (bean instanceof GenericConverter) {
registry.addConverter((GenericConverter)bean);
//如果是Converter组件就执行addConverter方法
} else if (bean instanceof Converter) {
registry.addConverter((Converter)bean);
}
}
}
web配置类
实现接口WebMvcConfigurer
当自带的前缀不能满足需求时,可以自行写配置类,必须写在扫描包目录下
/**
* @EnableWebMvc和@Configuration都是可以加在配置类上,都会使配置类生效
* @author stone
* @date 2022/01/05 10:25
*/
//@EnableWebMvc → 全面接管web配置
//@Configuration → 配置的补充
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/pic1/**").addResourceLocations("file:d:/spring/");
registry.addResourceHandler("/pic2/**").addResourceLocations("classpath:/static/");
}
}
整合MyBatis
流程
引入starter依赖 mybatis-spring-boot-starter
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
<version>5.1.47</version>
</dependency>
数据源提供、扫描包
spring.datasource
spring:
datasource:
# 驼峰命名形式的成员变量 → 在配置文件中也可以使用短横线来连接
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/cskaoyan_db\
username: root
password: 123456
@MapperScan("com.cskaoyan.demo2mybatis.mapper")
@SpringBootApplication
public class Demo2MybatisApplication {
public static void main(String[] args) {
SpringApplication.run(Demo2MybatisApplication.class, args);
}
}
配置
mybatis的其他配置:自动配置类 → 参数类 → prefix=mybatis
mybatis:
configuration:
lazy-loading-enabled: true
cache-enabled: true
type-aliases-package: com.cskaoyan.demo2mybatis.bean
自动配置类
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.mybatis.spring.boot.autoconfigure.MybatisLanguageDriverAutoConfiguration,\
org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
@Configuration
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties({MybatisProperties.class})
@AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class})
public class MybatisAutoConfiguration implements InitializingBean {
private final MybatisProperties properties;
@Bean
@ConditionalOnMissingBean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource);
return factory.getObject();
}
}
项目
日志
多配制文件
@Configuration
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties({MybatisProperties.class})
@AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class})
public class MybatisAutoConfiguration implements InitializingBean {
private final MybatisProperties properties;
@Bean
@ConditionalOnMissingBean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource);
return factory.getObject();
}
}
# 项目
日志
多配制文件