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
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();
}
}
# 项目 日志 多配制文件