ehcache与spring结合注解缓存

controller层:
package com.ehcache.controller;

import java.util.List;
import java.util.UUID;

import javax.annotation.Resource;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.ehcache.pojo.State;
import com.ehcache.service.StateService;
@Controller
public class StateController {

	@Resource 
	private StateService stateService;
	
	@RequestMapping("state/findstate")
	public void findcache(){
		List<State> caches = this.stateService.findAll("state");
		for (State cache : caches) {
			System.out.println(cache.getValue());
		}
	}
	
	@RequestMapping("state/addstate")
	public void addcache(){
		System.out.println("1");
		State cache = new State();
		cache.setId(UUID.randomUUID().toString());
		int count = 0;
		cache.setValue("q"+count++);
		this.stateService.add(cache);
	} 
	
	@RequestMapping("state/updatestate")
	public void update(String name){
		State cache = new State();
		cache.setId(2+"");
		cache.setValue(name);
		this.stateService.modify(cache);
	}
	@RequestMapping("state/removestate")
	public void remove(String id){
		
		this.stateService.removeById(id);
	}
}

pojo:

package com.ehcache.pojo;

import java.io.Serializable;

public class State implements Serializable{

	private String id;
	private String value;
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getValue() {
		return value;
	}
	public void setValue(String value) {
		this.value = value;
	}
	
}
service:

package com.ehcache.service.base.impl;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.aspectj.weaver.patterns.ThisOrTargetAnnotationPointcut;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;

import com.ehcache.dao.base.BaseDao;
import com.ehcache.service.base.BaseService;

@SuppressWarnings("all")
public abstract class BaseServiceImpl<T> implements BaseService<T>{
	
	public abstract BaseDao<T> getBaseDao();
	
	@CacheEvict(value="serviceCache",allEntries=true)
	public void add(T entity) {
		this.getBaseDao().add(entity);
	}

	@CacheEvict(value="serviceCache",allEntries=true)
	public void modify(T entity) {
		this.getBaseDao().modify(entity);
	}

	// 通过ID删除  
    @CacheEvict(value = "serviceCache" ,allEntries=true)  
	public void removeById(Serializable id) {
		this.getBaseDao().removeById(id);
	}

    // allEntries 表示调用之后,清空缓存,默认false,  
    // 还有个beforeInvocation 属性,表示先清空缓存,再进行查询  
    @CacheEvict(value="serviceCache",allEntries=true)  
	public void removeAll(List ids) {
		this.getBaseDao().removeAll(ids);
	}

	// 查询所有,不要key,默认以方法名+参数值+内容 作为key 
	@Cacheable(value="serviceCache")
	public List<T> findAll(Serializable en) {
		return this.getBaseDao().findAll();
	}

	public List<T> pageAllByMap(Map map){
		
		return this.getBaseDao().pageAllByMap(map);
	}
	
	public T findOne(Map map){
		return this.getBaseDao().findOne(map);
		
	}
	
	public List<T> findAllmap(Map map){
		return this.getBaseDao().findAllmap(map);
		
	}

	// 根据ID查询,ID 我们默认是唯一的  
    @Cacheable(value = "serviceCache", key="#id")  
	public T findById(Serializable id){
		return this.getBaseDao().findById(id);
	}
	
	public int countAll(){
		return this.getBaseDao().countAll();
	}
	
}
配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="ehcache.xsd"
         updateCheck="true" monitoring="autodetect"
         dynamicConfig="true">

    <!-- timeToIdleSeconds 当缓存闲置n秒后销毁 -->
    <!-- timeToLiveSeconds 当缓存存活n秒后销毁 -->
    <!--
缓存配置 
       name:缓存名称。 
       maxElementsInMemory:缓存最大个数。 
       eternal:对象是否永久有效,一但设置了,timeout将不起作用。 
       timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。 
       timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。 
       overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。 
       diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。 
       maxElementsOnDisk:硬盘最大缓存个数。 
       diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false. 
       diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。 
       memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。 
       clearOnFlush:内存数量最大时是否清除。 


    -->

    <diskStore path="java.io.tmpdir" />

    <defaultCache
        eternal="false"
        maxElementsInMemory="500"
        overflowToDisk="true"
        timeToIdleSeconds="300"
        timeToLiveSeconds="1200" />

    <cache
        name="serviceCache"
        eternal="false"
        maxElementsInMemory="150"
        overflowToDisk="true"
        timeToIdleSeconds="3600"
        timeToLiveSeconds="36000" />

</ehcache>

spring配置文件:

<?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:mvc="http://www.springframework.org/schema/mvc"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	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.0.xsd 
	http://www.springframework.org/schema/mvc 
	http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd 
	http://www.springframework.org/schema/context 
	http://www.springframework.org/schema/context/spring-context-3.0.xsd 
	http://www.springframework.org/schema/aop 
	http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 
	http://www.springframework.org/schema/tx 
	http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 
	http://www.springframework.org/schema/cache   
    http://www.springframework.org/schema/cache/spring-cache.xsd"> 
	
	<!-- 注解扫描器 -->
	<context:component-scan base-package="com.ehcache.service"/>
	<!--  <context:component-scan base-package="com.ihuodong.dao"/>-->
	<!-- 引入dataBase配置文件 -->
	<context:property-placeholder location="classpath:jdbc.properties"/>
	<!-- 配置c3p0数据源 -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driverClassName}"></property>
		<property name="jdbcUrl" value="${jdbc.url}"></property>
		<property name="user" value="${jdbc.username}"></property>
		<property name="password" value="${jdbc.password}"></property>
		
		<property name="maxPoolSize" value="${c3p0.pool.maxPoolSize}"></property>
		<property name="minPoolSize" value="${c3p0.pool.minPoolSize}"></property>
		<property name="initialPoolSize" value="${c3p0.pool.initialPoolSize}"></property>
		<property name="acquireIncrement" value="${c3p0.pool.acquireIncrement}"></property>
	</bean>
	<!-- 配置sessionFactory加载sqlMapConfig.xml和映射文件 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource"></property>
		<property name="configLocation" value="classpath:sqlMapConfig.xml"></property>
		<property name="mapperLocations" value="classpath:mapping/*.xml"></property>
	</bean>
	<!-- 配置事务 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>

    <!-- DAO接口所在包名,Spring会自动查找其下的类 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
      <property name="basePackage" value="com.ehcache.dao" />
      <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
    </bean>
 
 	<!--  缓存  属性-->  
    <bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">    
        <property name="configLocation"  value="classpath:ehcache.xml"/>   
    </bean>   
      
    <!-- 支持缓存注解 -->  
    <cache:annotation-driven cache-manager="cacheManager" />  
      
    <!-- 默认是cacheManager -->  
    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">    
        <property name="cacheManager"  ref="cacheManagerFactory"/>    
    </bean>
        
	<!-- 配置通知 -->
	<tx:advice transaction-manager="transactionManager" id="txAdvice">
		<tx:attributes>
			<tx:method name="add*" read-only="false"/>
			<tx:method name="update*" read-only="false" />
			<tx:method name="remove*" read-only="false"/>
			<tx:method name="find*" read-only="true"/>
		</tx:attributes>
	</tx:advice>
	<!-- 配置切面 -->
	<aop:config>
		<aop:pointcut expression="execution(* com.cache.service.*.*(..))" id="proxy"/>
		<aop:advisor advice-ref="txAdvice" pointcut-ref="proxy"/>
	</aop:config>
</beans>

ehcache注解讲解:

缓存注解有以下三个:

@Cacheable      @CacheEvict     @CachePut

@Cacheable(value=”accountCache”),这个注释的意思是,当调用这个方法的时候,会从一个名叫 accountCache 的缓存中查询,如果没有,则执行实际的方法(即查询数据库),并将执行的结果存入缓存中,否则返回缓存中的对象。这里的缓存中的 key 就是参数 userName,value 就是 Account 对象。“accountCache”缓存是在 spring*.xml 中定义的名称。

@Cacheable(value="accountCache")// 使用了一个缓存名叫 accountCache 
public Account getAccountByName(String userName) {
     // 方法内部实现不考虑缓存逻辑,直接实现业务
     System.out.println("real query account."+userName); 
     return getFromDB(userName); 
} 

@CacheEvict 注释来标记要清空缓存的方法,当这个方法被调用后,即会清空缓存。注意其中一个 @CacheEvict(value=”accountCache”,key=”#account.getName()”),其中的 Key 是用来指定缓存的 key 的,这里因为我们保存的时候用的是 account 对象的 name 字段,所以这里还需要从参数 account 对象中获取 name 的值来作为 key,前面的 # 号代表这是一个 SpEL 表达式,此表达式可以遍历方法的参数对象,具体语法可以参考 Spring 的相关文档手册。

@CacheEvict(value="accountCache",key="#account.getName()")// 清空accountCache 缓存  
public void updateAccount(Account account) {
     updateDB(account); 
} 
  
@CacheEvict(value="accountCache",allEntries=true)// 清空accountCache 缓存
public void reload() {
     reloadAll()
}

@Cacheable(value="accountCache",condition="#userName.length() <=4")// 缓存名叫 accountCache 
public Account getAccountByName(String userName) { 
 // 方法内部实现不考虑缓存逻辑,直接实现业务
 return getFromDB(userName); 
}
@CachePut 注释,这个注释可以确保方法被执行,同时方法的返回值也被记录到缓存中,实现缓存与数据库的同步更新。

@CachePut(value="accountCache",key="#account.getName()")// 更新accountCache 缓存
public Account updateAccount(Account account) { 
   return updateDB(account); 
} 

@Cacheable、@CachePut、@CacheEvict 注释介绍

通过上面的例子,我们可以看到 spring cache 主要使用两个注释标签,即 @Cacheable、@CachePut 和 @CacheEvict,我们总结一下其作用和配置方法。

表 1. @Cacheable 作用和配置方法
@Cacheable 的作用  主要针对方法配置,能够根据方法的请求参数对其结果进行缓存

@Cacheable 主要的参数
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 例如:
@Cacheable(value=”mycache”) 或者 
@Cacheable(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 例如:
@Cacheable(value=”testcache”,key=”#userName”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 例如:
@Cacheable(value=”testcache”,condition=”#userName.lengt

表 2. @CachePut 作用和配置方法
@CachePut 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用
@CachePut 主要的参数
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 例如:
@Cacheable(value=”mycache”) 或者 
@Cacheable(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 例如:
@Cacheable(value=”testcache”,key=”#userName”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 例如:
@Cacheable(value=”testcache”,condition=”#userName.length()>2”)
表 3. @CacheEvict 作用和配置方法
@CachEvict 的作用 主要针对方法配置,能够根据一定的条件对缓存进行清空
@CacheEvict 主要的参数
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 例如:
@CachEvict(value=”mycache”) 或者 
@CachEvict(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 例如:
@CachEvict(value=”testcache”,key=”#userName”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才清空缓存 例如:
@CachEvict(value=”testcache”,
condition=”#userName.length()>2”)
allEntries 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存 例如:
@CachEvict(value=”testcache”,allEntries=true)
beforeInvocation 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存 例如:
@CachEvict(value=”testcache”,beforeInvocation=true)



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值