diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml
index 87311e4f8..9d3ca7b04 100644
--- a/ruoyi-admin/pom.xml
+++ b/ruoyi-admin/pom.xml
@@ -23,6 +23,12 @@
spring-boot-starter-thymeleaf
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
org.springframework.boot
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/CacheConfig.java b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/CacheConfig.java
new file mode 100644
index 000000000..ed59d8afe
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/CacheConfig.java
@@ -0,0 +1,68 @@
+package com.ruoyi.web.core.config;
+
+import com.alibaba.fastjson.JSON;
+import com.google.common.collect.Maps;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cache.Cache;
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cache.ehcache.EhCacheCacheManager;
+import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.data.redis.cache.RedisCacheConfiguration;
+import org.springframework.data.redis.cache.RedisCacheManager;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+
+import java.time.Duration;
+import java.util.Map;
+
+@EnableCaching
+@Configuration
+public class CacheConfig {
+ @Autowired(required = false)
+ RedisConnectionFactory redisConnectionFactory;
+ //默认超时设置1小时
+ @Value("${spring.redis.defaultExpiration:3600}")
+ Duration defaultExpiration;
+ //自定义部分缓存的超时
+ @Value("${spring.redis.expires}")
+ String expires = "{}";
+
+ @Bean
+ public CacheManager cacheManager() {
+ if (redisConnectionFactory != null) {
+ try {
+ //配置有redis standalone或cluster,并且能正常连接时才启用redis缓存
+ redisConnectionFactory.getConnection().ping();
+ System.err.println("using redis cache manager");
+ RedisCacheManager redisCacheManager = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults
+ (RedisCacheConfiguration.defaultCacheConfig().entryTtl(defaultExpiration))
+ .withInitialCacheConfigurations(Maps.transformValues(JSON.parseObject(expires, Map.class), d ->
+ RedisCacheConfiguration
+ .defaultCacheConfig().entryTtl(Duration.ofSeconds(Long.valueOf(d.toString())))))
+ .transactionAware().build();
+ return redisCacheManager;
+ } catch (Exception e) {
+ System.err.println("fail to connect to redis");
+ }
+ }
+ EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();
+ ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource("classpath:ehcache/ehcache-shiro.xml"));
+ ehCacheManagerFactoryBean.setShared(true);
+ return new EhCacheCacheManager(ehCacheManagerFactoryBean.getObject()) {
+ @Override
+ protected Cache getMissingCache(String name) {
+ Cache cache = super.getMissingCache(name);
+ if (cache == null) {
+ //使用default配置克隆缓存
+ getCacheManager().addCacheIfAbsent(name);
+ cache = super.getCache(name);
+ }
+ return cache;
+ }
+ };
+ }
+}
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index 92a78b141..b92c1189d 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -69,6 +69,22 @@ spring:
restart:
# 热部署开关
enabled: true
+ # redis配置
+ redis:
+ host: localhost
+ port: 6379
+ password:
+ timeout: 1500ms
+ # redis连接池配置
+ jedis:
+ pool:
+ min-idle: 1
+ # redis集群配置,逗号分隔多个host:port
+# cluster:
+# nodes: 127.0.0.1:6381,127.0.0.1:6382
+ # 默认缓存超时1小时,启动时可初始化多个缓存并指定超时N秒
+ defaultExpiration: 1h
+ expires: '{ "loginRecordCache": "600" }'
# MyBatis
mybatis:
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ShiroConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ShiroConfig.java
index 721baf37b..d56faeb1e 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ShiroConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ShiroConfig.java
@@ -6,6 +6,8 @@ import java.io.InputStream;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.servlet.Filter;
+
+import com.ruoyi.framework.shiro.cache.SpringCacheManagerWrapper;
import org.apache.commons.io.IOUtils;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.codec.Base64;
@@ -17,8 +19,10 @@ import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.ruoyi.common.utils.StringUtils;
@@ -93,23 +97,27 @@ public class ShiroConfig
@Value("${shiro.user.unauthorizedUrl}")
private String unauthorizedUrl;
+ @Autowired(required = false)
+ private CacheManager cacheManager;
+
/**
- * 缓存管理器 使用Ehcache实现
+ * 缓存管理器 使用Spring CacheManager或Ehcache实现
*/
@Bean
- public EhCacheManager getEhCacheManager()
+ public org.apache.shiro.cache.CacheManager getEhCacheManager()
{
- net.sf.ehcache.CacheManager cacheManager = net.sf.ehcache.CacheManager.getCacheManager("ruoyi");
- EhCacheManager em = new EhCacheManager();
- if (StringUtils.isNull(cacheManager))
- {
- em.setCacheManager(new net.sf.ehcache.CacheManager(getCacheManagerConfigFileInputStream()));
- return em;
- }
- else
- {
- em.setCacheManager(cacheManager);
- return em;
+ if(cacheManager != null){
+ return new SpringCacheManagerWrapper(cacheManager);
+ }else {
+ net.sf.ehcache.CacheManager cacheManager = net.sf.ehcache.CacheManager.getCacheManager("ruoyi");
+ EhCacheManager em = new EhCacheManager();
+ if (StringUtils.isNull(cacheManager)) {
+ em.setCacheManager(new net.sf.ehcache.CacheManager(getCacheManagerConfigFileInputStream()));
+ return em;
+ } else {
+ em.setCacheManager(cacheManager);
+ return em;
+ }
}
}
@@ -142,7 +150,7 @@ public class ShiroConfig
* 自定义Realm
*/
@Bean
- public UserRealm userRealm(EhCacheManager cacheManager)
+ public UserRealm userRealm(org.apache.shiro.cache.CacheManager cacheManager)
{
UserRealm userRealm = new UserRealm();
userRealm.setCacheManager(cacheManager);
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/cache/SpringCacheManagerWrapper.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/cache/SpringCacheManagerWrapper.java
new file mode 100644
index 000000000..02020d192
--- /dev/null
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/cache/SpringCacheManagerWrapper.java
@@ -0,0 +1,22 @@
+package com.ruoyi.framework.shiro.cache;
+
+
+import org.apache.shiro.cache.Cache;
+import org.apache.shiro.cache.CacheException;
+import org.apache.shiro.cache.CacheManager;
+
+/** 包装Spring CacheManager为Shiro CacheManager */
+public class SpringCacheManagerWrapper implements CacheManager {
+
+ private org.springframework.cache.CacheManager cacheManager;
+
+ public SpringCacheManagerWrapper(org.springframework.cache.CacheManager cacheManager) {
+ this.cacheManager = cacheManager;
+ }
+
+ @Override
+ public Cache getCache(String name) throws CacheException {
+ org.springframework.cache.Cache springCache = cacheManager.getCache(name);
+ return new SpringCacheWrapper(springCache);
+ }
+}
\ No newline at end of file
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/cache/SpringCacheWrapper.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/cache/SpringCacheWrapper.java
new file mode 100644
index 000000000..2c19a3a6b
--- /dev/null
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/cache/SpringCacheWrapper.java
@@ -0,0 +1,106 @@
+package com.ruoyi.framework.shiro.cache;
+
+import net.sf.ehcache.Ehcache;
+import org.apache.shiro.cache.Cache;
+import org.apache.shiro.cache.CacheException;
+import org.apache.shiro.util.CollectionUtils;
+import org.springframework.cache.support.SimpleValueWrapper;
+
+import java.util.*;
+
+/** 包装Spring Cache为Shiro Cache */
+public class SpringCacheWrapper implements Cache {
+ private org.springframework.cache.Cache springCache;
+ private boolean isEhcache;
+ private Set