SpringBoot中Shiro缓存使用Redis、Ehcache

在SpringBoot中Shiro缓存使用Redis、Ehcache实现的两种方式实例

SpringBoot 中配置redis作为session 缓存器。 让shiro引用

  • 本文是建立在你是使用这shiro基础之上的补充内容

第一种: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;
    }

}

转载于:https://www.cnblogs.com/rolandlee/p/11359314.html

你可能感兴趣的:(SpringBoot中Shiro缓存使用Redis、Ehcache)