在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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:notice#nhooo.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。