SpringBoot
2021-12-05 21:15:06 28 举报
AI智能生成
SpringBoot 总结
作者其他创作
大纲/内容
基础回顾
约定优于配置
概念
spring优点:轻量级EJB,实现了IOC、AOP
spring缺点:配置重,需要分析导入依赖。坐标版本选错了,严重阻碍开发进度。
SpringBoot解决spring所有问题
起步依赖:传递依赖,把坐标打在一起,提供默认功能
自动配置:自动将配置类的Bean注册ioc容器。对于主流开发框架无配置集成,提高开发、部署效率
SpringBoot 案例实现
使用Spring Initializr构建Spring Boot(需要联网)
创建controller
运行
解决中文乱码
@RequestMapping(produces = "application/json; charset=utf-8")
#设置响应utf-8
spring.http.encoding.force-response=true
spring.http.encoding.force-response=true
单元测试与热部署
添加依赖
编写测试方法(@RunWith(SpringRunner.class) @SpringBootTest)
热部署
引入依赖
idea配置(compiler->Build project automatically)
快捷键 Ctrl+Shift+Alt+/ ->compiler.automake.allow.when.app.running
全剧配置文件
application.properties配置文件
可以是系统属性、环境变量、自定义配置
可以是系统属性、环境变量、自定义配置
@ConfigurationProperties(prefix = "person") 表示为 配置文件中以person开头通过setXX注入到实体类中
实体类注入到ico容器中,这样 @ConfigurationProperties 赋值
application.yaml
普通数据类型
server:
port: 8081
path: /hello
port: 8081
path: /hello
数组/单列集合
person:
hobby:
- play
- read
- sleep
hobby:
- play
- read
- sleep
配置文件属性值注入
@Value("${person.id}") 直接给属性赋值
自定义配置
使用@PropertySource加载配置文件
@Component
@PropertySource("classpath:test.properties") //配置自定义配置文件的名称及位置
@ConfigurationProperties(prefix = "test")
@PropertySource("classpath:test.properties") //配置自定义配置文件的名称及位置
@ConfigurationProperties(prefix = "test")
@Configuration自定义配置文件
使用配置类的方式向容器中添加组件配置,替代XML配置文件
在标注 @Configuration 类下的@Bean将返回值对象作为组件添加到容器中
随机数&参数引用
随机数
my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}
参数引用
app.name=MyApp
app.description=${app.name} is a Spring Boot application
(注意要相互关联的属性)
app.description=${app.name} is a Spring Boot application
(注意要相互关联的属性)
源码剖析
依赖管理
spring-boot-starter-parent->spring-boot-dependencies配置了常用的框架的约定版本,进行版本统一管理
如果pom.xml没有spring-boot-starter-parent依赖,则需要指定版本
如果pom.xml没有spring-boot-starter-parent依赖,则需要指定版本
spring-boot-starter-web提供了web开发所需的所有底层依赖框架
像额外导入的web依赖文件和tomcat都由parent统一管理
像额外导入的web依赖文件和tomcat都由parent统一管理
第三方依赖starter需要写版本号->druid-spring-boot-starter
自动配置(启动流程)
@SpringBootApplication能够扫描组件,并自动配置
@SpringBootConfiguration
底层是@Configuration,标注它是个配置类
底层是@Configuration,标注它是个配置类
@EnableAutoConfiguration
@AutoConfigurationPackage
@Import(AutoConfigurationPackages.Registrar.class)
将Registrar类导入,作用是将所在包和子包组件扫描到容器中
所以注意main程序路径位置
将Registrar类导入,作用是将所在包和子包组件扫描到容器中
所以注意main程序路径位置
导入AutoConfigurationImportSelector
告诉springboot 需要导入哪些组件
可以帮助springboot应用将所有符合条件的@Configuration配置都加载到当前SpringBoot
创建并使用的IoC容器(ApplicationContext)中
告诉springboot 需要导入哪些组件
可以帮助springboot应用将所有符合条件的@Configuration配置都加载到当前SpringBoot
创建并使用的IoC容器(ApplicationContext)中
loadMetadata
读取spring-boot-autoconfigure.jar包中spring-autoconfigure-metadata.properties的信息生成urls枚举对象
获得 PATH 对应的 URL
遍历 URL 数组,读取到 properties 中
解析urls枚举对象中的信息封装成properties对象并加载
将 properties 转换成 PropertiesAutoConfigurationMetadata 对象
根据封装好的properties对象生成AutoConfigurationMetadata对象返回
获得 PATH 对应的 URL
遍历 URL 数组,读取到 properties 中
解析urls枚举对象中的信息封装成properties对象并加载
将 properties 转换成 PropertiesAutoConfigurationMetadata 对象
根据封装好的properties对象生成AutoConfigurationMetadata对象返回
getAutoConfigurationEntry
getCandidateConfigurations()用来获取默认支持的自动配置类名列表
将自动配置导入事件通知监听器,并触发fireAutoConfigurationImportEvents事件。
创建 AutoConfigurationEntry 对象
将自动配置导入事件通知监听器,并触发fireAutoConfigurationImportEvents事件。
创建 AutoConfigurationEntry 对象
总结
1. springboot应用启动
2. @SpringBootApplication 起作用
3. @EnableAutoConfiguration
4. @AutoConfigurationPackage 扫描主配置同类以及子包,并将相应的组件导入到容器中
5. @Import(AutoConfigurationImportSelector.class) 查找classpath 上所有jar包中的META-INF/spring.factories,进行容器创建。
2. @SpringBootApplication 起作用
3. @EnableAutoConfiguration
4. @AutoConfigurationPackage 扫描主配置同类以及子包,并将相应的组件导入到容器中
5. @Import(AutoConfigurationImportSelector.class) 查找classpath 上所有jar包中的META-INF/spring.factories,进行容器创建。
@ComponentScan
包扫描,对@AutoConfigurationPackage的具体位置,从而的到主程序启动类所在的具体位置
自定义Stater
SpringBoot starter机制
不需要具体配置细节,引用对应starter,自动织入相应的Bean
命名规则
xxx-spring-boot-starter
创建步骤
1. 创建SimpleBean实体类,加入 @EnableConfigurationProperties(SimpleBean.class)// 使使用 @ConfigurationProperties 注解的类生效。
@ConfigurationProperties(prefix = "simplebean") // 配置配置文件的前缀
2. MyAutoConfiguration 创建自定义配置文件,增加@Configuration//标注配置类@ConditionalOnClass
3. 把simpleBean 标注@bean加入配置文件中,加入到容器中
4. 打包 并在测试项目中引用依赖,进行测试
@ConfigurationProperties(prefix = "simplebean") // 配置配置文件的前缀
2. MyAutoConfiguration 创建自定义配置文件,增加@Configuration//标注配置类@ConditionalOnClass
3. 把simpleBean 标注@bean加入配置文件中,加入到容器中
4. 打包 并在测试项目中引用依赖,进行测试
执行原理
执行SpringApplication.run()即可启动整个Spring Boot 项目
run()内部源码
SpringApplication实例初始化创建(实例化)
//项目启动类 SpringbootDemoApplication.class设置为属性存储起来
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
//设置应用类型是SERVLET应用(Spring 5之前的传统MVC应用)还是REACTIVE应用(Spring 5开始出现的WebFlux交互式应用)
this.webApplicationType = WebApplicationType.deduceFromClasspath();
this.webApplicationType = WebApplicationType.deduceFromClasspath();
// 设置初始化器(Initializer),最后会调用这些初始化器,使用spring类加载器将Spring.factories文件中获取所有可用的应用初始化器类
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
// 设置监听器(Listener) (添加到监听器容器,初始化完成通知)
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
// 初始化 mainApplicationClass 属性:用于推断并设置项目main()方法启动的主程序启动类
this.mainApplicationClass = deduceMainApplicationClass();
this.mainApplicationClass = deduceMainApplicationClass();
项目初始化启动,调用run方法
(1)获取并启动监听器
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
(2)项目运行环境Environment的预配置
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
// 准备Banner打印器 - 就是启动Spring Boot的时候打印在console上的ASCII艺术字体
Banner printedBanner = printBanner(environment);
Banner printedBanner = printBanner(environment);
(3)创建Spring容器
context = createApplicationContext();
context = createApplicationContext();
(4)Spring容器前置处理
//这一步主要是在容器刷新之前的准备动作。包含一个非常关键的操作:将启动类注入容器,为后续开启自动化配置奠定基础。
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
//这一步主要是在容器刷新之前的准备动作。包含一个非常关键的操作:将启动类注入容器,为后续开启自动化配置奠定基础。
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
(5):刷新容器
refreshContext(context);
refreshContext(context);
(6):Spring容器后置处理
//扩展接口,设计模式中的模板方法,默认为空实现。
// 如果有自定义需求,可以重写该方法。比如打印一些启动结束log,或者一些其它后置处理
afterRefresh(context, applicationArguments);
//扩展接口,设计模式中的模板方法,默认为空实现。
// 如果有自定义需求,可以重写该方法。比如打印一些启动结束log,或者一些其它后置处理
afterRefresh(context, applicationArguments);
(7)发出结束执行的事件通知
listeners.started(context);
listeners.started(context);
(8):执行Runners
用于调用项目中自定义的执行器XxxRunner类,使得在项目启动完成后立即执行一些特定程序
Runner 运行器用于在服务启动时进行一些业务初始化操作,这些操作只在服务启动后执行一次。
Spring Boot提供了ApplicationRunner和CommandLineRunner两种服务接口
callRunners(context, applicationArguments);
用于调用项目中自定义的执行器XxxRunner类,使得在项目启动完成后立即执行一些特定程序
Runner 运行器用于在服务启动时进行一些业务初始化操作,这些操作只在服务启动后执行一次。
Spring Boot提供了ApplicationRunner和CommandLineRunner两种服务接口
callRunners(context, applicationArguments);
(9)发布应用上下文就绪事件
listeners.running(context);
listeners.running(context);
整体流程图
数据访问
整合Mybaits
1. 引入mybatis-starter 依赖
2. 配置文件 url/username/password
3. 注解整合@Mapper/@MapperScan("xxx")->自动扫描
xml整合 编写mapper.xml & mybatis.mapper-locations=classpath:mapper/*.xml // 配置路径 & mybatis.type-aliases-package=com.zjn.pojo // 别名
4. 测试
5. mybatis.configuration.map-underscore-to-camel-case=true 开启驼峰
2. 配置文件 url/username/password
3. 注解整合@Mapper/@MapperScan("xxx")->自动扫描
xml整合 编写mapper.xml & mybatis.mapper-locations=classpath:mapper/*.xml // 配置路径 & mybatis.type-aliases-package=com.zjn.pojo // 别名
4. 测试
5. mybatis.configuration.map-underscore-to-camel-case=true 开启驼峰
整合JPA
1. 添加starter-data-jpa依赖
2. 实体类 增加 @Entity(name = "t_comment")
3. 编写Repository接口 -> interface CommentRepository extends JpaRepository<Comment,Integer>
4. 测试
2. 实体类 增加 @Entity(name = "t_comment")
3. 编写Repository接口 -> interface CommentRepository extends JpaRepository<Comment,Integer>
4. 测试
整合Redis
1. 添加 starter-data-redis 依赖
2. 实体类上添加@RedisHash("persons"),指定存储空间 。@Indexed 标识二级索引
3. Repository接口 继承 CrudRepository或者 JpaRepository(必须引入jpa&redis)
2. 实体类上添加@RedisHash("persons"),指定存储空间 。@Indexed 标识二级索引
3. Repository接口 继承 CrudRepository或者 JpaRepository(必须引入jpa&redis)
视图技术
不太支持常用的JSP模版,没有提供相应的整合
原因如下:
1. boot 默认以JAR打包进行项目部署,这种JAR包方式不支持JSP模版
2. 使用Undertow 嵌入式容器,也不支持JSP
3. boot 默认提供请求路径 “/error” 统一处理错误,使用JSP无法对默认页进行覆盖
原因如下:
1. boot 默认以JAR打包进行项目部署,这种JAR包方式不支持JSP模版
2. 使用Undertow 嵌入式容器,也不支持JSP
3. boot 默认提供请求路径 “/error” 统一处理错误,使用JSP无法对默认页进行覆盖
Thymeleaf
语法
标准表达式
变量表达式${...}
<p th:text="${title}">xxx</p>
<p th:text="${title}">xxx</p>
内置对象
选择变量表达式
<div th:object="${book}">
<p>titile: <span th:text="*{title}">标题</span>.</p>
</div>
title 表示获取 boot 的titile 属性值
<div th:object="${book}">
<p>titile: <span th:text="*{title}">标题</span>.</p>
</div>
title 表示获取 boot 的titile 属性值
消息表达式#{...}
国际化内容的动态展示和替换
国际化内容的动态展示和替换
链接表达式@{...} 引入资源
<a th:href="@{/order/details(orderId=${o.id})}">view</a>
<a th:href="@{/order/details(orderId=${o.id})}">view</a>
片段表达式~{...} 标记一个片段模版,传递模版
<div th:insert="~{thymeleafDemo::title}"></div>
使用th:insert 属性将title 引用进来
<div th:insert="~{thymeleafDemo::title}"></div>
使用th:insert 属性将title 引用进来
基本使用
引入Thymeleaf依赖
配置参数
静态资源访问
从resources中public/resources/static三个子目录狭隘查找静态资源
从resources中public/resources/static三个子目录狭隘查找静态资源
配置国际化
在resources 狭隘创建i18n的文件夹,编写多语言配置文件
login.properties
login_zh_CN.properties
login_en_US.properties
login_zh_CN.properties
login_en_US.properties
编写配置文件 spring.messages.basename=i18n.login
i18n表示国际化文件相对项目路径resources的位置,login 是前缀
i18n表示国际化文件相对项目路径resources的位置,login 是前缀
自定义MyLocalResovel
@Configuration
public class MyLocaleResovel implements LocaleResolver
将自定义MyLocaleResovel 注册一个类型的LocaleResoler 的Bean 组件
@Configuration
public class MyLocaleResovel implements LocaleResolver
将自定义MyLocaleResovel 注册一个类型的LocaleResoler 的Bean 组件
缓存管理
默认缓存管理
@EnableCaching 开启注解缓存支持
@EnableCaching
@SpringBootApplication
public class Springboot04CacheApplication
@EnableCaching
@SpringBootApplication
public class Springboot04CacheApplication
@Cacheable注解对数据操作方法进行缓存管理注解到service类的查询方法上
执行流程&时机
方法运行前,查询Cache缓存组件,按照name 获取,没有Cache 自动创建,SimpleKeyGenerator 生成Key默认策略
SPEL表达式
@CachePut 用于修改操作
@CacheEvict用于删除操作
整合Redis 缓存实现
支持9种缓存组件,有加载先后顺序
基于注解的Redis 缓存实现
@Cacheable(cacheNames = "comment",unless = "#result==null")
@CachePut(cacheNames = "comment",key = "#result.id")
@CacheEvict(cacheNames = "comment")
@Cacheable(cacheNames = "comment",unless = "#result==null")
@CachePut(cacheNames = "comment",key = "#result.id")
@CacheEvict(cacheNames = "comment")
spring.cache.redis.time-to-live=60000 // 缓存有效期配置
基于API的Redis 缓存实现
@Autowired
private RedisTemplate redisTemplate;
commentRepository.deleteById(comment_id);
redisTemplate.delete("comment_"+comment_id);
@Autowired
private RedisTemplate redisTemplate;
commentRepository.deleteById(comment_id);
redisTemplate.delete("comment_"+comment_id);
自定义Redis缓存序列化机制
自定义RedisTemplate
默认序列化机制,点RedisTemplate进入,在afterPropertiesSet()方法中,如果defaultSerializer 变量为空, 将数据默认序列化方式设置成JdkSerializationRedisSerializer
点进RedisAutoConfiguration 看到默认配置类,跟着写一个
@Configuration
public class RedisConfig
@Bean
public RedisTemplate<Object, Object> redisTemplate...
@Configuration
public class RedisConfig
@Bean
public RedisTemplate<Object, Object> redisTemplate...
自定义RedisCacheManager
打开boot整合Redis自动配置类RedisCacheConfiguration(org.springframework.boot.autoconfigure.cache)包下的 ,仿照写
0 条评论
下一页