Spring-Security (学习记录六)--采用ehcache缓存UserDetails
2016-08-29 10:42
513 查看
[Toc]
1. spring-security提供了缓存UserDetails的UserDetailsService实现类。
Spring Security提供了一个实现了可以缓存UserDetails的UserDetailsService实现类,CachingUserDetailsService。该类的构造接收一个用于真正加载UserDetails的UserDetailsService实现类。当需要加载UserDetails时,其首先会从缓存中获取,如果缓存中没有对应的UserDetails存在,则使用持有的UserDetailsService实现类进行加载,然后将加载后的结果存放在缓存中。UserDetails与缓存的交互是通过UserCache接口来实现的。CachingUserDetailsService默认拥有UserCache的一个空实现引用,NullUserCache。以下是CachingUserDetailsService的类定义。public class CachingUserDetailsService implements UserDetailsService { private UserCache userCache = new NullUserCache(); private final UserDetailsService delegate; CachingUserDetailsService(UserDetailsService delegate) { this.delegate = delegate; } public UserCache getUserCache() { return userCache; } public void setUserCache(UserCache userCache) { this.userCache = userCache; } public UserDetails loadUserByUsername(String username) { UserDetails user = userCache.getUserFromCache(username); if (user == null) { user = delegate.loadUserByUsername(username); } Assert.notNull(user, "UserDetailsService " + delegate + " returned null for username " + username + ". " + "This is an interface contract violation"); userCache.putUserInCache(user); return user; } }
我们可以看到当缓存中不存在对应的UserDetails时将使用引用的UserDetailsService类型的delegate进行加载。加载后再把它存放到Cache中并进行返回。除了NullUserCache之外,Spring Security还为我们提供了一个基于Ehcache的UserCache实现类,EhCacheBasedUserCache,其源码如下所示。
public class EhCacheBasedUserCache implements UserCache, InitializingBean { private static final Log logger = LogFactory.getLog(EhCacheBasedUserCache.class); private Ehcache cache; public void afterPropertiesSet() throws Exception { Assert.notNull(cache, "cache mandatory"); } public Ehcache getCache() { returncache; } public UserDetails getUserFromCache(String username) { Element element = cache.get(username); if (logger.isDebugEnabled()) { logger.debug("Cache hit: " + (element != null) + "; username: " + username); } if (element == null) { returnnull; } else { return (UserDetails) element.getValue(); } } public void putUserInCache(UserDetails user) { Element element = new Element(user.getUsername(), user); if (logger.isDebugEnabled()) { logger.debug("Cache put: " + element.getKey()); } cache.put(element); } public void removeUserFromCache(UserDetails user) { if (logger.isDebugEnabled()) { logger.debug("Cache remove: " + user.getUsername()); } this.removeUserFromCache(user.getUsername()); } public void removeUserFromCache(String username) { cache.remove(username); } public void setCache(Ehcache cache) { this.cache = cache; } }
2. 通过配置来完成缓存 UserDetails (使用ehcache)
从上述源码我们可以看到EhCacheBasedUserCache所引用的Ehcache是空的,所以,当我们需要对UserDetails进行缓存时,我们只需要定义一个Ehcache实例,然后把它注入给EhCacheBasedUserCache就可以了。接下来我们来看一下定义一个支持缓存UserDetails的CachingUserDetailsService的示例。<!-- 认证管理器,配置了管理员与角色的关系 --> <security:authentication-manager alias="authenticationManager"> <!-- 配置账号密码所属的角色 角色以 ROLE_开头,为spring获取名称的标识 (xml方式的才需要) user-service-ref="accountService" : 配置启动数据库方式获取用户和角色,xml失效 --> <security:authentication-provider user-service-ref="cachingUserDetailsService"> <!-- 密码采用md5加密 --> <security:password-encoder hash="md5" /> </security:authentication-provider> </security:authentication-manager> <bean id="cachingUserDetailsService" class="org.springframework.security.config.authentication.CachingUserDetailsService"> <!-- 真正加载UserDetails的UserDetailsService --> <constructor-arg ref="accountService"/> <!-- 缓存UserDetails的UserCache --> <property name="userCache"> <bean class="org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache"> <!-- 用于真正缓存的Ehcache对象 --> <property name="cache" ref="ehcache4UserDetails"/> </bean> </property> </bean> <!-- 将使用默认的CacheManager创建一个名为ehcache4UserDetails的Ehcache对象 --> <bean id="ehcache4UserDetails" class="org.springframework.cache.ehcache.EhCacheFactoryBean"/>
3. 引入ehcache
pom.xml中引入<!-- ehcache需要的依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>3.2.5.RELEASE</version> </dependency> <!-- 加入ehcache --> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> <version>2.7.4</version> </dependency>
添加ehcache.xml配置文件(详见附件)
项目中添加spring-ehcache.xml (详见附件)
<!-- 开启spring缓存 --> <cache:annotation-driven cache-manager="cacheManager" /> <bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:configLocation="classpath:ehcache.xml" p:shared="false" /> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cacheManager-ref="cacheManagerFactory" /> </beans>
这样。缓存UserDetails就成功了。
百度云链接:http://pan.baidu.com/s/1c2FmMQG 密码:vnov
相关文章推荐
- Spring-Security (学习记录五)--配置登录时,密码采用md5加密,以及获取登录信息属性监听同步自己想要的登录信息
- Spring-Security (学习记录四)--配置权限过滤器,采用数据库方式获取权限
- Spring-Security (学习记录三)--读取数据库中的用户和角色
- Spring-Security (学习记录二)--修改为自己的登录页面
- Spring-Security (学习记录一)--登录
- Spring-Security (学习记录七)--实现FilterInvocationSecurityMetadataSource的类将无法切入声明式事物
- spring-security学习笔记--配置文件
- spring-security学习笔记--配置文件
- 框架学习之Spring 第三节 采用Spring实现AOP功能
- Android 采用Pull解析XML内容 【学习记录】
- spring-security学习笔记--配置文件
- 框架学习之Spring 第二节 采用Spring管理Bean和依赖注入
- 框架学习之Spring 第三节 采用Spring实现AOP功能
- jqGrid分页技术学习(三)spring jdbc 通用DAO——添加一条记录
- 页面每次添加都显示最后一次访问记录spring scope="prototype" 学习笔记
- spring-security学习笔记--配置文件
- 框架学习之Spring 第二节 采用Spring管理Bean和依赖注入
- 框架学习之Spring 第二节 采用Spring管理Bean和依赖注入
- 微软企业库5.0 学习之路——第三步、为项目加上异常处理(采用自定义扩展方式记录到数据库中)
- Android 采用DOM解析XML内容 【学习记录】