Skip to content

K、缓存

wangjie edited this page Dec 25, 2019 · 1 revision

组件默认使用基于ConcurrentHashMap的内存缓存。

如果您的项目中使用了Spring缓存(在配置类或者启动类上添加了@EnableCaching注解),则会使用Spring缓存。

Spring默认的缓存是guava(基于内存的HashMap),如果检测到类路径下有ehcache.xml会自动启用ehcache缓存; 如果类路径下没有ehcache.xml而在application.x(y)ml中有spring.redis的配置则启用redis缓存。

ehcache

单机部署的项目建议使用ehcache,简单方便,如果使用ehcache缓存,请在在ehcache.xml中添加配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
	<diskStore path="java.io.tmpdir" />
	
	<!-- ================= jsets-shiro相关缓存配置  ====================-->
	<!-- 属性说明-->
	<!-- name:cache的名称,必须是唯一的-->
	<!-- maxEntriesLocalHeap:内存中保持的对象数量 -->
	<!-- overflowToDisk:缓存数据数量超过maxElementsInMemory限制后是否缓存到磁盘上,这里设为true确保数据不丢失 -->
	<!-- eternal:是否是永恒数据,这里设为true确保数据不丢失,清扫任务交由程序逻辑 -->
	<!-- statistics:开启命中统计 -->
	
	<!-- 活跃的SESSION缓存 -->
	<cache 	name="shiro-activeSessionCache" 
			maxEntriesLocalHeap="2000"
			overflowToDisk="true" 
			eternal="true"
			statistics="true">
	</cache>
	<!-- 密码重试次数缓存 -->
	<cache 	name="shiro-passwordRetryCache" 
			maxEntriesLocalHeap="2000"
			overflowToDisk="true" 
			eternal="true"
			statistics="true">
	</cache>
	<!-- 保持账号唯一用户登陆缓存 -->
	<cache 	name="shiro-keepOneUserCache"
			maxEntriesLocalHeap="2000"
			overflowToDisk="true" 
			eternal="true"
			statistics="true">
	</cache>
	<!-- 认证数据缓存 ,最后一次访问后一小时失效 -->
	<cache name="shiro-authenticationCache"
           maxEntriesLocalHeap="2000"
           overflowToDisk="false"
           eternal="false"
           timeToIdleSeconds="3600"
           statistics="true">
    </cache>
    <!-- 授权数据缓存  ,最后一次访问后一小时失效-->
	<cache name="shiro-authorizationCache"
           maxEntriesLocalHeap="2000"
           overflowToDisk="false"
           eternal="false"
           timeToIdleSeconds="3600"
           statistics="true">
    </cache>
    <!-- 已使用过的令牌缓存 ,仅存活一小时-->
    <cache name="shiro-tokenBurnersCache"
           maxEntriesLocalHeap="2000"
           overflowToDisk="true"
           eternal="false"
           timeToLiveSeconds="3600"
           statistics="true">
    </cache>
</ehcache>

redis

集群部署的项目建议使用redis,集群共享方便,redi配置示例如下:

# 此为示例,参数可根据你项目实际情况调整
spring:
  redis:
    timeout: 6000ms
    host: 127.0.0.1
    port: 6379
    lettuce:
      pool:
        max-active: 1000   # 连接池最大连接数(使用负值表示没有限制)
        max-idle: 10       # 连接池中的最大空闲连接
        max-wait: -1       # 连接池最大阻塞等待时间(使用负值表示没有限制)
        min-idle:  5       # 连接池中的最小空闲连接 

用户和权限信息缓存

缓存用户和权限信息。比如要访问一个URL,shiro需要判断您是否有权限访问这个URL,此时就需要查询用户的角色,如果启用了缓存,直接获取无需查询数据库。

开启用户和权限信息缓存:

#jsets-shiro配置
jsets:
  shiro:
    #是否开启用户和权限数据缓存,不配置默认不启用
    auth-cache-enabled: true 

注意,如果开启了用户和权限信息缓存,在用户和用户权限数据发生改变时,要同步刷新缓存。如下:

@Service
public class UserService {
	@Autowired
	private JdbcEnhance jdbcEnhance;
	@Autowired
	private UserRoleService userRoleService;
        /**
	 * 保存用户信息
	 */
	@Transactional
	public void save(UserEntity user){
		if(Strings.isNullOrEmpty(user.getId())){
		// 密码明文加密存储
	        user.setPassword(shiroSecurityService.password(user.getPassword()));
			user.setStatus(UserEntity.USER_STATUS_OK);
			jdbcEnhance.insert(user);
		} else {
			userRoleService.deleteByUser(user.getId());
			jdbcEnhance.update(user);
		}
                // 保存用户角色
		if(!Strings.isNullOrEmpty(user.getRoleCodes())){
			for(String roleName:CommonUtil.split(user.getRoleCodes())){
				UserRoleEntity userRole = new UserRoleEntity();
				userRole.setUserId(user.getId());
				userRole.setRoleId(roleName);
				userRoleService.save(userRole);
			}
			// 清除该用户的用户和权限信息缓存
			ShiroUtils.clearAuthCache(user.getAccount());
		}
	}
	/**
	 * 修改用户状态(锁定\解锁\禁用\启用)
	 */
	public void updateStatus(String account,Short status){
		jdbcEnhance.update(SqlBuilder.BUILD()
						.UPDATE("T_USER")
						.SET("STATUS = ?")
						.WHERE("ACCOUNT = ?"), 
					status,account);
		// 清除该用户的用户和权限信息缓存
		ShiroUtils.clearAuthCache(user.getAccount());
	}
}

Clone this wiki locally