• Spring Boot Oauth2缓存UserDetails到Ehcache


    在Spring中有一个类CachingUserDetailsService实现了UserDetailsService接口,该类使用静态代理模式为UserDetailsService提供缓存功能。该类源码如下:

    CachingUserDetailsService.java

    public class CachingUserDetailsService implements UserDetailsService {
        private UserCache userCache = new NullUserCache();
        private final UserDetailsService delegate;
    
        CachingUserDetailsService(UserDetailsService delegate) {
            this.delegate = delegate;
        }
    
        public UserCache getUserCache() {
            return this.userCache;
        }
    
        public void setUserCache(UserCache userCache) {
            this.userCache = userCache;
        }
    
        public UserDetails loadUserByUsername(String username) {
            UserDetails user = this.userCache.getUserFromCache(username);
            if (user == null) {
                user = this.delegate.loadUserByUsername(username);
            }
    
            Assert.notNull(user, "UserDetailsService " + this.delegate + " returned null for username " + username + ". This is an interface contract violation");
            this.userCache.putUserInCache(user);
            return user;
        }
    }
    

    CachingUserDetailsService默认的userCache属性值为new NullUserCache(),该对象并未实现缓存。因为我打算使用EhCache来缓存UserDetails,所以需要使用Spring的EhCacheBasedUserCache类,该类是UserCache接口的实现类,主要是缓存操作。

    缓存UserDetails到Ehcache的具体实现如下:

    ehcache.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
        <!-- 磁盘缓存位置 -->
        <diskStore path="java.io.tmpdir" />
    
        <cache name="userCache"
               maxElementsInMemory="0"
               eternal="true"
               overflowToDisk="true"
               diskPersistent="true"
               memoryStoreEvictionPolicy="LRU">
        </cache>
    </ehcache>
    

    UserDetailsCacheConfig.java

    @Slf4j
    @Configuration
    public class UserDetailsCacheConfig {
        @Autowired
        private CustomUserDetailsService customUserDetailsService;
    
        @Bean
        public UserCache userCache(){
            try {
                EhCacheBasedUserCache userCache = new EhCacheBasedUserCache();
                val cacheManager = CacheManager.getInstance();
                val cache = cacheManager.getCache("userCache");
                userCache.setCache(cache);
                return userCache;
            } catch (Exception e) {
                e.printStackTrace();
                log.error(e.getMessage());
            }
            return null;
        }
    
        @Bean
        public UserDetailsService userDetailsService(){
            Constructor<CachingUserDetailsService> ctor = null;
            try {
                ctor = CachingUserDetailsService.class.getDeclaredConstructor(UserDetailsService.class);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
            Assert.notNull(ctor, "CachingUserDetailsService constructor is null");
            ctor.setAccessible(true);
    
            CachingUserDetailsService cachingUserDetailsService = BeanUtils.instantiateClass(ctor, customUserDetailsService);
            cachingUserDetailsService.setUserCache(userCache());
            return cachingUserDetailsService;
        }
    }
    

    使用

    @Autowired
    private UserDetailsService userDetailsService;
    

    欢迎关注我的oauthserver项目,仅仅需要运行建表sql,修改数据库的连接配置,即可得到一个Spring Boot Oauth2 Server微服务。项目地址https://github.com/jeesun/oauthserver

  • 相关阅读:
    Unix下5种I/O模型
    UDP/TCP拾遗
    智能指针
    YUV的数据格式
    OpenCV中RGB和HSV转换的问题
    RGB、YUV和HSV颜色空间模型
    const成员函数和mutable关键字
    设计模式--观察者模式Observer(对象行为型)
    linux备忘簿
    ctags使用详解(转载)
  • 原文地址:https://www.cnblogs.com/rainmer/p/9417108.html
Copyright © 2020-2023  润新知