目录
注1:当spring-context.xml中需要注册多个.properties,那么
不能在spering-*.xml中添加注册
注2:resources的配置必须要涵盖读取.preperties 结尾的文件
注3:redisTemplate的使用,可以参照jdbcTemplate,amqpTemplate,rabbitMQtemplate

- "1.0" encoding="UTF-8"?>
-
"http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
4.0.0 -
-
org.example -
ssm2 -
1.0-SNAPSHOT -
war -
-
ssm2 Maven Webapp -
-
http://www.example.com -
-
UTF-8 -
1.8 -
1.8 -
3.7.0 -
-
-
5.0.2.RELEASE -
-
3.4.5 -
-
5.1.44 -
-
5.1.2 -
-
1.3.1 -
-
2.1.1 -
2.4.3 -
-
2.9.1 -
-
4.12 -
4.0.0 -
1.18.2 -
2.10.0 -
1.7.7 -
2.9.0 -
1.7.1.RELEASE -
-
-
-
-
org.springframework -
spring-context -
${spring.version} -
-
-
org.springframework -
spring-orm -
${spring.version} -
-
-
org.springframework -
spring-tx -
${spring.version} -
-
-
org.springframework -
spring-aspects -
${spring.version} -
-
-
org.springframework -
spring-web -
${spring.version} -
-
-
org.springframework -
spring-test -
${spring.version} -
-
-
-
org.mybatis -
mybatis -
${mybatis.version} -
-
-
-
mysql -
mysql-connector-java -
${mysql.version} -
-
-
-
com.github.pagehelper -
pagehelper -
${pagehelper.version} -
-
-
-
org.mybatis -
mybatis-spring -
${mybatis.spring.version} -
-
-
-
org.apache.commons -
commons-dbcp2 -
${commons.dbcp2.version} -
-
-
org.apache.commons -
commons-pool2 -
${commons.pool2.version} -
-
-
-
-
org.apache.logging.log4j -
log4j-core -
${log4j2.version} -
-
-
org.apache.logging.log4j -
log4j-api -
${log4j2.version} -
-
-
-
org.apache.logging.log4j -
log4j-web -
${log4j2.version} -
-
-
-
junit -
junit -
${junit.version} -
test -
-
-
javax.servlet -
javax.servlet-api -
${servlet.version} -
provided -
-
-
org.projectlombok -
lombok -
${lombok.version} -
provided -
-
-
org.springframework -
spring-webmvc -
${spring.version} -
-
-
-
javax.servlet.jsp -
javax.servlet.jsp-api -
2.3.3 -
-
-
jstl -
jstl -
1.2 -
-
-
taglibs -
standard -
1.1.2 -
-
-
commons-fileupload -
commons-fileupload -
1.3.3 -
-
-
org.hibernate -
hibernate-validator -
6.0.7.Final -
-
-
com.fasterxml.jackson.core -
jackson-databind -
2.9.3 -
-
-
com.fasterxml.jackson.core -
jackson-core -
2.9.3 -
-
-
com.fasterxml.jackson.core -
jackson-annotations -
2.9.3 -
-
-
org.apache.shiro -
shiro-core -
1.3.2 -
-
-
org.apache.shiro -
shiro-web -
1.3.2 -
-
-
org.apache.shiro -
shiro-spring -
1.3.2 -
-
-
net.sf.ehcache -
ehcache -
${ehcache.version} -
-
-
-
org.slf4j -
slf4j-api -
${slf4j-api.version} -
-
-
org.slf4j -
jcl-over-slf4j -
${slf4j-api.version} -
runtime -
-
-
-
org.apache.logging.log4j -
log4j-slf4j-impl -
${log4j2.version} -
-
-
redis.clients -
jedis -
${redis.version} -
-
-
org.springframework.data -
spring-data-redis -
${redis.spring.version} -
-
-
-
ssm2 -
-
-
-
src/main/java -
-
**/*.xml -
-
-
-
-
src/main/resources -
-
*.properties -
*.xml -
-
-
-
-
-
-
org.apache.maven.plugins -
maven-compiler-plugin -
${maven.compiler.plugin.version} -
-
${maven.compiler.source} -
${maven.compiler.target} -
${project.build.sourceEncoding} -
-
-
-
org.mybatis.generator -
mybatis-generator-maven-plugin -
1.3.2 -
-
-
-
mysql -
mysql-connector-java -
${mysql.version} -
-
-
-
true -
-
-
-
maven-clean-plugin -
3.1.0 -
-
-
-
maven-resources-plugin -
3.0.2 -
-
-
maven-compiler-plugin -
3.8.0 -
-
-
maven-surefire-plugin -
2.22.1 -
-
-
maven-war-plugin -
3.2.2 -
-
-
maven-install-plugin -
2.5.2 -
-
-
maven-deploy-plugin -
2.8.2 -
-
-
-
- "1.0" encoding="UTF-8"?>
"http://www.springframework.org/schema/beans" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:cache="http://www.springframework.org/schema/cache"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context.xsd
- http://www.springframework.org/schema/cache
- http://www.springframework.org/schema/cache/spring-cache.xsd">
-
-
-
-
-
-
"poolConfig" class="redis.clients.jedis.JedisPoolConfig"> -
-
"maxIdle" value="${redis.maxIdle}"/> -
-
"maxTotal" value="${redis.maxTotal}"/> -
-
"maxWaitMillis" value="${redis.maxWaitMillis}"/> -
-
"minEvictableIdleTimeMillis" value="${redis.minEvictableIdleTimeMillis}"/> -
-
"numTestsPerEvictionRun" value="${redis.numTestsPerEvictionRun}"/> -
-
"timeBetweenEvictionRunsMillis" value="${redis.timeBetweenEvictionRunsMillis}"/> -
-
"testOnBorrow" value="${redis.testOnBorrow}"/> -
-
"testWhileIdle" value="${redis.testWhileIdle}"/> -
-
-
-
"connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" - destroy-method="destroy">
-
"poolConfig" ref="poolConfig"/> -
-
"hostName" value="${redis.hostName}"/> -
-
"port" value="${redis.port}"/> -
-
"password" value="${redis.password}"/> -
-
"timeout" value="${redis.timeout}"/> -
-
-
-
"redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> -
"connectionFactory" ref="connectionFactory"/> -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- redis.hostName=localhost
- redis.port=6379
- redis.password=123456
- redis.timeout=10000
- redis.maxIdle=300
- redis.maxTotal=1000
- redis.maxWaitMillis=1000
- redis.minEvictableIdleTimeMillis=300000
- redis.numTestsPerEvictionRun=1024
- redis.timeBetweenEvictionRunsMillis=30000
- redis.testOnBorrow=true
- redis.testWhileIdle=true
- redis.expiration=3600
- package com.zking.ssm.redis;
-
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.cache.interceptor.KeyGenerator;
- import org.springframework.util.ClassUtils;
-
- import java.lang.reflect.Array;
- import java.lang.reflect.Method;
-
- @Slf4j
- public class CacheKeyGenerator implements KeyGenerator {
- // custom cache key
- public static final int NO_PARAM_KEY = 0;
- public static final int NULL_PARAM_KEY = 53;
-
- @Override
- public Object generate(Object target, Method method, Object... params) {
- StringBuilder key = new StringBuilder();
- key.append(target.getClass().getSimpleName()).append(".").append(method.getName()).append(":");
- if (params.length == 0) {
- key.append(NO_PARAM_KEY);
- } else {
- int count = 0;
- for (Object param : params) {
- if (0 != count) {//参数之间用,进行分隔
- key.append(',');
- }
- if (param == null) {
- key.append(NULL_PARAM_KEY);
- } else if (ClassUtils.isPrimitiveArray(param.getClass())) {
- int length = Array.getLength(param);
- for (int i = 0; i < length; i++) {
- key.append(Array.get(param, i));
- key.append(',');
- }
- } else if (ClassUtils.isPrimitiveOrWrapper(param.getClass()) || param instanceof String) {
- key.append(param);
- } else {//Java一定要重写hashCode和eqauls
- key.append(param.hashCode());
- }
- count++;
- }
- }
-
- String finalKey = key.toString();
- // IEDA要安装lombok插件
- log.debug("using cache key={}", finalKey);
- return finalKey;
- }
- }
@Cacheable 配置在方法或类上,作用:本方法执行后,先去缓存看有没有数据,如果没有,从数据库中查找出来,给缓存中存一份,返回结果, 下次本方法执行,在缓存未过期情况下,先在缓存中查找,有的话直接返回,没有的话从数据库查找
@CachePut 类似于更新操作,即每次不管缓存中有没有结果,都从数据库查找结果,并将结果更新到缓存,并返回结果
@CacheEvict 用来清除用在本方法或者类上的缓存数据(用在哪里清除哪里)
定义查询接口使用Cacheable注解
编写测试类
测试结果
再次运行相同的数据时不再查询了,直接从缓冲中拿取数据:
@Cacheable可以指定三个属性,value、key和condition。

它的使用与Cacheable的使用一致,它们的区别:
- Cacheable:会在redis中存储数据,同时也会读取数据
- CachePut:只会在redis储存数据,不会进行读取操作
测试类
测试结果
当一个在缓存中不存在但是经常查询的 key 被请求时,大量的请求会穿透缓存直接到达数据库,导致数据库压力过大,影响系统性能。
解决方法:
使用布隆过滤器,将所有可能出现的查询 key 存入布隆过滤器中,如果布隆过滤器返回不存在该 key,则直接返回不存在即可,避免了对底层存储系统的查询操作,减小了数据库的压力。
当存在大量的恶意请求或者访问不存在的 key 时,这些请求会穿透缓存直接到达底层存储系统,导致底层存储系统压力过大,甚至会导致底层存储系统崩溃。
解决方法:
也是使用布隆过滤器,在布隆过滤器返回不存在该 key 时,不再直接查询底层存储系统,而是将请求拦截。
当 Redis 缓存中大量的数据过期后,同时有大量请求访问这些已经过期的数据时,这些请求会穿透 Redis 直接到达底层存储系统,导致底层存储系统压力过大,甚至崩溃。
解决方法:
使用分布式锁和缓存预热。对于 Redis 中的数据,定期进行缓存预热,提高缓存命中率;同时对于热点数据,可以使用分布式锁,保证在数据过期时,只有一个请求去查询底层存储系统,并在查询完数据后重新设置缓存。