Spring+Ehcache

源码地址:https://github.com/dragonwarrior01/test01.git

POM.xml

<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>
	<parent>
		<groupId>com.citi.learn</groupId>
		<artifactId>learn</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<artifactId>learn-ehcache</artifactId>
	<packaging>war</packaging>
	<name>learn-ehcache</name>
	<description>learn-ehcache</description>
	<properties>
		<org.springframework.version>3.2.3.RELEASE</org.springframework.version>
		<org.hibernate.version>4.2.0.Final</org.hibernate.version>
		<tiles.version>3.0.4</tiles.version>
	</properties>

	<dependencies>
		<!-- logger -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.6.1</version>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.16</version>
		</dependency>

		<!-- Spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${org.springframework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${org.springframework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>${org.springframework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${org.springframework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>${org.springframework.version}</version>
		</dependency>

		<!-- ehcache -->
		<dependency>
			<groupId>net.sf.ehcache</groupId>
			<artifactId>ehcache</artifactId>
			<version>2.8.3</version>
		</dependency>

		<!-- springMVC -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${org.springframework.version}</version>
		</dependency>
		<!-- Oracle Driver -->
		<dependency>
			<groupId>com.oracle</groupId>
			<artifactId>ojdbc6</artifactId>
			<version>11g</version>
		</dependency>
		<dependency>
			<groupId>com.oracle</groupId>
			<artifactId>ucp</artifactId>
			<version>11g</version>
		</dependency>
		<!-- JPA -->
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-jpa</artifactId>
			<version>1.5.2.RELEASE</version>
		</dependency>
		<!-- <dependency> <groupId>javax.persistence</groupId> <artifactId>persistence-api</artifactId> 
			<version>1.0.2</version> </dependency> -->
		<!-- hibernate -->
		<dependency>
			<groupId>org.hibernate.javax.persistence</groupId>
			<artifactId>hibernate-jpa-2.0-api</artifactId>
			<version>1.0.1.Final</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-entitymanager</artifactId>
			<version>${org.hibernate.version}</version>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>${org.hibernate.version}</version>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-ehcache</artifactId>
			<version>${org.hibernate.version}</version>
			<scope>compile</scope>
		</dependency>

	</dependencies>

</project>


一.配置ehcache.xml

  <!-- 缺省缓存配置。CacheManager 会把这些配置应用到程序中。 下列属性是 defaultCache 必须的: 
    maxInMemory -设定内存中创建对象的最大值。 
	eternal - 设置元素(译注:内存中对象)是否永久驻留。如果是,将忽略超 时限制且元素永不消亡。
	timeToIdleSeconds - 设置某个元素消亡前的停顿时间。也就是在一个元素消亡之前,两次访问时间的最大时间间隔值。 这只能在元素不是永久驻留时有效(译注:如果对象永恒不灭,则设置该属性也无用)。如果该值是 0 就意味着元素可以停顿无穷长的时间。 
	timeToLiveSeconds - 为元素设置消亡前的生存时间。 也就是一个元素从构建到消亡的最大时间间隔值。这只能在元素不是永久驻留时有效。 
	overflowToDisk - 设置当内存中缓存达到 maxInMemory 限制时元素是否可写到磁盘上。 -->
<ehcache>
	<diskStore path="c:\\ehcache\\learn-ehcache" />
	<defaultCache maxElementsInMemory="1" eternal="false"
		timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" />
	<cache name="org.test.cache.METHOD_CACHE" maxElementsInMemory="10000" eternal="false"
		timeToIdleSeconds="300000" timeToLiveSeconds="600000" overflowToDisk="true" />
</ehcache>


二、配置spring 文件spring_commons.xml

<?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:context="http://www.springframework.org/schema/context"
	xmlns:mongo="http://www.springframework.org/schema/data/mongo"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/context
          http://www.springframework.org/schema/context/spring-context-3.0.xsd
          http://www.springframework.org/schema/data/mongo
          http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
          http://www.springframework.org/schema/tx 
          http://www.springframework.org/schema/tx/spring-tx.xsd
          http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans.xsd">

	<!-- 注解支持 -->
	<context:annotation-config />

	<!-- 启动组件扫描,排除@Controller组件,该组件由SpringMVC配置文件扫描 -->
	<context:component-scan base-package="com.springMVC.test">
		<context:exclude-filter type="annotation"
			expression="org.springframework.stereotype.Controller" />
	</context:component-scan>


	<!-- 配置DataSource数据源 -->
	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
		<property name="url"
			value="jdbc:oracle:thin:@rcot1.aspac.citicorp.com:5201/a3cotr" />
		<property name="username" value="RCOTRPR1" />
		<property name="password" value="RCOTRPR1" />
	</bean>

	<!-- 配置实体管理对象 p:persistenceUnitManager-ref="persistenceUnitManager" -->
	<bean id="entityManagerFactory"
		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<!-- <property name="persistenceXmlLocation" value="classpath:persistence.xml" 
			/> -->
		<property name="dataSource" ref="dataSource" />
		<property name="packagesToScan" value="com.springMVC.test.domains" />
		<!-- 选配属性 -->
		<property name="jpaVendorAdapter">
			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
				<property name="databasePlatform" value="${hibernate.dialect}" />
				<property name="showSql" value="true" />
				<property name="generateDdl" value="false" />
			</bean>
		</property>
		<property name="jpaProperties">
			<props>
				<!--<prop key="hibernate.hbm2ddl.auto">create-drop</prop> -->
				<!--<prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop> -->
				<prop key="hibernate.hbm2ddl.auto">update</prop>
				<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
			</props>
		</property>
	</bean>

	<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
		<property name="entityManagerFactory" ref="entityManagerFactory" />
	</bean>

	<!-- 注解式事务 -->
	<tx:annotation-driven transaction-manager="txManager" />

	<!-- cache manager -->
	<bean id="cacheManager"
		class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
		<property name="configLocation">
			<value>classpath:ehcache.xml</value>
		</property>
	</bean>
	<bean id="methodCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
		<property name="cacheManager" ref="cacheManager" />
		<property name="cacheName" value="org.test.cache.METHOD_CACHE" />
	</bean>
	
	<span style="color:#ff0000;"><!-- customize intercepter begin -->
	<!-- generate cache intercepter -->
	<bean id="methodCacheInterceptor" class="com.ehcache.test.intercepter.MethodCacheInterceptor">
		<property name="cache" ref="methodCache" />
	</bean>
	<!-- remove cache intercepter -->
	<bean id="methodCacheAfterAdvice" class="com.ehcache.test.intercepter.MethodCacheAfterAdvice">
		<property name="cache" ref="methodCache" />
	</bean>
	<!-- customize intercepter end -->
	
	<bean id="methodCachePointCut"
		class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
		<property name="advice" ref="methodCacheInterceptor" />
		<property name="patterns">
			<list>
				<value>.*find.*</value>
				<value>.*get.*</value>
			</list>
		</property>
	</bean>
	<bean id="methodCacheAdvicePointCut"
		class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
		<property name="advice" ref="methodCacheAfterAdvice" />
		<property name="patterns">
			<list>
				<value>.*update.*</value>
				<value>.*save.*</value>
				<value>.*del.*</value>
			</list>
		</property>
	</bean></span>

</beans>


三、配置bean工厂,引用自定义拦截器methodCachePointCut、methodCacheAdvicePointCut

<?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:context="http://www.springframework.org/schema/context"
	xmlns:mongo="http://www.springframework.org/schema/data/mongo"
	xsi:schemaLocation="http://www.springframework.org/schema/context
          http://www.springframework.org/schema/context/spring-context-3.0.xsd
          http://www.springframework.org/schema/data/mongo
          http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
          http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

	<import resource="spring_commons.xml" />

	<bean id="userServiceImp" class="com.ehcache.test.inf.impl.UserServiceImp" />
	<bean id="userService" class="org.springframework.aop.framework.ProxyFactoryBean">
		<!-- 代理接口 -->
		<property name="proxyInterfaces" value="com.ehcache.test.inf.UserService" />
		<!-- 目标实现类 -->
		<property name="target" ref="userServiceImp" />
		<!-- 拦截器 -->
		<property name="interceptorNames">
			<list>
				<value>methodCachePointCut</value>
				<value>methodCacheAdvicePointCut</value>
			</list>
		</property>
	</bean>

</beans>


四、自定义拦截器

MethodCacheInterceptor.java

package com.ehcache.test.intercepter;

import java.io.Serializable;

import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;

public class MethodCacheInterceptor implements MethodInterceptor,
		InitializingBean {
	private static final Logger logger = LoggerFactory
			.getLogger(MethodCacheInterceptor.class);

	private transient Cache cache;

	public void setCache(Cache cache) {
		this.cache = cache;
	}

	public MethodCacheInterceptor() {
		super();
	}

	/**
	 * 拦截Service/DAO 的方法,并查找该结果是否存在,如果存在就返回cache 中的值, 否则,返回数据库查询结果,并将查询结果放入cache
	 */
	public Object invoke(MethodInvocation invocation) throws Throwable {
		String targetName = invocation.getThis().getClass().getName();
		String methodName = invocation.getMethod().getName();
		Object[] arguments = invocation.getArguments();
		Object result;
		logger.info("Find object from cache is " + cache.getName());
		String cacheKey = getCacheKey(targetName, methodName, arguments);
		Element element = cache.get(cacheKey);
		if (element == null) {
			logger.info("Hold up method , Get method result and create cache........!");
			result = invocation.proceed();
			element = new Element(cacheKey, (Serializable) result);
			cache.put(element);
		}
		return element.getValue();
	}

	/**
	 * 获得cache key 的方法,cache key 是Cache 中一个Element 的唯一标识 cache key
	 * 包括包名+类名+方法名,如com.co.cache.service.UserServiceImpl.getAllUser
	 */
	private String getCacheKey(String targetName, String methodName,
			Object[] arguments) {
		StringBuffer sb = new StringBuffer();
		sb.append(targetName).append(".").append(methodName);
		if ((arguments != null) && (arguments.length != 0)) {
			for (int i = 0; i < arguments.length; i++) {
				sb.append(".").append(arguments[i]);
			}
		}
		return sb.toString();
	}

	/**
	 * implement InitializingBean,检查cache 是否为空
	 */
	public void afterPropertiesSet() throws Exception {
		Assert.notNull(cache,
				"Need a cache. Please use setCache(Cache) create it.");
	}
}


MethodCacheAfterAdvice.java

package com.ehcache.test.intercepter;

import java.lang.reflect.Method;
import java.util.List;

import net.sf.ehcache.Cache;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;

public class MethodCacheAfterAdvice implements AfterReturningAdvice,
		InitializingBean {
	private static final Logger logger = LoggerFactory
			.getLogger(MethodCacheAfterAdvice.class);

	private transient Cache cache;

	public void setCache(Cache cache) {
		this.cache = cache;
	}

	public MethodCacheAfterAdvice() {
		super();
	}

	public void afterReturning(Object arg0, Method arg1, Object[] arg2,
			Object arg3) throws Throwable {
		String className = arg3.getClass().getName();
		List list = cache.getKeys();
		for (int i = 0; i < list.size(); i++) {
			String cacheKey = String.valueOf(list.get(i));
			if (cacheKey.startsWith(className)) {
				cache.remove(cacheKey);
				logger.info("remove cache " + cacheKey);
			}
		}
	}

	public void afterPropertiesSet() throws Exception {
		Assert.notNull(cache,
				"Need a cache. Please use setCache(Cache) create it.");
	}
}



测试

UserService

package com.ehcache.test.inf;

public interface UserService {
	public void printUser(String userName);

	public String getUser(String userId);

	public String findUser(String userId);

	public void updateUser(String user);

	public void delUser(String userId);
}


接口实现类UserServiceImp

package com.ehcache.test.inf.impl;

import com.ehcache.test.inf.UserService;

public class UserServiceImp implements UserService {

	@Override
	public void printUser(String userName) {
		// TODO Auto-generated method stub
		System.out.println("printUser user:" + userName);// 显示user
	}

	@Override
	public String findUser(String userId) {
		// TODO Auto-generated method stub
		return userId + "-- result";
	}

	@Override
	public void updateUser(String user) {
		// TODO Auto-generated method stub
		System.out.println("updateUser:" + user);
	}

	@Override
	public void delUser(String userId) {
		// TODO Auto-generated method stub
		System.out.println("delete user:" + userId);
	}

	@Override
	public String getUser(String userId) {
		// TODO Auto-generated method stub
		return userId + "--result";
	}

}


测试类

package com.ehcache.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.ehcache.test.inf.UserService;

public class TestEhcache {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"classpath:spring_beans.xml");

		UserService us = (UserService) ctx.getBean("userService");
		System.out.println("1--第一次查找并创建cache");
		us.getUser("zhangsan");

		System.out.println("2--在cache中查找");
		us.getUser("zhangsan");

		System.out.println("3--remove cache");
		us.updateUser("zhangsan");

		System.out.println("4--需要重新查找并创建cache");
		us.getUser("zhangsan");
	}

}


你可能感兴趣的:(spring,cache,ehcahce)