在很多情况下,需要从多个数据源中获取用户信息,然后合并相关的信息返回给客户端。在person directory中有两种方式来解决这个问题,一是MergingPersonAttributeDaoImpl, 即将多个IPersonAttributesAttributeDao获取到的用户信息,进行合并成一个结果集,默认是将几个结果集相同属性的合成在一起,然后返回给客户端;另一个是CascadingPersonAttributeDao,默认它将后一个结果集,替换上一个结果集中相同的属性值,然后返回给客户端。
MergingPersonAttributeDaoImpl配置:
<bean id="mergingPersonAttributeDao" class="org.jasig.services.persondir.support.MergingPersonAttributeDaoImpl"> <property name="personAttributeDaos"> <list> <ref bean="jdbcPersonAttributeDao1" /> <ref bean="jdbcPersonAttributeDao2" /> <ref bean="jdbcPersonAttributeDao3" /> </list> </property> </bean>
它的返回结果是jdbcPersonAttributeDao1,jdbcPersonAttributeDao2,jdbcPersonAttributeDao3三个结果集的合并集, 默认合并方式MultivaluedAttributeMerger;
CascadingPersonAttributeDao配置:
<bean id="cascadingPersonAttributeDao" class="org.jasig.services.persondir.support.CascadingPersonAttributeDao"> <property name="personAttributeDaos"> <list> <ref bean="jdbcPersonAttributeDao1" /> <ref bean="jdbcPersonAttributeDao2" /> <ref bean="jdbcPersonAttributeDao3" /> </list> </property> </bean>
它的返回结果是jdbcPersonAttributeDao1,jdbcPersonAttributeDao2,jdbcPersonAttributeDao3依次替换最后剩下的属性集合结果,默认合并方式ReplacingAttributeAdder。
假设jdbcPersonAttributeDao1的返回结果集{email=test@example.com,phone=12345678};jdbcPersonAttributeDao2的返回结果集{phone=12356790,office=33438}
那么如何进行结果集的合并呢?这就涉及到合并策略。
1.MultivaluedAttributeMerger
它的合并结果将所有的属性合并在一起,result={email=test@example.com,phone=[12345678,12356790],office=33438}
2.ReplacingAttributeAdder
它的合并结果是 result={email=test@example.com,phone=12356790,office=33438};
另外person directory还提供了另外一种合并策略
3.NoncollidingAttributeAdder
它的合并结果是 result={email=test@example.com,phone=12345678,office=33438}
MergingPersonAttributeDaoImpl或者CascadingPersonAttributeDao的合并策略,通过merger属性,如下:
<bean id="mergingPersonAttributeDao" class="org.jasig.services.persondir.support.MergingPersonAttributeDaoImpl"> <property name="personAttributeDaos"> <list> <ref bean="jdbcPersonAttributeDao1" /> <ref bean="jdbcPersonAttributeDao2" /> <ref bean="jdbcPersonAttributeDao3" /> </list> </property> <property name="merger" ref="noncollidingAttributeAdder" /> </bean> <bean id="noncollidingAttributeAdder" class="org.jasig.services.persondir.support.merger.NoncollidingAttributeAdder" />
对于这种用户认证成功之后,cas服务器,通过person directory,每次都需要重新获取用户信息,然后合并处理,最后返回给客户端。通常用户信息,都是不频繁更改的,person directory提供了用户信息的缓存功能:CachingPersonAttributeDaoImpl,它的配置如下:
<bean id="cachingPersonAttributeDao" class="org.jasig.services.persondir.support.CachingPersonAttributeDaoImpl"> <property name="cachedPersonAttributesDao" ref="mergingPersonAttributeDao" /> <property name="userInfoCache" ref="userInfoCacheMap" /> <property name="cacheNullResults" value="false" /> <property name="cacheKeyGenerator" ref="attributeBasedCacheKeyGenerator" /> </bean> <bean id="attributeBasedCacheKeyGenerator" class="org.jasig.services.persondir.support.AttributeBasedCacheKeyGenerator"> <!-- 需要增加spring-modules-cache-.jar --> </bean>
默认情况下attributeBasedCacheKeyGenerator,是以用户名username生成缓存键值,然后进行数据缓存;
userInfoCache是一个private Map<Serializable, Set<IPersonAttributes>> userInfoCache;
在person directory 中没有默认实现类,这个需要用户自己去实现。在这里我们就有了很大的发挥空间了,可以实现单机版,可以实现集群版等。
对于集群版,可以用ehcache,memcached 等去存储,这个不具体说明了。对于单机版进行测试,可以进行如下配置:
<bean id="userInfoCacheMap" class="java.util.concurrent.ConcurrentHashMap" />
它的缺点,就是对于缓存的内容无过期处理策略.
发表评论(对文章涉及的知识点还有疑问,可以在这里留言,老高看到后会及时回复的。)