SpringBoot中Shiro缓存使用Redis、Ehcache

心已赠人 2023-06-04 02:41 79阅读 0赞

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

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

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

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

引入pom

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-data-redis</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.session</groupId>
  7. <artifactId>spring-session-data-redis</artifactId>
  8. </dependency>

配置redisConfig

  1. @Configuration
  2. @EnableCaching
  3. public class RedisConfig extends CachingConfigurerSupport {
  4. @Bean
  5. public KeyGenerator keyGenerator() {
  6. return new KeyGenerator() {
  7. @Override
  8. public Object generate(Object target, Method method, Object... params) {
  9. StringBuilder sb = new StringBuilder();
  10. sb.append(target.getClass().getName());
  11. sb.append(method.getName());
  12. for (Object obj : params) {
  13. sb.append(obj.toString());
  14. }
  15. return sb.toString();
  16. }
  17. };
  18. }
  19. @Bean
  20. //在这里配置缓存reids配置
  21. public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
  22. RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
  23. .entryTtl(Duration.ofHours(1)); // 设置缓存有效期一小时
  24. System.out.println("《========【开启redis】 ======== 》 ");
  25. return RedisCacheManager
  26. .builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
  27. .cacheDefaults(redisCacheConfiguration).build();
  28. }
  29. @Bean
  30. public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
  31. StringRedisTemplate template = new StringRedisTemplate(factory);
  32. Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
  33. ObjectMapper om = new ObjectMapper();
  34. om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
  35. om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
  36. jackson2JsonRedisSerializer.setObjectMapper(om);
  37. template.setValueSerializer(jackson2JsonRedisSerializer);
  38. template.afterPropertiesSet();
  39. return template;
  40. }
  41. }

配置自定义缓存管理器,引入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 ){

        1. return null;

        }
        // 新建一个ShiroSpringCache 将Bean放入并实例化
        return new ShiroSpringCache(name,getCacheManager());
        }

  1. }
  • 定义自己实现的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) {

      1. if(name==null || cacheManager==null){
      2. throw new IllegalArgumentException("cacheManager or CacheName cannot be null.");
      3. }
      4. this.cacheManager = cacheManager;
      5. //这里首先是从父类中获取这个cache,如果没有会创建一个redisCache,初始化这个redisCache的时候
      6. //会设置它的过期时间如果没有配置过这个缓存的,那么默认的缓存时间是为0的,如果配置了,就会把配置的时间赋予给这个RedisCache
      7. //如果从缓存的过期时间为0,就表示这个RedisCache不存在了,这个redisCache实现了spring中的cache
      8. this.cache= cacheManager.getCache(name);

      }
      @Override
      public V get(K key) throws CacheException {

      1. log.info("从缓存中获取key为{}的缓存信息",key);
      2. if(key == null){
      3. return null;
      4. }
      5. ValueWrapper valueWrapper = cache.get(key);
      6. if(valueWrapper==null){
      7. return null;
      8. }
      9. return (V) valueWrapper.get();

      }

      @Override
      public V put(K key, V value) throws CacheException {

      1. log.info("创建新的缓存,信息为:{}={}",key,value);
      2. cache.put(key, value);
      3. return get(key);

      }

      @Override
      public V remove(K key) throws CacheException {

      1. log.info("干掉key为{}的缓存",key);
      2. V v = get(key);
      3. cache.evict(key);//干掉这个名字为key的缓存
      4. return v;

      }

      @Override
      public void clear() throws CacheException {

      1. log.info("清空所有的缓存");
      2. cache.clear();

      }

      @Override
      public int size() {

      1. 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.DICTNAME + “‘+#name+’‘+#val”)

配置spring session管理器

  1. @Bean
  2. @ConditionalOnProperty(prefix = "xpro", name = "spring-session-open", havingValue = "true")
  3. public ServletContainerSessionManager servletContainerSessionManager() {
  4. return new ServletContainerSessionManager();
  5. }
  • 新建类 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 文件

    <?xml version=”1.0” encoding=”UTF-8”?>

























配置自定义缓存管理器,引入ehcache缓存管理器

  1. /**
  2. * ehcache配置
  3. *
  4. */
  5. @Configuration
  6. @EnableCaching
  7. public class EhCacheConfig {
  8. /**
  9. * EhCache的配置
  10. */
  11. @Bean
  12. public EhCacheCacheManager cacheManager(CacheManager cacheManager) {
  13. MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
  14. ManagementService.registerMBeans(cacheManager, mBeanServer, true, true, true, true);
  15. return new EhCacheCacheManager(cacheManager);
  16. }
  17. /**
  18. * EhCache的配置
  19. */
  20. @Bean
  21. public EhCacheManagerFactoryBean ehcache() {
  22. System.out.println("《========【开启ehcache】 ======== 》 ");
  23. EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();
  24. ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache.xml"));
  25. return ehCacheManagerFactoryBean;
  26. }
  27. @Bean
  28. public org.apache.shiro.cache.CacheManager getCacheShiroManager(EhCacheManagerFactoryBean ehcache) {
  29. EhCacheManager ehCacheManager = new EhCacheManager();
  30. ehCacheManager.setCacheManager(ehcache.getObject());
  31. return ehCacheManager;
  32. }
  33. }

最后 最重要的是引入shriro 中

  1. /**
  2. * shiro权限管理的配置
  3. *
  4. */
  5. @Configuration
  6. public class ShiroConfig {
  7. /**
  8. * 安全管理器
  9. */
  10. @Bean
  11. public DefaultWebSecurityManager securityManager(CookieRememberMeManager rememberMeManager, CacheManager cacheShiroManager, SessionManager sessionManager) {
  12. DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
  13. securityManager.setAuthenticator(modularRealmAuthenticator());
  14. List<Realm> realms=new ArrayList<>();
  15. securityManager.setRealms(realms);
  16. securityManager.setCacheManager(cacheShiroManager);
  17. securityManager.setRememberMeManager(rememberMeManager);
  18. securityManager.setSessionManager(sessionManager);
  19. return securityManager;
  20. }
  21. /**
  22. * spring session管理器(多机环境)
  23. */
  24. @Bean
  25. public ServletContainerSessionManager servletContainerSessionManager() {
  26. return new ServletContainerSessionManager();
  27. }
  28. /**
  29. * session管理器(单机环境) 使用cookie存储缓存。。如果多级请注释
  30. */
  31. @Bean
  32. public DefaultWebSessionManager defaultWebSessionManager(CacheManager cacheShiroManager, XProProperties xProProperties) {
  33. DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
  34. sessionManager.setCacheManager(cacheShiroManager);
  35. sessionManager.setSessionValidationInterval(xProProperties.getSessionValidationInterval() * 1000);
  36. sessionManager.setGlobalSessionTimeout(xProProperties.getSessionInvalidateTime() * 1000);
  37. sessionManager.setDeleteInvalidSessions(true);
  38. sessionManager.setSessionValidationSchedulerEnabled(true);
  39. Cookie cookie = new SimpleCookie(ShiroHttpSession.DEFAULT_SESSION_ID_NAME);
  40. cookie.setName("shiroCookie");
  41. cookie.setHttpOnly(true);
  42. sessionManager.setSessionIdCookie(cookie);
  43. return sessionManager;
  44. }
  45. /**
  46. * 缓存管理器 使用Ehcache实现 如果使用redis则注释下面内容!!!!
  47. */
  48. @Bean
  49. public CacheManager getCacheShiroManager(EhCacheManagerFactoryBean ehcache) {
  50. EhCacheManager ehCacheManager = new EhCacheManager();
  51. ehCacheManager.setCacheManager(ehcache.getObject());
  52. return ehCacheManager;
  53. }
  54. /**
  55. * 项目自定义的Realm
  56. */
  57. @Bean
  58. public ShiroDbRealm shiroDbRealm() {
  59. return new ShiroDbRealm();
  60. }
  61. @Bean
  62. public ShiroTockenRealm shiroTockenRealm( ) {
  63. return new ShiroTockenRealm();
  64. }
  65. @Bean
  66. public ShiroJwtRealm shiroJwtRealm( ) {
  67. return new ShiroJwtRealm();
  68. }
  69. /**
  70. * 系统自带的Realm管理,主要针对多realm
  71. * */
  72. @Bean
  73. public ModularRealmAuthenticator modularRealmAuthenticator(){
  74. ModularRealmAuthenticator modularRealmAuthenticator=new ModularRealmAuthenticator();
  75. modularRealmAuthenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
  76. return modularRealmAuthenticator;
  77. }
  78. /**
  79. * rememberMe管理器, cipherKey生成见{@code Base64Test.java}
  80. */
  81. @Bean
  82. public CookieRememberMeManager rememberMeManager(SimpleCookie rememberMeCookie) {
  83. CookieRememberMeManager manager = new CookieRememberMeManager();
  84. manager.setCipherKey(Base64.decode("Z3VucwAAAAAAAAAAAAAAAA=="));
  85. manager.setCookie(rememberMeCookie);
  86. return manager;
  87. }
  88. /**
  89. * 记住密码Cookie
  90. */
  91. @Bean
  92. public SimpleCookie rememberMeCookie() {
  93. SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
  94. simpleCookie.setHttpOnly(true);
  95. simpleCookie.setMaxAge(7 * 24 * 60 * 60);//7天
  96. return simpleCookie;
  97. }
  98. /**
  99. * 在方法中 注入 securityManager,进行代理控制
  100. */
  101. @Bean
  102. public MethodInvokingFactoryBean methodInvokingFactoryBean(DefaultWebSecurityManager securityManager) {
  103. MethodInvokingFactoryBean bean = new MethodInvokingFactoryBean();
  104. bean.setStaticMethod("org.apache.shiro.SecurityUtils.setSecurityManager");
  105. bean.setArguments(new Object[]{securityManager});
  106. return bean;
  107. }
  108. /**
  109. * 保证实现了Shiro内部lifecycle函数的bean执行
  110. */
  111. @Bean
  112. public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
  113. return new LifecycleBeanPostProcessor();
  114. }
  115. /**
  116. * 启用shrio授权注解拦截方式,AOP式方法级权限检查
  117. */
  118. @Bean
  119. @DependsOn(value = "lifecycleBeanPostProcessor") //依赖其他bean的初始化
  120. public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
  121. return new DefaultAdvisorAutoProxyCreator();
  122. }
  123. @Bean
  124. public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
  125. AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor =
  126. new AuthorizationAttributeSourceAdvisor();
  127. authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
  128. return authorizationAttributeSourceAdvisor;
  129. }
  130. }

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

发表评论

表情:
评论列表 (有 0 条评论,79人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Spring Boot Shiro使用缓存

    在Shiro中加入缓存可以使权限相关操作尽可能快,避免频繁访问数据库获取权限信息,因为对于一个用户来说,其权限在短时间内基本是不会变化的。Shiro提供了Cache的抽象,其并