资讯

精准传达 • 有效沟通

从品牌网站建设到网络营销策划,从策略到执行的一站式服务

怎么在SpringBoot中使用Redis和Ehcache缓存Shiro

怎么在SpringBoot中使用redis和Ehcache缓存Shiro?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

创新互联主要从事成都网站设计、网站建设、网页设计、企业做网站、公司建网站等业务。立足成都服务伊川,十余年网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:18980820575

第一种:Redis缓存,将数据存储到redis 并且开启session存入redis中。

引入pom

  
      org.springframework.boot
      spring-boot-starter-data-redis
    
    
      org.springframework.session
      spring-session-data-redis
   

配置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)); // 设置缓存有效期一小时
    System.out.println("《========【开启redis】 ======== 》 ");
    return RedisCacheManager
        .builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
        .cacheDefaults(redisCacheConfiguration).build();
  }

  @Bean
  public RedisTemplate 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

/**
 * 

 自定义cacheManage 扩张shiro里面的缓存 使用reids作缓存 

   *   * 引入自己定义的CacheManager   * 关于CacheManager的配置文件在spring-redis-cache.xml中  *   */ @Component public class ShiroSpringCacheManager implements CacheManager ,Destroyable{   /**    * 将之上的RedisCacheManager的Bean拿出来 注入于此    */   @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  Cache getCache(String name) {     if (name == null ){       return null;     }     // 新建一个ShiroSpringCache 将Bean放入并实例化     return new ShiroSpringCache(name,getCacheManager());   } }

定义自己实现的Shiro的Cache,实现了Shiro包里的Cache

/**
 * 

 自定义缓存 将数据存入到redis中 

 */ @SuppressWarnings("unchecked") public class ShiroSpringCache implements org.apache.shiro.cache.Cache{   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;     //这里首先是从父类中获取这个cache,如果没有会创建一个redisCache,初始化这个redisCache的时候     //会设置它的过期时间如果没有配置过这个缓存的,那么默认的缓存时间是为0的,如果配置了,就会把配置的时间赋予给这个RedisCache     //如果从缓存的过期时间为0,就表示这个RedisCache不存在了,这个redisCache实现了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("创建新的缓存,信息为:{}={}",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);//干掉这个名字为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 keys() {     return (Set) cacheManager.getCacheNames();   }   /**    * 获取缓存中所有的values值    */   @Override   public Collection values() {     return (Collection) 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设置session过期时间

/**
 * spring session配置
 *
 * @author xingri
 * @date 2017-07-13 21:05
 */
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 900) //session过期时间 如果部署多机环境,需要打开注释
@ConditionalOnProperty(prefix = "xpro", name = "spring-session-open", havingValue = "true")
public class SpringSessionConfig {

}

第一种:Ehcache做缓存,可以将数据存储到磁盘中,也可以存到内存中

新建ehcache.xml 文件



  
  
  
  

  
  

  
  

  
  

  
  

  
  

  
  

配置自定义缓存管理器,引入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权限管理的配置
 *
 */
@Configuration
public class ShiroConfig {

  /**
   * 安全管理器
   */
  @Bean
  public DefaultWebSecurityManager securityManager(CookieRememberMeManager rememberMeManager, CacheManager cacheShiroManager, SessionManager sessionManager) {
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    securityManager.setAuthenticator(modularRealmAuthenticator());

    List realms=new ArrayList<>();
    securityManager.setRealms(realms);

    securityManager.setCacheManager(cacheShiroManager);

    securityManager.setRememberMeManager(rememberMeManager);
    securityManager.setSessionManager(sessionManager);
    return securityManager;
  }


  /**
   * spring session管理器(多机环境)
   */
  @Bean
  public ServletContainerSessionManager servletContainerSessionManager() {
    return new ServletContainerSessionManager();
  }

  /**
   * session管理器(单机环境) 使用cookie存储缓存。。如果多级请注释
   */
  @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实现 如果使用redis则注释下面内容!!!! 
   */
  @Bean
  public CacheManager getCacheShiroManager(EhCacheManagerFactoryBean ehcache) {
    EhCacheManager ehCacheManager = new EhCacheManager();
    ehCacheManager.setCacheManager(ehcache.getObject());
    return ehCacheManager;
  }



  /**
   * 项目自定义的Realm
   */
  @Bean
  public ShiroDbRealm shiroDbRealm() {
    return new ShiroDbRealm();
  }

  @Bean
  public ShiroTockenRealm shiroTockenRealm( ) {
    return new ShiroTockenRealm();
  }

  @Bean
  public ShiroJwtRealm shiroJwtRealm( ) {
    return new ShiroJwtRealm();
  }

  /**
   * 系统自带的Realm管理,主要针对多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,进行代理控制
   */
  @Bean
  public MethodInvokingFactoryBean methodInvokingFactoryBean(DefaultWebSecurityManager securityManager) {
    MethodInvokingFactoryBean bean = new MethodInvokingFactoryBean();
    bean.setStaticMethod("org.apache.shiro.SecurityUtils.setSecurityManager");
    bean.setArguments(new Object[]{securityManager});
    return bean;
  }

  /**
   * 保证实现了Shiro内部lifecycle函数的bean执行
   */
  @Bean
  public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
    return new LifecycleBeanPostProcessor();
  }

  /**
   * 启用shrio授权注解拦截方式,AOP式方法级权限检查
   */
  @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;
  }

}

看完上述内容,你们掌握怎么在SpringBoot中使用Redis和Ehcache缓存Shiro的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注创新互联行业资讯频道,感谢各位的阅读!


文章名称:怎么在SpringBoot中使用Redis和Ehcache缓存Shiro
URL分享:http://cdkjz.cn/article/gdhoog.html
多年建站经验

多一份参考,总有益处

联系快上网,免费获得专属《策划方案》及报价

咨询相关问题或预约面谈,可以通过以下方式与我们联系

大客户专线   成都:13518219792   座机:028-86922220