怎么在SpringBoot中使用redis和Ehcache緩存Shiro?相信很多沒(méi)有經(jīng)驗(yàn)的人對(duì)此束手無(wú)策,為此本文總結(jié)了問(wèn)題出現(xiàn)的原因和解決方法,通過(guò)這篇文章希望你能解決這個(gè)問(wèn)題。
創(chuàng)新互聯(lián)主要從事成都網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)伊川,十余年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來(lái)電咨詢建站服務(wù):18980820575
第一種:Redis緩存,將數(shù)據(jù)存儲(chǔ)到redis 并且開啟session存入redis中。
引入pom
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency>
配置redisConfig
@Configuration @EnableCaching public class RedisConfig extends CachingConfigurerSupport { @Bean public KeyGenerator keyGenerator() { return new KeyGenerator() { @Override public Object generate(Object target, Method method, Object... params) { StringBuilder sb = new StringBuilder(); sb.append(target.getClass().getName()); sb.append(method.getName()); for (Object obj : params) { sb.append(obj.toString()); } return sb.toString(); } }; } @Bean //在這里配置緩存reids配置 public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) { RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofHours(1)); // 設(shè)置緩存有效期一小時(shí) System.out.println("《========【開啟redis】 ======== 》 "); return RedisCacheManager .builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory)) .cacheDefaults(redisCacheConfiguration).build(); } @Bean public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) { StringRedisTemplate template = new StringRedisTemplate(factory); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); template.setValueSerializer(jackson2JsonRedisSerializer); template.afterPropertiesSet(); return template; } }
配置自定義緩存管理器,引入redis緩存管理器
定義自己的CacheManager
/** * <p> 自定義cacheManage 擴(kuò)張shiro里面的緩存 使用reids作緩存 </p> * <description> * 引入自己定義的CacheManager * 關(guān)于CacheManager的配置文件在spring-redis-cache.xml中 * </description> */ @Component public class ShiroSpringCacheManager implements CacheManager ,Destroyable{ /** * 將之上的RedisCacheManager的Bean拿出來(lái) 注入于此 */ @Autowired private org.springframework.cache.CacheManager cacheManager; public org.springframework.cache.CacheManager getCacheManager() { return cacheManager; } public void setCacheManager(org.springframework.cache.CacheManager cacheManager) { this.cacheManager = cacheManager; } @Override public void destroy() throws Exception { cacheManager = null; } @Override public <K, V> Cache<K, V> getCache(String name) { if (name == null ){ return null; } // 新建一個(gè)ShiroSpringCache 將Bean放入并實(shí)例化 return new ShiroSpringCache<K,V>(name,getCacheManager()); } }
定義自己實(shí)現(xiàn)的Shiro的Cache,實(shí)現(xiàn)了Shiro包里的Cache
/** * <p> 自定義緩存 將數(shù)據(jù)存入到redis中 </p> */ @SuppressWarnings("unchecked") public class ShiroSpringCache<K,V> implements org.apache.shiro.cache.Cache<K, V>{ private static final Logger log = LoggerFactory.getLogger(ShiroSpringCache.class); private CacheManager cacheManager; private Cache cache; public ShiroSpringCache(String name, CacheManager cacheManager) { if(name==null || cacheManager==null){ throw new IllegalArgumentException("cacheManager or CacheName cannot be null."); } this.cacheManager = cacheManager; //這里首先是從父類中獲取這個(gè)cache,如果沒(méi)有會(huì)創(chuàng)建一個(gè)redisCache,初始化這個(gè)redisCache的時(shí)候 //會(huì)設(shè)置它的過(guò)期時(shí)間如果沒(méi)有配置過(guò)這個(gè)緩存的,那么默認(rèn)的緩存時(shí)間是為0的,如果配置了,就會(huì)把配置的時(shí)間賦予給這個(gè)RedisCache //如果從緩存的過(guò)期時(shí)間為0,就表示這個(gè)RedisCache不存在了,這個(gè)redisCache實(shí)現(xiàn)了spring中的cache this.cache= cacheManager.getCache(name); } @Override public V get(K key) throws CacheException { log.info("從緩存中獲取key為{}的緩存信息",key); if(key == null){ return null; } ValueWrapper valueWrapper = cache.get(key); if(valueWrapper==null){ return null; } return (V) valueWrapper.get(); } @Override public V put(K key, V value) throws CacheException { log.info("創(chuàng)建新的緩存,信息為:{}={}",key,value); cache.put(key, value); return get(key); } @Override public V remove(K key) throws CacheException { log.info("干掉key為{}的緩存",key); V v = get(key); cache.evict(key);//干掉這個(gè)名字為key的緩存 return v; } @Override public void clear() throws CacheException { log.info("清空所有的緩存"); cache.clear(); } @Override public int size() { return cacheManager.getCacheNames().size(); } /** * 獲取緩存中所的key值 */ @Override public Set<K> keys() { return (Set<K>) cacheManager.getCacheNames(); } /** * 獲取緩存中所有的values值 */ @Override public Collection<V> values() { return (Collection<V>) cache.get(cacheManager.getCacheNames()).get(); } @Override public String toString() { return "ShiroSpringCache [cache=" + cache + "]"; } }
到此為止,使用redis做緩存,和spring的集成就完成了。
可以使用以下注解將緩存放入redis
@Cacheable(value = Cache.CONSTANT, key = "'" + CacheKey.DICT_NAME + "'+#name+'_'+#val")
配置spring session管理器
@Bean @ConditionalOnProperty(prefix = "xpro", name = "spring-session-open", havingValue = "true") public ServletContainerSessionManager servletContainerSessionManager() { return new ServletContainerSessionManager(); }
新建類 spring session設(shè)置session過(guò)期時(shí)間
/** * spring session配置 * * @author xingri * @date 2017-07-13 21:05 */ @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 900) //session過(guò)期時(shí)間 如果部署多機(jī)環(huán)境,需要打開注釋 @ConditionalOnProperty(prefix = "xpro", name = "spring-session-open", havingValue = "true") public class SpringSessionConfig { }
第一種:Ehcache做緩存,可以將數(shù)據(jù)存儲(chǔ)到磁盤中,也可以存到內(nèi)存中
新建ehcache.xml 文件
<?xml version="1.0" encoding="UTF-8"?> <ehcache updateCheck="false" dynamicConfig="false"> <diskStore path="java.io.tmpdir"/> <!--授權(quán)信息緩存--> <cache name="authorizationCache" maxEntriesLocalHeap="2000" eternal="false" timeToIdleSeconds="1800" timeToLiveSeconds="1800" overflowToDisk="false" statistics="true"> </cache> <!--身份信息緩存--> <cache name="authenticationCache" maxEntriesLocalHeap="2000" eternal="false" timeToIdleSeconds="1800" timeToLiveSeconds="1800" overflowToDisk="false" statistics="true"> </cache> <!--session緩存--> <cache name="activeSessionCache" maxEntriesLocalHeap="2000" eternal="false" timeToIdleSeconds="1800" timeToLiveSeconds="1800" overflowToDisk="false" statistics="true"> </cache> <!-- 緩存半小時(shí) --> <cache name="halfHour" maxElementsInMemory="10000" maxElementsOnDisk="100000" eternal="false" timeToIdleSeconds="1800" timeToLiveSeconds="1800" overflowToDisk="false" diskPersistent="false" /> <!-- 緩存一小時(shí) --> <cache name="hour" maxElementsInMemory="10000" maxElementsOnDisk="100000" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="3600" overflowToDisk="false" diskPersistent="false" /> <!-- 緩存一天 --> <cache name="oneDay" maxElementsInMemory="10000" maxElementsOnDisk="100000" eternal="false" timeToIdleSeconds="86400" timeToLiveSeconds="86400" overflowToDisk="false" diskPersistent="false" /> <!-- name:緩存名稱。 maxElementsInMemory:緩存最大個(gè)數(shù)。 eternal:對(duì)象是否永久有效,一但設(shè)置了,timeout將不起作用。 timeToIdleSeconds:設(shè)置對(duì)象在失效前的允許閑置時(shí)間(單位:秒)。僅當(dāng)eternal=false對(duì)象不是永久有效時(shí)使用,可選屬性,默認(rèn)值是0,也就是可閑置時(shí)間無(wú)窮大。 timeToLiveSeconds:設(shè)置對(duì)象在失效前允許存活時(shí)間(單位:秒)。最大時(shí)間介于創(chuàng)建時(shí)間和失效時(shí)間之間。僅當(dāng)eternal=false對(duì)象不是永久有效時(shí)使用,默認(rèn)是0.,也就是對(duì)象存活時(shí)間無(wú)窮大。 overflowToDisk:當(dāng)內(nèi)存中對(duì)象數(shù)量達(dá)到maxElementsInMemory時(shí),Ehcache將會(huì)對(duì)象寫到磁盤中。 diskSpoolBufferSizeMB:這個(gè)參數(shù)設(shè)置DiskStore(磁盤緩存)的緩存區(qū)大小。默認(rèn)是30MB。每個(gè)Cache都應(yīng)該有自己的一個(gè)緩沖區(qū)。 maxElementsOnDisk:硬盤最大緩存?zhèn)€數(shù)。 diskPersistent:是否緩存虛擬機(jī)重啟期數(shù)據(jù) Whether the disk store persists between restarts of the Virtual Machine. The default value is false. diskExpiryThreadIntervalSeconds:磁盤失效線程運(yùn)行時(shí)間間隔,默認(rèn)是120秒。 memoryStoreEvictionPolicy:當(dāng)達(dá)到maxElementsInMemory限制時(shí),Ehcache將會(huì)根據(jù)指定的策略去清理內(nèi)存。默認(rèn)策略是LRU(最近最少使用)。你可以設(shè)置為FIFO(先進(jìn)先出)或是LFU(較少使用)。 clearOnFlush:內(nèi)存數(shù)量最大時(shí)是否清除。 --> <defaultCache name="defaultCache" maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="600" timeToLiveSeconds="600" overflowToDisk="false" maxElementsOnDisk="100000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"/> </ehcache>
配置自定義緩存管理器,引入ehcache緩存管理器
/** * ehcache配置 * */ @Configuration @EnableCaching public class EhCacheConfig { /** * EhCache的配置 */ @Bean public EhCacheCacheManager cacheManager(CacheManager cacheManager) { MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer(); ManagementService.registerMBeans(cacheManager, mBeanServer, true, true, true, true); return new EhCacheCacheManager(cacheManager); } /** * EhCache的配置 */ @Bean public EhCacheManagerFactoryBean ehcache() { System.out.println("《========【開啟ehcache】 ======== 》 "); EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean(); ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache.xml")); return ehCacheManagerFactoryBean; } @Bean public org.apache.shiro.cache.CacheManager getCacheShiroManager(EhCacheManagerFactoryBean ehcache) { EhCacheManager ehCacheManager = new EhCacheManager(); ehCacheManager.setCacheManager(ehcache.getObject()); return ehCacheManager; } }
最后 最重要的是引入shriro 中
/** * shiro權(quán)限管理的配置 * */ @Configuration public class ShiroConfig { /** * 安全管理器 */ @Bean public DefaultWebSecurityManager securityManager(CookieRememberMeManager rememberMeManager, CacheManager cacheShiroManager, SessionManager sessionManager) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setAuthenticator(modularRealmAuthenticator()); List<Realm> realms=new ArrayList<>(); securityManager.setRealms(realms); securityManager.setCacheManager(cacheShiroManager); securityManager.setRememberMeManager(rememberMeManager); securityManager.setSessionManager(sessionManager); return securityManager; } /** * spring session管理器(多機(jī)環(huán)境) */ @Bean public ServletContainerSessionManager servletContainerSessionManager() { return new ServletContainerSessionManager(); } /** * session管理器(單機(jī)環(huán)境) 使用cookie存儲(chǔ)緩存。。如果多級(jí)請(qǐng)注釋 */ @Bean public DefaultWebSessionManager defaultWebSessionManager(CacheManager cacheShiroManager, XProProperties xProProperties) { DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); sessionManager.setCacheManager(cacheShiroManager); sessionManager.setSessionValidationInterval(xProProperties.getSessionValidationInterval() * 1000); sessionManager.setGlobalSessionTimeout(xProProperties.getSessionInvalidateTime() * 1000); sessionManager.setDeleteInvalidSessions(true); sessionManager.setSessionValidationSchedulerEnabled(true); Cookie cookie = new SimpleCookie(ShiroHttpSession.DEFAULT_SESSION_ID_NAME); cookie.setName("shiroCookie"); cookie.setHttpOnly(true); sessionManager.setSessionIdCookie(cookie); return sessionManager; } /** * 緩存管理器 使用Ehcache實(shí)現(xiàn) 如果使用redis則注釋下面內(nèi)容?。。?! */ @Bean public CacheManager getCacheShiroManager(EhCacheManagerFactoryBean ehcache) { EhCacheManager ehCacheManager = new EhCacheManager(); ehCacheManager.setCacheManager(ehcache.getObject()); return ehCacheManager; } /** * 項(xiàng)目自定義的Realm */ @Bean public ShiroDbRealm shiroDbRealm() { return new ShiroDbRealm(); } @Bean public ShiroTockenRealm shiroTockenRealm( ) { return new ShiroTockenRealm(); } @Bean public ShiroJwtRealm shiroJwtRealm( ) { return new ShiroJwtRealm(); } /** * 系統(tǒng)自帶的Realm管理,主要針對(duì)多realm * */ @Bean public ModularRealmAuthenticator modularRealmAuthenticator(){ ModularRealmAuthenticator modularRealmAuthenticator=new ModularRealmAuthenticator(); modularRealmAuthenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy()); return modularRealmAuthenticator; } /** * rememberMe管理器, cipherKey生成見{@code Base64Test.java} */ @Bean public CookieRememberMeManager rememberMeManager(SimpleCookie rememberMeCookie) { CookieRememberMeManager manager = new CookieRememberMeManager(); manager.setCipherKey(Base64.decode("Z3VucwAAAAAAAAAAAAAAAA==")); manager.setCookie(rememberMeCookie); return manager; } /** * 記住密碼Cookie */ @Bean public SimpleCookie rememberMeCookie() { SimpleCookie simpleCookie = new SimpleCookie("rememberMe"); simpleCookie.setHttpOnly(true); simpleCookie.setMaxAge(7 * 24 * 60 * 60);//7天 return simpleCookie; } /** * 在方法中 注入 securityManager,進(jìn)行代理控制 */ @Bean public MethodInvokingFactoryBean methodInvokingFactoryBean(DefaultWebSecurityManager securityManager) { MethodInvokingFactoryBean bean = new MethodInvokingFactoryBean(); bean.setStaticMethod("org.apache.shiro.SecurityUtils.setSecurityManager"); bean.setArguments(new Object[]{securityManager}); return bean; } /** * 保證實(shí)現(xiàn)了Shiro內(nèi)部lifecycle函數(shù)的bean執(zhí)行 */ @Bean public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } /** * 啟用shrio授權(quán)注解攔截方式,AOP式方法級(jí)權(quán)限檢查 */ @Bean @DependsOn(value = "lifecycleBeanPostProcessor") //依賴其他bean的初始化 public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { return new DefaultAdvisorAutoProxyCreator(); } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; } }
看完上述內(nèi)容,你們掌握怎么在SpringBoot中使用Redis和Ehcache緩存Shiro的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!
分享題目:怎么在SpringBoot中使用Redis和Ehcache緩存Shiro
網(wǎng)頁(yè)網(wǎng)址:http://jinyejixie.com/article6/gdhoog.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計(jì)、外貿(mào)網(wǎng)站建設(shè)、全網(wǎng)營(yíng)銷推廣、網(wǎng)頁(yè)設(shè)計(jì)公司、響應(yīng)式網(wǎng)站、商城網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)