SpringBoot中的一些组件
Redis
引入data-redis-starter
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<!-- 排除lettuce依赖 -->
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion></exclusions>
</dependency>
<dependency>
<!-- 使用jedis客户端 -->
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
lettuce客户端会产生堆外内存溢出:OutOfDirectMemoryError(堆外内存溢出)
SpringBoot 2.0以后 默认使用lettuce作为操作redis的客户端,它使用netty进行网络通信。lettuce的bug导致netty堆外内存溢出 -Xmx100m netty。如果没有指定堆外内存,默认使用-Xmx100m
可以通过-Dio.netty.maxDirectMemory进行设置(调大堆外内存)
解决方案:不能只是调大堆外内存
升级lettuce客户端
切换使用jedis
lettuce和jedis是操作redis的底层客户端,spring进行了再次封装redisTemplate;
所以不管底层用的是lettuce还是jedis我们直接使用redisTemplate即可操作redis;
简单配置redis的host、port等信息
spring:
redis:
host: 192.168.101.100
port: 6379
使用SpringBoot自动配置好的StringRedisTemplate来操作redis
Redisson
<!-- 以后使用redisson作为所有分布式锁,分布式对象等功能框架 -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.12.0</version>
</dependency>
/**
* 配置Redisson操作客户端
*/
@Configuration
public class MyRedissonConfig {
/**
* 所有对Redisson的使用都是通过 RedissonClient对象
**/
@Bean(destroyMethod="shutdown")
public RedissonClient redisson() throws IOException {
// 1.创建配置
//Redis url should start with redis:// or rediss:// (for SSL connection)
Config config = new Config();
// 使用单节点模式,指定redis服务器地址
config.useSingleServer().setAddress("redis://192.168.101.100:6379");
// 2.根据Config创建出RedissonClient实例
return Redisson.create(config);
}
}
SpringCache
引入依赖 spring-boot-starter-cache、spring-boot-starter-data-redis
<!-- 再加上上文的Redis依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>配置类
@EnableConfigurationProperties(CacheProperties.class) // 开启属性配置的绑定功能
@Configuration
@EnableCaching // 开启缓存功能
public class MyCacheConfig {
@Bean
RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties){
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
// key的序列化
config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
// value的序列化
config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
CacheProperties.Redis redisProperties = cacheProperties.getRedis();
// 将配置文件中的所有配置都生效
if (redisProperties.getTimeToLive() != null) {
config = config.entryTtl(redisProperties.getTimeToLive());
}
if (redisProperties.getKeyPrefix() != null) {
config = config.prefixKeysWith(redisProperties.getKeyPrefix());
}
if (!redisProperties.isCacheNullValues()) {
config = config.disableCachingNullValues();
}
if (!redisProperties.isUseKeyPrefix()) {
config = config.disableKeyPrefix();
}
return config;
}
}配置文件
# 配置使用redis作为缓存
spring.cache.type=redis
# 过期时间:毫秒
spring.cache.redis.time-to-live=3600000
# 缓存前缀,如果指定了前缀就用我们指定的前缀,若没有就默认使用缓存的名字作为前缀 缓存的名字:@Cacheable(value = {"category"})
#spring.cache.redis.key-prefix=CACHE_
# 是否使用缓存前缀
spring.cache.redis.use-key-prefix=true
# 是否缓存空值,防止缓存穿透
spring.cache.redis.cache-null-values=true使用缓存
@Cacheable
: Triggers cache population. 触发将数据保存到缓存的操作@Cacheable可以标记在一个方法上,也可以标记在一个类上。当标记在一个方法上时表示该方法是支持缓存的,当标记在一个类上时则表示该类所有的方法都是支持缓存的。对于一个支持缓存的方法,Spring会在其被调用后将其返回值缓存起来,以保证下次利用同样的参数来执行该方法时可以直接从缓存中获取结果,而不需要再次执行该方法。@Cacheable可以指定三个属性,value、key和condition。
@CacheEvict
: Triggers cache eviction. 触发将数据从缓存删除@CacheEvict是用来标注在需要清除缓存元素的方法或类上的。当标记在一个类上时表示其中所有的方法的执行都会触发缓存的清除操作。@CacheEvict可以指定的属性有value、key、condition、allEntries和beforeInvocation。其中value、key和condition的语义与@Cacheable对应的属性类似。即value表示清除操作是发生在哪些Cache上的(对应Cache的名称);key表示需要清除的是哪个key,如未指定则会使用默认策略生成的key;condition表示清除操作发生的条件。
@CachePut
: Updates the cache without interfering with the method execution.以不影响方法执行的方式更新缓存在支持Spring Cache的环境下,对于使用@Cacheable标注的方法,Spring在每次执行前都会检查Cache中是否存在相同key的缓存元素,如果存在就不再执行该方法,而是直接从缓存中获取结果进行返回,否则才会执行并将返回结果存入指定的缓存中。@CachePut也可以声明一个方法支持缓存功能。与@Cacheable不同的是使用@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。
@Caching
: Regroups multiple cache operations to be applied on a method. 组合多个缓存操作@Caching注解可以让我们在一个方法或者类上同时指定多个Spring Cache相关的注解。其拥有三个属性:cacheable、put和evict,分别用于指定@Cacheable、@CachePut和@CacheEvict。
@CacheConfig
: Shares some common cache-related settings at class-level. 在类级别共享缓存的相同配置@CacheConfig用在类上,将公共缓存内容写在该注解中,方法中这些属性即可不用再写了。
开启缓存功能
@EnableCaching
只需要使用注解就能完成缓存操作
代码
@Cacheable(value = {"category"},key = "#root.method.name",sync = true) //sync = true 很重要(加锁,解决击穿)
@Override
public List<CategoryEntity> getLevel1Categorys() {
System.out.println("getLevel1Categorys....");
List<CategoryEntity> categoryEntities = baseMapper.selectList(new QueryWrapper<CategoryEntity>().eq("parent_cid", 0));
return categoryEntities;
}
@Cacheable(value = "category",key = "#root.methodName")
@Override
public Map<String, List<Catelog2Vo>> getCatalogJson() {
dosomething();
}
@CacheEvict(value = "category",allEntries = true) // 指定删除某个分区下的所有数据
@Transactional
@Override
public void updateCascade(CategoryEntity category) {
this.updateById(category); //先更新自己
categoryBrandRelationService.updateCategory(category.getCatId(), category.getName());
// 同时修改缓存中的数据【双写模式】
// 删除缓存中的数据,等待下一次主动查询进行更新【失效模式】
}
@Caching(cacheable = @Cacheable("users"), evict = { @CacheEvict("cache2"),
@CacheEvict(value = "cache3", allEntries = true) })
public User find(Integer id) {
return null;
}
@CacheConfig(value="emp")
public class EmployeeService{
@Cacheable(key="#user.id")
public User find(User user) {
return null;
}
@Cacheable(key = "#root.args[0]")
public User getUserById(Integer id){
User user=userMapper.getUserById(id);
return user;
}
}
@Cacheable({"category"})
代表当前方法的结果需要缓存。如果缓存中有,方法不用调用,如果缓存中没有,会调用方法,最后将方法中的结果放入缓存。 每一个需要缓存的数据我们都来指定要放到哪个名字的缓存,这里是放在“category”分区【缓存的分区(按照业务类型分)】
默认行为 1)如果缓存中有,方法不调用 2)key默认自动生成:缓存的名字 category::SimpleKey [] (自动生成的key) 3)缓存的value的值,默认使用jdk序列化机制,将序列化后的数据存到redis 4)默认ttl时间:-1 永不过期
自定义
1)value是我们设置的缓存中的分区名字。 2)指定生成的缓存使用的key : key属性指定,接收一个spEL spEL详细语法参照文档 3)指定缓存的数据的存活时间 配置文件中修改ttl 4)将数据存为json数据
mybatisplus
依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>配置
spring:
datasource:
username: root
password: root
url: jdbc:mysql://192.168.101.100:3306/gulimall_pms?useUnicode=true&characterEncoding=UTF8
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
#设置实体类的自增主键
global-config:
db-config:
id-type: auto
#逻辑删除
logic-delete-value: 1
logic-not-delete-value: 2@MapperScan注解
实体类字段上加上逻辑删除注解@TableLogic
SpringBoot中的一些组件的更多相关文章
- springboot中的mybatis是如果使用pagehelper的
springboot中使用其他组件都是基于自动配置的AutoConfiguration配置累的,pagehelper插件也是一样的,通过PageHelperAutoConfiguration的,这个类 ...
- SpringBoot中异步请求和异步调用(看这一篇就够了)
原创不易,如需转载,请注明出处https://www.cnblogs.com/baixianlong/p/10661591.html,否则将追究法律责任!!! 一.SpringBoot中异步请求的使用 ...
- springboot 中使用Druid 数据源提供数据库监控
一.springboot 中注册 Servlet/Filter/Listener 的方式有两种,1 通过代码注册 ServletRegistrationBean. FilterRegistration ...
- SpringBoot中实现依赖注入功能
本文转载自:https://blog.csdn.net/linzhiqiang0316/article/details/52639888 今天给大家介绍一下SpringBoot中是如何实现依赖注入的功 ...
- SpringBoot中使用LoadTimeWeaving技术实现AOP功能
目录 1. 关于LoadTimeWeaving 1.1 LTW与不同的切面织入时机 1.2 JDK实现LTW的原理 1.3 如何在Spring中实现LTW 2. Springboot中使用LTW实现A ...
- SpringBoot中通过SpringBootServletInitializer如何实现容器初始化
相关文章 <Servlet3.0之四:动态注册和Servlet容器初始化> <SpringBoot中通过SpringBootServletInitializer如何实现组件加载> ...
- SpringBoot(七) SpringBoot中的缓存机制
随着时间的积累,应用的使用用户不断增加,数据规模也越来越大,往往数据库查询操作会成为影响用户使用体验的瓶颈,此时使用缓存往往是解决这一问题非常好的手段之一.Spring 3开始提供了强大的基于注解的缓 ...
- SpringBoot学习笔记(10)-----SpringBoot中使用Redis/Mongodb和缓存Ehcache缓存和redis缓存
1. 使用Redis 在使用redis之前,首先要保证安装或有redis的服务器,接下就是引入redis依赖. pom.xml文件如下 <dependency> <groupId&g ...
- Spring生态研习【五】:Springboot中bean的条件注入
在springboot中,开发的确变的简单了很多,但是,开发者现在希望开发傻瓜式的方便搞定项目中的各种奇怪的需求最好了,不用烧脑,本来程序猿的生活就是枯燥的,不要再给自己添加更多的烦恼. 今天,就为了 ...
- SpringBoot中的@ConfigurationProperties
有什么用 该注解的作用类似于@Value,即为组件中的属性进行赋值. 怎么用 首先是建立一个springboot的工程,不再赘述. 首先我们建立一个Person类和一个Dog类. package co ...
随机推荐
- C语言:如何删除超链接
单独写出一个函数出来,基本思想就是用fscanf一个一个字符读取出来,(文本流只能用fscanf,不能用fgetc等用于二进制流的函数,不然会导致乱码)遇到<的时候就停止读取,先把之前存进cop ...
- PageOffice6 版本常用事件
1.AfterDocumentOpened 事件 打开文件后自动触发的事件是 AfterDocumentOpened 事件,它通常用于实现文件打开后自动执行某些业务逻辑,比如将默认控件全屏.禁止保存. ...
- redis持久化存储数据(rdb和aof)
rdb持久化存储数据 总的 redis持久化 防止数据丢失,持久化到本地,以文件形式保存 持久化的方式 ,两种 aof和 rdb模式 1.触发机制, - 手动执行save命令 - 或者配置触发条件 s ...
- 统计学习:EM算法及其在高斯混合模型(GMM)中的应用
1. EM算法的基本思想 我们在应用中所面对的数据有时是缺损的/观测不完全的[1][2].我们将数据分为: 可观测数据,用\(Y\)表示: 缺失数据,用\(Z\)表示; 完全数据,用\(X=(Y, Z ...
- redis安装和基础使用
redis安装 mkdir /server/tools -p cd /server/tools echo 'PATH=/usr/local/redis/src:$PATH' >>/etc/ ...
- uniapp SyntaxError: Unexpected token u in JSON at position 0 解决方案
今天在做页面跳转传值的时候,一直出现下面的报错: 后来查看了下文档,说如果你的JSON数据是在上一个页面传值过来的话, 这时候在接收数据页解析JSON也会报该错误,因为此时并没有相关的JSON数据从上 ...
- 使用Wesky.Net.Opentools库,一行代码实现自动解析实体类summary注释信息(可用于数据实体文档的快速实现)
使用前,需要对你的项目勾选输出api文档文件. 引用Wesky.Net.OpenTools包,保持1.0.11版本或以上. 为了方便,我直接在昨天的演示基础上,继续给实体类添加注释. 昨天的演示文 ...
- css做多列瀑布流
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...
- ETL工具-nifi干货系列 第十八讲 nifi Funnel实战教程
1.Funnel (漏斗),Funnel是 NiFi 组件,用于将多个连接中的数据合并到一个连接中. 使用场景:nifi中的Funnel组件用于合并多个数据流并将它们传递到下游处理器.它可以将来自不同 ...
- 实现并发新高度:23ai的无锁列值保留
Oracle Database 23ai支持Lock-Free Reservation,中文通常译为"无锁列值保留". 本文将通过3个部分来阐述Lock-Free Reservat ...