spring缓存机制-根据key更新缓存(二)

spring是一个轻量级开源框架,以IoC(Inverse of Control:控制反转)和AOP(Aspect Oriented Programming:面向切面编程)为内核,
兼具功能强大的的原生展现层spring mvc,原生持久层spring jdbc和原生业务层等技术,并且以海纳百川的胸怀整合了开源世界里众多
著名的第三方框架和类库,已经逐渐成为世界上使用最多的JavaEE企业级应用开源框架.
spring3.2.3中负责cache的模块是org.spring.framework.context-3.2.3.RELEASE.jar.
@Cacheable负责将方法的返回值加入到缓存中,支持如下参数:
value:缓存位置名称,不能为空.
key:缓存的key,默认为空,支持springEL表达式.
condition:触发条件,只有满足条件的情况下才会加入缓存,默认为空,表示全部加入缓存,支持springEL表达式.
@CachEvict负责清除缓存,支持如下参数:
value:缓存位置名称,不能为空.
key:缓存的key,默认为空,支持springEL表达式.
condition:触发条件,只有满足条件的情况下才会清除缓存,默认为空,支持springEL表达式.
allEntries:ture表示清除value中的全部缓存,默认为false.
一般来说我们的添加,更新和删除操作,只需要操作缓存中的某一个对象或某些对象,所以定义缓存的key值得最好是能够唯一,
因为这样我们就可以根据key值准取的更新特定的缓存,而不会影响到其他的缓存,进而提高我们的效率.
例如针对用户的操作,我们可以使用(id+方法名)作为key值,下面通过一个实例简单介绍一下spring缓存的使用.

1.通过maven构建项目,直接看pom.xml文件.

<span style="font-size:12px;"><?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.ilucky.spring</groupId>
	<artifactId>spring-cache</artifactId>
	<version>1.0.0</version>
	<packaging>jar</packaging>

	<dependencies>
		  <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>3.2.3.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>3.2.3.RELEASE</version>
        </dependency>

	</dependencies>
</project>
</span>

2.创建service,dao和model,并将spring缓存加在service层,直接看代码UserService,UserServiceImpl,UserDao,UserDaoImpl和User.

<span style="font-size:12px;">package com.ilucky.spring.cache.service;

import java.util.Map;

import com.ilucky.spring.cache.model.User;

/**
 * @author IluckySi
 * @date 20140613
 */
public interface UserService {

	public abstract void add(User user);
	
	public abstract void delete(String id);
	
	public abstract void update(User user);
	
	public abstract User find(String id);
	
	public abstract Map<String, User> getAll();
}
</span>
<span style="font-size:12px;">package com.ilucky.spring.cache.service.impl;

import java.util.Map;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;

import com.ilucky.spring.cache.dao.UserDao;
import com.ilucky.spring.cache.model.User;
import com.ilucky.spring.cache.service.UserService;

/**
 * @author IluckySi
 * @date 20140613
 */
public class UserServiceImpl implements UserService {

	private UserDao userDao;
	
	/**
	 * JVM加载spring配置文件时, 通过set方法注入本类的依赖.
	 * @param userDao
	 */
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	/**
	 * 对数据进行增删改时清空缓存, 查询时使用缓存, 其中value为缓存区,
	 * allEntries表示清空缓存中所有的数据, 使用#"user.id + '方法名'"做为key.
	 */
	@Override
    @CacheEvict(value = "data", key = "#user.id + 'add'")  
	public void add(User user) {
		System.out.println("UserService: method- add(User user)" );
		userDao.add(user);
	}

	@Override
	@CacheEvict(value = "data", key = "#id + 'delete'")  
	public void delete(String id) {
		System.out.println("UserService: method-delete(String id)" );
		userDao.delete(id);
	}

	@Override
	@CacheEvict(value = "data", key = "#user.id+ 'update'")  
	public void update(User user) {
		System.out.println("UserService: method-update(User user)" );
		userDao.update(user);
	}

	@Override
	@Cacheable(value = "data")   
	public User find(String id) {
		System.out.println("UserService: method-find(String id)" );
		return userDao.find(id);
	}

	@Override
	@Cacheable(value = "data")  
	public Map<String, User> getAll() {
		System.out.println("UserService: method-getAll()" );
		return userDao.getAll();
	}
}
</span>
<span style="font-size:12px;">package com.ilucky.spring.cache.dao;

import java.util.Map;

import com.ilucky.spring.cache.model.User;

/**
 * @author IluckySi
 * @date 20140613
 */
public interface UserDao {

	public abstract void add(User user);
	
	public abstract void delete(String id);
	
	public abstract void update(User user);
	
	public abstract User find(String id);
	
	public abstract Map<String, User> getAll();
}
</span>
<span style="font-size:12px;">package com.ilucky.spring.cache.dao.impl;

import java.util.HashMap;
import java.util.Map;

import com.ilucky.spring.cache.dao.UserDao;
import com.ilucky.spring.cache.model.User;

/**
 * @author IluckySi
 * @date 20140613
 */
public class UserDaoImpl implements UserDao {

	//使用Map模拟数据表.
	private Map<String, User> users = new HashMap<String, User>();
	
	@Override
	public void add(User user) {
		System.out.println("UserDao method- add(User user)" );
		users.put(user.getId(), user);
	}

	@Override
	public void delete(String id) {
		System.out.println("UserDao method- delete(String id)" );
		users.remove(id);
	}

	@Override
	public void update(User user) {
		System.out.println("UserDao method- update(User user)" );
		users.put(user.getId(), user);
	}

	@Override
	public User find(String id) {
		System.out.println("UserDao method- find(String id)" );
		return users.get(id);
	}

	@Override
	public Map<String, User> getAll() {
		System.out.println("UserDao method- getAll()" );
		return users;
	}
}
</span>

  其中UserServiceImpl中的内容分为两种,直接看代码UserServiceImpl_bak(每次更新数据更新所有的缓存),和UserServiceImpl_bak2

  (每次更新数据更新指定的缓存),其中更新指定的缓存是通过配置key值来实现的.

<span style="font-size:12px;">package com.ilucky.spring.cache.service.impl;

import java.util.Map;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;

import com.ilucky.spring.cache.dao.UserDao;
import com.ilucky.spring.cache.model.User;
import com.ilucky.spring.cache.service.UserService;

/**
 * @author IluckySi
 * @date 20140613
 */
public class UserServiceImpl_bak implements UserService {

	private UserDao userDao;
	
	/**
	 * JVM加载spring配置文件时, 通过set方法注入本类的依赖.
	 * @param userDao
	 */
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	/**
	 * 对数据进行增删改时清空缓存, 查询时使用缓存, 其中value为缓存区,
	 * allEntries表示清空缓存中所有的数据.
	 */
	@Override
    @CacheEvict(value = "data", allEntries = true)  
	public void add(User user) {
		System.out.println("UserService: method- add(User user)" );
		userDao.add(user);
	}

	@Override
	@CacheEvict(value = "data", allEntries = true)  
	public void delete(String id) {
		System.out.println("UserService: method-delete(String id)" );
		userDao.delete(id);
	}

	@Override
	@CacheEvict(value = "data", allEntries = true)  
	public void update(User user) {
		System.out.println("UserService: method-update(User user)" );
		userDao.update(user);
	}

	@Override
	@Cacheable(value = "data")   
	public User find(String id) {
		System.out.println("UserService: method-find(String id)" );
		return userDao.find(id);
	}

	@Override
	@Cacheable(value = "data")  
	public Map<String, User> getAll() {
		System.out.println("UserService: method-getAll()" );
		return userDao.getAll();
	}
}
</span>
<span style="font-size:12px;">package com.ilucky.spring.cache.service.impl;

import java.util.Map;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;

import com.ilucky.spring.cache.dao.UserDao;
import com.ilucky.spring.cache.model.User;
import com.ilucky.spring.cache.service.UserService;

/**
 * @author IluckySi
 * @date 20140613
 */
public class UserServiceImpl_bak2 implements UserService {

	private UserDao userDao;
	
	/**
	 * JVM加载spring配置文件时, 通过set方法注入本类的依赖.
	 * @param userDao
	 */
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	/**
	 * 对数据进行增删改时清空缓存, 查询时使用缓存, 其中value为缓存区,
	 * allEntries表示清空缓存中所有的数据, 使用#"user.id + '方法名'"做为key.
	 */
	@Override
    @CacheEvict(value = "data", key = "#user.id + 'add'")  
	public void add(User user) {
		System.out.println("UserService: method- add(User user)" );
		userDao.add(user);
	}

	@Override
	@CacheEvict(value = "data", key = "#id + 'delete'")  
	public void delete(String id) {
		System.out.println("UserService: method-delete(String id)" );
		userDao.delete(id);
	}

	@Override
	@CacheEvict(value = "data", key = "#user.id+ 'update'")  
	public void update(User user) {
		System.out.println("UserService: method-update(User user)" );
		userDao.update(user);
	}

	@Override
	@Cacheable(value = "data")   
	public User find(String id) {
		System.out.println("UserService: method-find(String id)" );
		return userDao.find(id);
	}

	@Override
	@Cacheable(value = "data")  
	public Map<String, User> getAll() {
		System.out.println("UserService: method-getAll()" );
		return userDao.getAll();
	}
}
</span>

3.创建spring配置文件,配置spring自己的缓存管理器和bean之间的依赖关系,直接看代码spring-cahce.xml.

<span style="font-size:12px;"><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:cache="http://www.springframework.org/schema/cache"
	xsi:schemaLocation="   
                http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd   
                http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd">


	<!-- 应用spring cache注解功能  -->
	<cache:annotation-driven />

 	<!-- 创建spring cache bean -->
	<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
		<property name="caches">
			<set>
				<bean
					class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"
					p:name="default" />
				<bean
					class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"
					p:name="data" />
			</set>
		</property>
	</bean>

	<!-- 创建User Dao bean -->
	<bean id="userDao" class="com.ilucky.spring.cache.dao.impl.UserDaoImpl" ></bean>

	<!-- 创建User Service bean -->
	<bean id="userService" class="com.ilucky.spring.cache.service.impl.UserServiceImpl" >
		<property name="userDao" >
			<ref bean="userDao"></ref>
		 </property>
	</bean> 
</beans>  </span>

4.最后通过测试类测试spring缓存机制是否生效,直接看代码MainTest.

<span style="font-size:12px;">package com.ilucky.spring.cache;

import java.util.Map;
import java.util.Map.Entry;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.ilucky.spring.cache.model.User;
import com.ilucky.spring.cache.service.UserService;

/**
 * @author IluckySi
 * @date 20140613
 * 测试spring缓存机制是否生效.
 */
public class MainTest {

	public static void main(String[] args) {
		
		//加载ClassPath路径下的spring配置文件, 并获取service bean.
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-cache.xml");  
		UserService userService = context.getBean("userService", UserService.class); 
		System.out.println("service bean: " + userService);
		
		//添加三个用户, 然后查询并输出.
		userService.add(new User("1", "Ilucky1", "pwd1"));
		userService.add(new User("2", "Ilucky2", "pwd2"));
		userService.add(new User("3", "Ilucky3", "pwd3"));
		Map<String, User> map = userService.getAll();
		for(Entry<String, User> entry : map.entrySet()) {
			System.out.println(entry.getValue());
		}
		
		//验证用户数据已经放入getAll()缓存中.
		Map<String, User> map2 = userService.getAll();
		for(Entry<String, User> entry : map2.entrySet()) {
			System.out.println(entry.getValue());
		}
		
		//更新用户1数据, 然后查询并输出, 同时将更新后的用户1数据放入缓存中. 
		userService.update(new User("1", "Ilucky1_new", "pwd1_new"));
		
		//验证更新用户1数据后, 是清除了所有缓存还是只是更新了用户1的数据缓存(通过UseServiceImpl和UserServiceImpl_bak两个文件验证).
		Map<String, User> map3 = userService.getAll();
		for(Entry<String, User> entry : map3.entrySet()) {
			System.out.println(entry.getValue());
		}
	}
}
/**
如果不配置key, 只配置allEntries=true(即用UserServiceImpl_bak文件里面的内容).
输出结果:
service bean: com.ilucky.spring.cache.service.impl.UserServiceImpl@1860038
UserService: method- add(User user)
UserDao method- add(User user)
UserService: method- add(User user)
UserDao method- add(User user)
UserService: method- add(User user)
UserDao method- add(User user)
UserService: method-getAll()
UserDao method- getAll()
3-Ilucky3-pwd3
2-Ilucky2-pwd2
1-Ilucky1-pwd1
3-Ilucky3-pwd3
2-Ilucky2-pwd2
1-Ilucky1-pwd1
UserService: method-update(User user)
UserDao method- update(User user)
UserService: method-getAll()
UserDao method- getAll()
3-Ilucky3-pwd3
2-Ilucky2-pwd2
1-Ilucky1_new-pwd1_new

只配置key, 即只更新指定条件的缓存(即用UserServiceImpl_bak2文件里面的内容).
输出结果:
service bean: com.ilucky.spring.cache.service.impl.UserServiceImpl@a522a6
UserService: method- add(User user)
UserDao method- add(User user)
UserService: method- add(User user)
UserDao method- add(User user)
UserService: method- add(User user)
UserDao method- add(User user)
UserService: method-getAll()
UserDao method- getAll()
3-Ilucky3-pwd3
2-Ilucky2-pwd2
1-Ilucky1-pwd1
3-Ilucky3-pwd3
2-Ilucky2-pwd2
1-Ilucky1-pwd1
UserService: method-update(User user)
UserDao method- update(User user)
3-Ilucky3-pwd3
2-Ilucky2-pwd2
1-Ilucky1_new-pwd1_new
*/</span>
  在测试代码中通过ClassPathXmlApplicationContext类加载spring配置文件,因为此maven项目是jar项目,且在maven中默认约定资源
  放在src/main/resources目录,所以spring配置文件需要放在src/main/resources目录下.
  另外比较重要的一点是:针对通过key值来更新指定的缓存,其实可以将spring的缓存看做是一个map,这个map有自己的标示符,即value值,

  缓存中的内容是根据key来进行区分的.

附图片:项目目录结构

点击链接下载源码



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
这是一个shiro的入门Demo.. 使用了Spring MVC,mybaits等技术.. 数据库设计 : User : name--password Role : id--userid--roleName Function : id--userid--url tinys普通用户只能访问index.jsp admin用户通过添加了admin的permission,所以可以访问admin.jsp role用户通过添加了role角色,所以可以访问role.jsp 这是最基本的shiro的运用..目的是让你快速了解shiro的机制.. 这个Demo体现shiro的地方主要在两个类以及shiro.xml的配置文件 CustomRealm : 处理了登录验证以及授权.. ShiroAction : 用来传递登录时的用户数据..转换为token传递给realm...之后根据结果做相应的逻辑处理.. shiro.xml : shiro的主要配置... 规则定义在以下地方 : /login.jsp* = anon /index.jsp* = authc /index.do* = authc /admin.jsp*=authc,perms[/admin] /role.jsp*=authc,roles[role] ------------------------------------------------------------------------------------------------------------------------------------------------------------- 2015-10-28更新 --通过添加了以下内容来使用注解方式配置权限.... unauth login --修改了过滤链 //简单的讲就是把需要特别处理的路径写到前面,越特殊写到越前 /shiro/login.do*=anon /login.jsp* = anon /admin.jsp*=authc,perms[/admin] /role.jsp*=authc,roles[role] /** = authc --------------------------------------------------------------------------------------------------------------------------------------------------- 15-10-29 添加了使用ehcache缓存机制 添加了redis缓存...
Spring三级缓存Spring框架内部的缓存机制,与Spring缓存机制并不直接相关。但是,Spring缓存机制可以用于对Bean的缓存,以提高应用程序的性能。下面介绍如何在Spring三级缓存中使用Spring缓存机制。 1. 配置缓存管理器:在Spring配置文件中配置缓存管理器。例如,使用Ehcache作为缓存管理器,可以在配置文件中添加以下内容: ``` <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"> <property name="cacheManager" ref="ehcache"/> </bean> <bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> <property name="configLocation" value="classpath:ehcache.xml"/> </bean> ``` 2. 在需要缓存的方法上添加缓存注解:在需要缓存的方法上添加缓存注解,例如@Cacheable注解。例如: ``` @Service public class UserServiceImpl implements UserService { @Override @Cacheable(value = "userCache", key = "#userId") public User getUserById(String userId) { // 从数据库中获取用户信息 User user = userDao.getUserById(userId); return user; } } ``` 3. 注入缓存管理器:在需要使用缓存的类中注入缓存管理器。例如: ``` @Service public class UserServiceImpl implements UserService { @Autowired private CacheManager cacheManager; ... } ``` 4. 获取缓存对象:在需要使用缓存的方法中,通过缓存管理器获取缓存对象,然后从缓存对象中获取缓存数据。例如: ``` @Service public class UserServiceImpl implements UserService { @Autowired private CacheManager cacheManager; @Override public User getUserById(String userId) { Cache userCache = cacheManager.getCache("userCache"); ValueWrapper valueWrapper = userCache.get(userId); if (valueWrapper != null) { User user = (User) valueWrapper.get(); return user; } else { User user = userDao.getUserById(userId); userCache.put(userId, user); return user; } } } ``` 在使用Spring缓存机制时,需要注意缓存key的生成方式,可以使用SpEL表达式来指定。此外,需要根据具体的业务需求来决定缓存的策略,例如缓存的有效时间、缓存的清除策略等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值