# 热部署
# 启动热部署
# 开启开发者工具
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-devtools</artifactId> |
| </dependency> |
# 激活热部署
# 关于热部署
# 重启(Restart)
自定义开发代码,包括类,页面,配置文件等,加载位置 restart 类加载器
# 重载(ReLoad)
jar 包,加载位置 base 类加载器
# 自动启动热部署
# 热部署的范围控制
# 默认不触发重启的目录列表
- /META-INF/maven
- /META-INF/resources
- /resources
- /static
- /public
- /templates
# 自定义参数排除项
| spring: |
| devtools: |
| restart: |
| exclude: public/**,static/** |
# 关闭热部署
# 配置文件中配置
| spring: |
| devtools: |
| restart: |
| enabled: false |
| |
# 设置优先级属性禁用热部署
| public static void main(String[] args) { |
| |
| System.setProperty("spring.devtools.restart.enabled","false"); |
| SpringApplication.run(Springboot08SsmpApplication.class, args); |
| } |
# 配置高级
# 使用 @ConfigurationProperties
第三方绑定属性
| @Bean |
| @Configruation(prefix = "datasource") |
| public DruidDataSource dataSource() { |
| DruidDatasource ds = new DruidDataSource(); |
| return ds; |
| } |
| datasource: |
| driverClassName: com.mysql.jdbc.Driver |
# @EnableConfigurationProperties
@EnableConfigurationProperties 注解可以使用 @ConfigurationProperties 注解对应的类加入 Spring 容器
| @SpringBootApplication |
| @EnableConfigurationProperties({ServerConfig.class}) |
| public class DemoApplication { |
| } |
| |
| @Data |
| @ConfigurationProperties(prefix = "servers") |
| public class ServerConfig { |
| } |
注意:@EnableConfigurationProperties 与 @Component 不能同时使用(防止定义两个 Bean 对象)
# 宽松绑定
# @ConfigurationProperties
绑定属性支持属性名宽松绑定
| public class ServerConfig { |
| private String ipAddress; |
| private int port; |
| private long timeout; |
| } |
| servers: |
| |
| |
| |
| |
| ipAddress: 192.168.0.1 |
| port: 2345 |
| timeout: -1 |
| @Bean |
| |
| @ConfigurationProperties(prefix = "datasource") |
| public DruidDataSource dataSource() { |
| DruidDataSource ds = new DruidDataSource(); |
| return ds; |
| } |
# 常用计量单位
# SpringBoot 支持 jdk8 提供的时间与计量单位
| @Component |
| @Data |
| @ConfigurationProperties(prefix = "servers") |
| public class ServerConfig { |
| private String ipAddress; |
| private int port; |
| private long timeout; |
| @DurationUnit(ChronoUnit.HOURS) |
| private Duration serverTimeout; |
| @DataSizeUnit(DataUnit.MeGABYTES) |
| private DataSize dataSize; |
| } |
# Bean 数据校验
# 开启 Bean 数据校验
| |
| <dependency> |
| <groupId>javax.validation</groupId> |
| <artifactId>validation-api</artifactId> |
| </dependency> |
| |
| <dependency> |
| <groupId>org.hibernate.validator</groupId> |
| <artifactId>hibernate-validator</artifactId> |
| </dependency> |
# 对 Bean 开启校验功能
| @Component |
| @Data |
| @ConfigurationProperties(prefix = "servers") |
| @Validated |
| public class ServerConfig { |
| } |
# 设置校验规则
| @Component |
| @Data |
| @ConfigurationProperties(prefix = "servers") |
| @Validated |
| public class ServerConfig { |
| @Max(value = 400,message = "最大值不超过400") |
| private int port; |
| } |
# 进制数据转换规则
# yml 语法规则
| boolean: TRUE # TRUE,true,True,FALSE,false,False均可 |
| float: 3.14 # 6.852315e+5 支持科学计数法 |
| int: 123 # 支持二进制,八进制,十六进制 |
| null: ~ # 使用~代表null |
| string: HelloWorld # 字符串可以直接书写 |
| string2: "HelloWorld" # 可以使用双引号包裹特殊字符 |
| date: 2018-02-17 # 日期必须使用yyyy-MM-dd格式 |
| datetime: 2018-02-17T15:02:31+08:00 # 时间和日期之间使用T连接,最后使用+代表时区 |
** 注意:** 如果写 password: 0314 会把 0314 解读为八进制,解决办法 "0314"
# 测试
# 加载测试专用属性
# 通过 properties 参数设置测试专用属性
| @SpringBootTest(properties = {"test.prop=testValue01"}) |
| public class PropertiesAndArgsTest { |
| @Value("${test.prop}") |
| private String msg; |
| @Test |
| void testProperties(){ |
| System.out.println(msg); |
| } |
| } |
** 优势:** 比多环境开发中的测试环境影响范围小,仅对当前测试类有效
# 通过 args 参数设置测试专用属性
| @SpringBootTest(args = {"--test.prop=testValue02"}) |
| public class PropertiesAndArgsTest { |
| @Value("${test.prop}") |
| private String msg; |
| @Test |
| void testProperties(){ |
| System.out.println(msg); |
| } |
| } |
# 加载测试专用配置
# 使用 @import
注解加载当前测试类专用配置
| @SpringBootTest |
| @Import({MsgConfig.class}) |
| public class ConfigurationTest() { |
| @Autowired |
| private String msg; |
| @Test |
| void testConfiguration(){ |
| System.out.println(msg); |
| } |
| } |
# web 开发模拟测试
# 模拟端口
| @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) |
| public class WebTest { |
| @Test |
| void test(){ |
| } |
| } |
# 模拟端口的类型
| |
| @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) |
| |
| @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) |
| |
| @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) |
| |
| @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) |
# 虚拟测试请求
| @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) |
| |
| @AutoConfigureMockMvc |
| public class WebTest { |
| @Test |
| |
| void testWeb(@Autowired MockMvc mvc) throws Exception { |
| |
| MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books"); |
| |
| mvc.perform(builder); |
| } |
| } |
# 虚拟请求状态匹配
| @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) |
| |
| @AutoConfigureMockMvc |
| public class WebTest { |
| @Test |
| void testStatus(@Autowired MockMvc mvc) throws Exception { |
| MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books"); |
| ResultActions action = mvc.perform(builder); |
| |
| |
| StatusResultMatchers status = MockMvcResultMatchers.status(); |
| |
| ResultMatcher ok = status.isOk(); |
| |
| action.andExpect(ok); |
| } |
| } |
# 匹配响应体
| @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) |
| |
| @AutoConfigureMockMvc |
| public class WebTest { |
| @Test |
| void testBody(@Autowired MockMvc mvc) throws Exception { |
| MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books"); |
| ResultActions action = mvc.perform(builder); |
| |
| |
| ContentResultMatchers content = MockMvcResultMatchers.content(); |
| ResultMatcher resule = content.string("springboot"); |
| |
| action.andExpect(resule); |
| } |
| } |
# 匹配响应体
| @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) |
| |
| @AutoConfigureMockMvc |
| public class WebTest { |
| @Test |
| void testJson(@Autowired MockMvc mvc) throws Exception { |
| MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books"); |
| ResultActions action = mvc.perform(builder); |
| |
| |
| ContentResultMatchers content = MockMvcResultMatchers.content(); |
| ResultMatcher result = content.json("{\"id\":1,\"name\":\"Java\",\"type\":\"Java\",\"description\":\"Java学习\"}"); |
| |
| action.andExpect(result); |
| } |
| } |
# 完整测试方法
| @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) |
| |
| @AutoConfigureMockMvc |
| public class WebTest { |
| @Test |
| void testContentType(@Autowired MockMvc mvc) throws Exception { |
| MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books"); |
| ResultActions action = mvc.perform(builder); |
| |
| StatusResultMatchers status = MockMvcResultMatchers.status(); |
| ResultMatcher ok = status.isOk(); |
| action.andExpect(ok); |
| |
| ContentResultMatchers content = MockMvcResultMatchers.content(); |
| ResultMatcher result = content.json("{\"id\":1,\"name\":\"Java\",\"type\":\"Java\",\"description\":\"Java学习\"}"); |
| action.andExpect(result); |
| |
| HeaderResultMatchers header = MockMvcResultMatchers.header(); |
| ResultMatcher contentType = header.string("Content-type","application/json"); |
| action.andExpect(contentType); |
| |
| } |
| } |
# 业务层测试
# 数据层测试事务回滚
为了测试添加事务,SpringBoot 会对测试用例对应的事务提交操作进行回滚
| @SpringBootTest |
| @Transactional |
| public class ServiceTest { |
| @Autowired |
| private BookService bookService; |
| } |
如果想测试用例中提交事务,可以通过 @RollBack 注解配置
| @SpringBootTest |
| @Transactional |
| @Rollback(value = false) |
| public class ServiceTest { |
| } |
# 测试用例设置随机数据
测试用例数据通常采用随机值进行测试,使用 SpringBoot 提供的随机数进行赋值
| testcase: |
| book: |
| id: ${random.int} |
| id2: ${random.int(10)} |
| type: ${random.int(5,10)} |
| name: 包子${random.value} |
| uuid: ${random.uuid} |
| publishTime: ${random.long} |
# 数据层解决方案
# 内置数据源
- HiKariCP
- Tomcat 提供 DataSource
- .Commons DBCP
# 内置持久化解决方案 ——jdbcTemplate
# 用法
| @Test |
| void testJdbcTemplate() { |
| String sql = "select * from tal_book where id = 1"; |
| RowMapper<Book> rm = new RowMapper<Book>() { |
| @Override |
| public Book mapRow(ResultSet rs, int rowNum) throws SQLException { |
| Book temp = new Book(); |
| temp.setId(rs.getInt("id")); |
| temp.setName(rs.getString("name")); |
| temp.setType(rs.getString("type")); |
| temp.setDescription( rs.getString("description")); |
| return temp; |
| } |
| }; |
| List<Book> list = jdbcTemplate.query(sql, rm); |
| System.out.println(list); |
| } |
# 导入依赖 jdbc
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-jdbc</artifactId> |
| </dependency> |
# 内嵌数据库
# 内嵌数据库(H2)
# 设置当前项目为 web 工程,配置 H2 管理控制台参数
| server: |
| port: 80 |
| spring: |
| h2: |
| console: |
| path: /h2 |
| enabled: true |
访问用户名 sa,默认密码 123456
# 设置访问权限
| server: |
| port: 80 |
| spring: |
| h2: |
| console: |
| path: /h2 |
| enabled: true |
| datasource: |
| url: jdbc:h2:~/test |
| driver-class-name: org.h2.Driver |
| username: sa |
| password: 123456 |
# Redis
# 概念
Redis 是一款 key-value 存储结构的内存级 NoSQL 数据库
- 支持多种数据库存储格式
- 支持持久化
- 支持集群
# Redis 下载
官网:https://github.com/tporadowski/redis/releases
# Redis 安装启动
# 服务端启动
redis-server.exe redis.windows.conf
# 客户端启动命令
redis-cli.exe
# SpringBoot 整合 Redis
# 导入 SpringBoot 整合 Redis 坐标
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-data-redis</artifactId> |
| </dependency> |
# 配置 Redis
| spring: |
| redis: |
| host: localhost |
| port: 6379 |
# RedisTemplate(操作接口)
| @SpringBootTest |
| class Springboot15RedisApplicationTests { |
| |
| @Autowired |
| private RedisTemplate redisTemplate; |
| @Test |
| void set() { |
| ValueOperations ops = redisTemplate.opsForValue(); |
| ops.set("age",41); |
| } |
| @Test |
| void get() { |
| ValueOperations ops = redisTemplate.opsForValue(); |
| Object age = ops.get("age"); |
| System.out.println(age); |
| } |
| } |
# SpringBoot 读写 Redis 客户端
StringRedisTemplate 以字符串作为 key 和 value,与 Redis 客户端操作等效
| @SpringBootTest |
| public class StringRedisTemplateTest { |
| @Autowired |
| private StringRedisTemplate stringRedisTemplate; |
| @Test |
| void get() { |
| ValueOperations<String, String> ops = stringRedisTemplate.opsForValue(); |
| String name = ops.get("name"); |
| System.out.println(name); |
| } |
| } |
# Redis 客户端实现技术切换(jedis)
| spring: |
| redis: |
| host: localhost |
| port: 6379 |
| client-type: jedis |
| jedis: |
| pool: |
| max-active: 16 |
| lettuce: |
| pool: |
| max-active: 16 |
# Mongodb
# 概念
MongdDB 是一个开源,高性能,无模式文档型数据库。NoSQL 数据库产品中的一种,是最像关系数据库的非关系型数据库
# 下载
官网:https://www.mongodb.com/try/download
# Mongodb 启动
- 服务器端启动:
mongod --dapath=..\data\db
- 客户端启动:
mongo --host=127.0.0.1 --port=27017
# Mongodb(CRUD)
# 新增
db.集合名称.insert/save/insertOne
# 修改
db.集合名称.update(条件,{操作种类:{文档}})
# 删除
db.集合名称.remove(条件)
# 查询
db.集合.find({})
# SpringBoot 整合 Mongodb
# 导入驱动
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-data-mongodb</artifactId> |
| </dependency> |
# 配置客户端
| spring: |
| data: |
| mongodb: |
| uri: mongodb://localhost/itheima |
# 客户端读写 Mongodb
| @SpringBootTest |
| class Springboot16MongodbApplicationTests { |
| @Autowired |
| private MongoTemplate mongoTemplate; |
| @Test |
| void contextLoads() { |
| Book book = new Book(); |
| book.setId(2); |
| book.setName("springboot111"); |
| book.setType("Java11"); |
| book.setDescription("study"); |
| mongoTemplate.save(book); |
| } |
| @Test |
| void find() { |
| List<Book> bookList = mongoTemplate.findAll(Book.class); |
| System.out.println(bookList); |
| } |
| } |
# Elasticsearch(ES)
# 概念
Elasticsearch 是一个分布式全文搜索引擎(倒排索引 有信息查 id 再查数据)
# 下载
官网:https://www.elastic.co/cn/download/elasticsearch
# 安装与启动
elasticsearch.bat
# ES 索引操作
# 创建
PUT http://localhost:9200/books
# 2)查询
GET http://localhost:9200/books
# 3)删除
DELETE http://localhost:9200/books
# 4)索引创建规则
| { |
| "mappings": { |
| "properties": { |
| "all": { |
| "type": "text", |
| "analyzer": "ik_max_word" |
| }, |
| "description": { |
| "type": "text", |
| "copy_to": [ |
| "all" |
| ], |
| "analyzer": "ik_max_word" |
| }, |
| "id": { |
| "type": "keyword" |
| }, |
| "name": { |
| "type": "text", |
| "copy_to": [ |
| "all" |
| ], |
| "analyzer": "ik_max_word" |
| }, |
| "type": { |
| "type": "keyword" |
| } |
| } |
| } |
| } |
# 文档操作
创建文档
| POST http://localhost:9200/books/_doc # 使用系统生成id |
| POST http://localhost:9200/books/_create/1 # 使用指定id |
| POST http://localhost:9200/books/_doc/1 # 使用指定id,不存在创建,存在更新 |
| { |
| "name":"springboot" |
| "type":"springboot" |
| "description":"springboot" |
| } |
查询文档
| GET http://localhost:9200/books/_doc/1 # 查询单个文档 |
| GET http://localhost:9200/books/_search # 查询全部文档 |
条件查询
| GET http://localhost:9200/books/_search?q=name:springboot |
删除文档
| DELETE http://localhost:9200/books/_doc/1 |
修改(全部)
| PUT http://localhost:9200/books/_doc/1 |
| { |
| "name":"springboot" |
| "type":"springboot" |
| "description":"springboot" |
| } |
修改(部分)
| POST http://localhost:9200/books/_update/1 |
| { |
| "doc":{ |
| "name":"springboot" |
| } |
| } |
# SpringBoot 整合 ES
# 导入依赖
| <dependency> |
| <groupId>org.elasticsearch.client</groupId> |
| <artifactId>elasticsearch-rest-high-level-client</artifactId> |
| </dependency> |
# 配置
| spring: |
| elesticsearch: |
| rest: |
| uris:http://localhost:9200 |
# 客户端
| @SpringBootTest |
| class Springboot17EsApplicationTests { |
| @BeforeEach |
| void setUp() { |
| HttpHost host = HttpHost.create("http://localhost:9200"); |
| RestClientBuilder builder = RestClient.builder(host); |
| client = new RestHighLevelClient(builder); |
| } |
| @AfterEach |
| void tearDown() throws IOException { |
| client.close(); |
| } |
| private RestHighLevelClient client; |
| @Test |
| void testCreateIndex() throws IOException { |
| CreateIndexRequest request = new CreateIndexRequest("books"); |
| client.indices().create(request, RequestOptions.DEFAULT); |
| } |
| } |
# 添加文档(单个)
| @Test |
| void testCreateDoc() throws IOException { |
| Book book = bookDao.selectById(1); |
| IndexRequest request = new IndexRequest("books").id(book.getId().toString()); |
| String json = JSON.toJSONString(book); |
| request.source(json, XContentType.JSON); |
| client.index(request,RequestOptions.DEFAULT); |
| } |
# 添加文档(批量添加)
| @Test |
| void testCreateDocAll() throws IOException { |
| List<Book> bookList = bookDao.selectList(null); |
| BulkRequest bulk = new BulkRequest(); |
| for (Book book : bookList) { |
| IndexRequest request = new IndexRequest("books").id(book.getId().toString()); |
| String json = JSON.toJSONString(book); |
| request.source(json,XContentType.JSON); |
| bulk.add(request); |
| } |
| client.bulk(bulk,RequestOptions.DEFAULT); |
| } |
# 查询文档(单个)
| @Test |
| void testGet() throws IOException { |
| GetRequest request = new GetRequest("books","1"); |
| GetResponse response = client.get(request, RequestOptions.DEFAULT); |
| String json = response.getSourceAsString(); |
| System.out.println(json); |
| } |
# 查询文档(条件)
| @Test |
| void testSearch() throws IOException { |
| SearchRequest request = new SearchRequest("books"); |
| SearchSourceBuilder builder = new SearchSourceBuilder(); |
| builder.query(QueryBuilders.termQuery("name","java")); |
| request.source(builder); |
| SearchResponse response = client.search(request, RequestOptions.DEFAULT); |
| SearchHits hits = response.getHits(); |
| for (SearchHit hit : hits) { |
| String json = hit.getSourceAsString(); |
| Book book = JSON.parseObject(json, Book.class); |
| System.out.println(book); |
| } |
| } |
# 整合第三方技术
# 缓存
# 概述
- 缓存时一种介于数据永久存储与数据应用之间得数据临时存储介质
- 使用缓存可以有效减少低速数据读取过程中的次数,提高系统性能
- 缓存不仅可以使用提高永久性存储介质的数据读取效率,还可以提供临时的数据存储空间
# SpringBoot 提供缓存技术
# 导入缓存技术 starter
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-cache</artifactId> |
| </dependency> |
# 启动缓存 @EnableCaching
| @SpringBootApplication |
| |
| @EnableCaching |
| public class Springboot18CacheApplication { |
| public static void main(String[] args) { |
| SpringApplication.run(Springboot18CacheApplication.class, args); |
| } |
| } |
# 设置当前操作结果数据进入缓存 @Cacheable
| @Override |
| |
| @Cacheable(value = "cacheSpace",key = "#id") |
| public Book getById(Integer id) { |
| return bookDao.selectById(id); |
| } |
# 整合 Ehcache
# 导入坐标
| <dependency> |
| <groupId>net.sf.ehcache</groupId> |
| <artifactId>ehcache</artifactId> |
| </dependency> |
# 缓存设定为使用 Ehcache
| spring: |
| cache: |
| type: ehcache |
| ehcache: |
| config: ehcache.xml |
# ehcache 配置文件
| <?xml version="1.0" encoding="UTF-8"?> |
| <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" |
| updateCheck="false"> |
| |
| diskStore:为缓存路径,ehcache 分为内存和磁盘两级,此属性定义磁盘的缓存位置。参数解释如下: |
| user.home – 用户主目录 |
| user.dir – 用户当前工作目录 |
| java.io.tmpdir – 默认临时文件路径 |
| --> |
| <diskStore path="java.io.tmpdir/Tmp_EhCache"/> |
| |
| defaultCache:默认缓存策略,当 ehcache 找不到定义的缓存时,则使用这个缓存策略。只能定义一个。 |
| --> |
| |
| name: 缓存名称。 |
| maxElementsInMemory: 缓存最大数目 |
| maxElementsOnDisk:硬盘最大缓存个数。 |
| eternal: 对象是否永久有效,一但设置了,timeout 将不起作用。 |
| overflowToDisk: 是否保存到磁盘,当系统当机时 |
| timeToIdleSeconds: 设置对象在失效前的允许闲置时间(单位:秒)。仅当 eternal=false 对象不是永久有效时使用,可选属性,默认值是 0,也就是可闲置时间无穷大。 |
| timeToLiveSeconds: 设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当 eternal=false 对象不是永久有效时使用,默认是 0.,也就是对象存活时间无穷大。 |
| diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false. |
| diskSpoolBufferSizeMB:这个参数设置 DiskStore(磁盘缓存)的缓存区大小。默认是 30MB。每个 Cache 都应该有自己的一个缓冲区。 |
| diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是 120 秒。 |
| memoryStoreEvictionPolicy:当达到 maxElementsInMemory 限制时,Ehcache 将会根据指定的策略去清理内存。默认策略是 LRU(最近最少使用)。你可以设置为 FIFO(先进先出)或是 LFU(较少使用)。 |
| clearOnFlush:内存数量最大时是否清除。 |
| memoryStoreEvictionPolicy: 可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。 |
| FIFO,first in first out,这个是大家最熟的,先进先出。 |
| LFU, Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个 hit 属性,hit 值最小的将会被清出缓存。 |
| LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。 |
| --> |
| <defaultCache |
| eternal="false" |
| maxElementsInMemory="10000" |
| overflowToDisk="false" |
| diskPersistent="false" |
| timeToIdleSeconds="1800" |
| timeToLiveSeconds="259200" |
| memoryStoreEvictionPolicy="LRU"/> |
| |
| <cache |
| name="smsCode" |
| eternal="false" |
| maxElementsInMemory="5000" |
| overflowToDisk="false" |
| diskPersistent="false" |
| timeToIdleSeconds="10" |
| timeToLiveSeconds="10" |
| memoryStoreEvictionPolicy="LRU"/> |
| |
| </ehcache> |
# 数据淘汰策略
- LRU:淘汰距离上次使用时间长的
- LFU:淘汰最近使用次数少的
# Redis 整合
# 导入 Redis 坐标
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-data-redis</artifactId> |
| </dependency> |
# 配置 Redis 服务器
| spring: |
| redis: |
| host: localhost |
| port: 6379 |
| cache: |
| type: redis |
# jetCache
# 加入坐标
| <dependency> |
| <groupId>com.alicp.jetcache</groupId> |
| <artifactId>jetcache-starter-redis</artifactId> |
| <version>2.6.2</version> |
| </dependency> |
# 配置
| jetcache: |
| local: |
| default: |
| type: linkedhashmap |
| keyConvertor: fastjson |
| remote: |
| default: |
| type: redis |
| host: localhost |
| port: 6379 |
| poolConfig: |
| maxTotal: 50 |
| sms: |
| type: redis |
| host: localhost |
| port: 6379 |
| poolConfig: |
| maxTotal: 50 |
# 开启 jetcache 注解支持
| @SpringBootApplication |
| |
| @EnableCreateCacheAnnotation |
| public class Springboot19JetcacheApplication { |
| public static void main(String[] args) { |
| SpringApplication.run(Springboot19JetcacheApplication.class, args); |
| } |
| } |
# 声明缓存对象
| @Service |
| public class SMSCodeServiceImpl implements SMSCodeService { |
| |
| |
| @CreateCache(name = "jetCache",expire = 3600,timeUnit = TimeUnit.SECONDS,cacheType = CacheType.LOCAL) |
| private Cache<String,String> jetCache; |
| @Override |
| public String sendCodeToSMS(String tele) { |
| String code = codeUtils.generator(tele); |
| jetCache.put(tele,code); |
| return code; |
| } |
| |
| @Override |
| public boolean checkCode(SMSCode smsCode) { |
| String code = jetCache.get(smsCode.getTele()); |
| return smsCode.getCode().equals(code); |
| } |
| } |
# 声明方法缓存,启动注解
| @SpringBootApplication |
| |
| @EnableCreateCacheAnnotation |
| @EnableMethodCache(basePackages = "com.baozi") |
| public class Springboot19JetcacheApplication { |
| public static void main(String[] args) { |
| SpringApplication.run(Springboot19JetcacheApplication.class, args); |
| } |
| } |
# 使用注解操作缓存
| @Service |
| public class BookServiceImpl implements BookService { |
| @Autowired |
| private BookDao bookDao; |
| @Override |
| @Cached(name = "book",key = "#id",expire = 1000) |
| |
| public Book getById(Integer id) { |
| return bookDao.selectById(id); |
| } |
| } |
# j2cache
# 概述
j2cache 是一个缓存整合框架,可以提供缓存整合方案,使用各种缓存搭配使用,自身不提供缓存功能
# 任务
# SpringBoot 整合 Quartz
# 相关概念
- 工作(Job):用于定义具体执行的工作
- 工作明细(JobDetail):用于描述定时工作相关的信息
- 触发器(Trigger):用于描述触发工作的规则,通常使用 cron 表达式定义调度规则
- 调度器(Scheduler):描述了工作明细与触发器的对应关系
# 导入整合 quartz 坐标
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-quartz</artifactId> |
| </dependency> |
# 定义具体执行的任务
| public class MyQuartz extends QuartzJobBean { |
| @Override |
| protected void executeInternal(JobExecutionContext context) throws JobExecutionException { |
| System.out.println("quartz task running ..."); |
| } |
| } |
# 定义工作明细与触发器,并绑定对应关系
| @Configuration |
| public class QuartzConfig { |
| @Bean |
| public JobDetail printJobDetaile(){ |
| return JobBuilder.newJob(MyQuartz.class).storeDurably().build(); |
| } |
| @Bean |
| public Trigger printJobTrigger(){ |
| ScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/3 * * * * ?"); |
| return TriggerBuilder.newTrigger().forJob(printJobDetaile()).withSchedule(scheduleBuilder).build(); |
| } |
| } |
# Spring Task
# 开启定时任务功能
| @SpringBootApplication |
| |
| @EnableScheduling |
| public class Springboot20TaskApplication { |
| public static void main(String[] args) { |
| SpringApplication.run(Springboot20TaskApplication.class, args); |
| } |
| } |
# 设置定时任务,并设定执行周期
| @Component |
| public class MyBean { |
| @Scheduled(cron = "0/3 * * * * ?") |
| public void print(){ |
| System.out.println("spring task running..."); |
| } |
| } |
# 配置文件
| spring: |
| task: |
| execution: |
| thread-name-prefix: spring_task_ |
# Mail 邮件
# SpringBoot 整合 JavaMail
# 邮件协议
- SMTP:发送电子邮件传输协议
- POP3:用于接收电子邮件标准协议
- IMAP:互联网信息协议,是 POP3 的替代协议
# 导入坐标
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-mail</artifactId> |
| </dependency> |
# 配置 JavaMail
| spring: |
| mail: |
| username: 2072626886@qq.com |
| password: bjh0314 |
| host: smtp.qq.com |
# 消息
# ActiveMQ
# RabbitMQ
# RocketMQ
# Kafka
# 监控
# 监控意义
- 监控服务状态是否宕机
- 监控服务运行指标
- 监控日志
- 管理服务
# 可视化监控平台
# Admin 客户端
| <properties> |
| <java.version>1.8</java.version> |
| <spring-boot-admin.version>2.7.4</spring-boot-admin.version> |
| </properties> |
| <dependencies> |
| <dependency> |
| <groupId>de.codecentric</groupId> |
| <artifactId>spring-boot-admin-starter-client</artifactId> |
| </dependency> |
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-web</artifactId> |
| </dependency> |
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-test</artifactId> |
| <scope>test</scope> |
| </dependency> |
| </dependencies> |
| <dependencyManagement> |
| <dependencies> |
| <dependency> |
| <groupId>de.codecentric</groupId> |
| <artifactId>spring-boot-admin-dependencies</artifactId> |
| <version>${spring-boot-admin.version}</version> |
| <type>pom</type> |
| <scope>import</scope> |
| </dependency> |
| </dependencies> |
| </dependencyManagement> |
| <dependency> |
| <groupId>de.codecentric</groupId> |
| <artifactId>spring-boot-admin-starter-client</artifactId> |
| <version>2.5.4</version> |
| </dependency> |
| spring: |
| boot: |
| admin: |
| client: |
| url: http://localhost:8080 |
| server: |
| port: 80 |
| management: |
| endpoint: |
| health: |
| show-details: always |
| endpoints: |
| web: |
| exposure: |
| include: "*" |
# Admin 服务端
| <dependency> |
| <groupId>de.codecentric</groupId> |
| <artifactId>spring-boot-admin-starter-server</artifactId> |
| <version>2.5.4</version> |
| </dependency> |
| |
| @SpringBootApplication |
| @EnableAdminServer |
| public class SpringBoot25ActuatorServerApplication { |
| piblic static void main(String[] args){ |
| SpringApplication.run(Springboot25ActuatorServerApplication.class,args); |
| } |
| } |
# 监控原理
- Actuator 提供了 SpringBoot 生产就绪功能,通过端点的配置与访问,获取端点信息
- 端点描述了一组监控信息,SpringBoot 提供了多个内置端点,也可以根据需要自定义端点信息
- 访问当前应用所有端点信息:/actuator
- 访问端点详细消息:/actuator/ 端点名称
# 自定义监控指标
# 为 info 端点添加自定义指标
| @Component |
| public class infoConfig implements InfoContributor { |
| @Override |
| public void contribute(Info.Builder builder) { |
| builder.withDetail("runTime",System.currentTimeMillis()); |
| Map infoMap = new HashMap(); |
| infoMap.put("buildeTine","2006"); |
| builder.withDetails(infoMap); |
| } |
| } |
# 自定义端点
| @Component |
| @Endpoiont(id = "pay") |
| public class PayEndPoint { |
| @ReadOperation |
| public Object getPay(){ |
| Map payMap = new HashMap(); |
| payMap.put("1",103); |
| payMap.put("2",104); |
| payMap.put("3",105); |
| return payMap; |
| } |
| } |