缓存

页面中权限的数据每次访问都会与数据库进行一次交互 这样就导致用户数量多的时候 访问量大的时候 就会导致数据库压力过大

所以为了避免这种问题 就需要给权限的数据加缓存 这样需要权限的时候对于已经授权的用户就不用与数据库交互 直接在缓存中去找对应的权限就好了 可以尽量减轻数据库的压力

CacheManager

Cache作用

  • Cache缓存:计算机内存中一段数据 内存条

  • 作用:用来减轻DB的访问压力,从而提高系统的查询效率

  • 流程:
    avatar

这里要注意 只有查询次数多并且增删改极少的数据才适合存入缓存中

EhCache实现缓存

  1. 引入依赖
1
2
3
4
5
6
<!--        shiro-ehcache-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.5.3</version>
</dependency>
  1. 开启缓存管理

在ShiroConfig中开启缓存管理
添加代码

1
2
3
4
5
6
7
//开启缓存管理
customerRealm.setCacheManager(new RedisCacheManager());
customerRealm.setCachingEnabled(true);//开启全局缓存
customerRealm.setAuthenticationCachingEnabled(true);//认证认证缓存
customerRealm.setAuthenticationCacheName("authenticationCache");
customerRealm.setAuthorizationCachingEnabled(true);//开启授权缓存
customerRealm.setAuthorizationCacheName("authorizationCache");

开启之后 只有第一次会操作我们的数据库 之后就不会操作数据库了 因为已经存到了缓存当中
但是使用这样的方法会有个缺点,就是如果当服务器断电或宕机时,重新访问依然会操作数据库,所以可以使用Redis来实现一个分布式缓存

Redis实现缓存

  1. 引入redis依赖
    1
    2
    3
    4
    5
    <!--redis整合springboot-->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
  2. 配置redis连接
    注意进行这步之前 需要先安装redis 确保正常运行
    在application.properties添加
    1
    2
    3
    spring.redis.port=6379
    spring.redis.host=localhost
    spring.redis.database=0
  3. 自定义缓存管理器

先在shiro下创建一个新的包cache
新建一个RedisCacheManager.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.ceit.springboot_jsp_shiro.shiro.cache;

import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.cache.CacheManager;

//自定义shiro缓存管理器
public class RedisCacheManager implements CacheManager {

//参数1:认证或者是授权缓存的统一名称
@Override
public <K, V> Cache<K, V> getCache(String cacheName) throws CacheException {
System.out.println(cacheName);
return new RedisCache<K,V>(cacheName);
}
}

这个时候就可以修改ShiroConfig的缓存管理器指定我们自定义的Redis管理器
ShiroConfig

1
customerRealm.setCacheManager(new RedisCacheManager());

再写一个RedisCache.java 这个才是真正实现缓存的操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package com.ceit.springboot_jsp_shiro.shiro.cache;

import com.ceit.springboot_jsp_shiro.utils.ApplicationContextUtils;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.util.Collection;
import java.util.Set;

//自定义redis缓存的实现
public class RedisCache<k,v> implements Cache<k,v> {

private String cacheName;

public RedisCache() {
}

public RedisCache(String cacheName) {
this.cacheName = cacheName;
}

@Override
public v get(k k) throws CacheException {
System.out.println("get key:"+k);
return (v) getRedisTemplate().opsForHash().get(this.cacheName,k.toString());
}

@Override
public v put(k k, v v) throws CacheException {
System.out.println("put key: "+k);
System.out.println("put value:"+v);
getRedisTemplate().opsForHash().put(this.cacheName,k.toString(),v);
return null;
}

@Override
public v remove(k k) throws CacheException {
System.out.println("=============remove=============");
return (v) getRedisTemplate().opsForHash().delete(this.cacheName,k.toString());
}

@Override
public void clear() throws CacheException {
System.out.println("=============clear==============");
getRedisTemplate().delete(this.cacheName);
}

@Override
public int size() {
return getRedisTemplate().opsForHash().size(this.cacheName).intValue();
}

@Override
public Set<k> keys() {
return getRedisTemplate().opsForHash().keys(this.cacheName);
}

@Override
public Collection<v> values() {
return getRedisTemplate().opsForHash().values(this.cacheName);
}

private RedisTemplate getRedisTemplate(){
RedisTemplate redisTemplate = (RedisTemplate) ApplicationContextUtils.getBean("redisTemplate");
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
return redisTemplate;
}
}

package com.ceit.springboot_jsp_shiro.shiro.cache;

import com.ceit.springboot_jsp_shiro.utils.ApplicationContextUtils;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.util.Collection;
import java.util.Set;

//自定义redis缓存的实现
public class RedisCache<k,v> implements Cache<k,v> {

private String cacheName;

public RedisCache() {
}

public RedisCache(String cacheName) {
this.cacheName = cacheName;
}

@Override
public v get(k k) throws CacheException {
System.out.println("get key:"+k);
return (v) getRedisTemplate().opsForHash().get(this.cacheName,k.toString());
}

@Override
public v put(k k, v v) throws CacheException {
System.out.println("put key: "+k);
System.out.println("put value:"+v);
getRedisTemplate().opsForHash().put(this.cacheName,k.toString(),v);
return null;
}

@Override
public v remove(k k) throws CacheException {
System.out.println("=============remove=============");
return (v) getRedisTemplate().opsForHash().delete(this.cacheName,k.toString());
}

@Override
public void clear() throws CacheException {
System.out.println("=============clear==============");
getRedisTemplate().delete(this.cacheName);
}

@Override
public int size() {
return getRedisTemplate().opsForHash().size(this.cacheName).intValue();
}

@Override
public Set<k> keys() {
return getRedisTemplate().opsForHash().keys(this.cacheName);
}

@Override
public Collection<v> values() {
return getRedisTemplate().opsForHash().values(this.cacheName);
}

private RedisTemplate getRedisTemplate(){
RedisTemplate redisTemplate = (RedisTemplate) ApplicationContextUtils.getBean("redisTemplate");
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
return redisTemplate;
}
}