`
wanmeilingdu
  • 浏览: 24299 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

利用Spring IoC和EHCache 拦截缓存方法,缓存结果

阅读更多

EHCache作为一种通用缓存解决方案集成进 Spring。

我将示范拦截器的例子,它能把方法返回的结果缓存起来。

 

利用 Spring IoC 配置 EHCache

Spring 里配置 EHCache 很简单。你只需一个 ehcache.xml 文件,该文件用于配置 EHCache

 

 

拦截器将使用 constantSeviceCache区域缓存方法返回结果。下面利用 Spring IoC 让 bean 来访问这一区域。

可以灵活的根据缓存的时间来建立多个这样的缓存,来控制不同的缓存时间

 

 

构建我们的 MethodCacheInterceptor

该拦截器根据spring2.0规范。一旦运行起来(kicks-in),它首先检查被拦截方法是否被配置为可缓存的。这将可选择性的配置想要缓存的 bean 方法。只要调用的方法配置为可缓存,拦截器将为该方法生成 cache key 并检查该方法返回的结果是否已缓存。如果已缓存,就返回缓存的结果,否则再次调用被拦截方法,并缓存结果供下次调用。

 

com.heshen.cache.MethodCacheInterceptor

 

MethodCacheInterceptor 代码说明了:

  • 默认条件下,所有方法返回结果都被缓存了(methodNames 是 null)
  • 缓存区利用 IoC 形成
  • cacheKey 的生成还包括方法参数的因素(译注:参数的改变会影响 cacheKey)

使用 MethodCacheInterceptor

下面摘录了怎样配置 MethodCacheInterceptor

 

 

 

译注

夏昕所著《Hibernate 开发指南》,其中他这样描述 EHCache 配置文件的:

ehcache.xml 文件

 

 

 

<ehcache>
    <diskStore path="java.io.tmpdir"/>
    <defaultCache
        maxElementsInMemory="10000" //Cache中最大允许保存的数据数量
        eternal="false"                       //Cache中数据是否为常量
        timeToIdleSeconds="120"     //缓存数据钝化时间
        timeToLiveSeconds="120"     //缓存数据的生存时间
        overflowToDisk="true"       //内存不足时,是否启用磁盘缓存
    />
</ehcache>
<cache name="constantSeviceCache
"
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="3600"
        timeToLiveSeconds="3600"
        overflowToDisk="true"
        />


提供缓存拦截的类

 MethodCacheInterceptor.java

 

/**
*/
package com.heshen.cache;

import java.io.Serializable;
import java.lang.reflect.Method;

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

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;

/**
 * 针对方法切入,进行缓存的拦截器
 * @author wanggang
   @version 2010-12-03
 *
 *       缓存处理
 */
public class
MethodCacheInterceptor implements InitializingBean {

    private Logger logger = Logger.getLogger("Method-Cache-Inegceptor");

    private Cache serviceCache;

    /**
     * 设置缓存名
     */
    public void setServiceCache(Cache serviceCache) {
        this.serviceCache = serviceCache;
    }

    /**
     * 主方法 如果某方法可被缓存就缓存其结果 方法结果必须是可序列化的(serializable)
     */
    public Object doCacheOperation(ProceedingJoinPoint pjp)
            throws Throwable {

        String targetName = pjp.getTarget().getClass().getName();
        Signature signature = pjp.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();

        // String methodName = pjp.getThis()methodName.
        // invocation.getMethod().getName();
        String methodName = method.getName();

        Object[] arguments = pjp.getArgs();// invocation.getArguments();
        Object result;
        // logger.info("looking for method result in cache");
        String cacheKey = getCacheKey(targetName, methodName, arguments);
        logger.info("cache key" + cacheKey);
        Element element = serviceCache.get(cacheKey);
        if (element == null) {
            // call target/sub-interceptor
            logger.info("calling intercepted method");
            result = pjp.proceed();

            // cache method result
            logger.info("caching result");
            element = new Element(cacheKey, (Serializable) result);
            serviceCache.put(element);
        }
        return element.getValue();

    }

    /**
     * creates cache key: targetName.methodName.argument0.argument1...
     */
    private String getCacheKey(String targetName, String methodName,
            Object[] arguments) throws Exception {
        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();
    }
   
    /**
     * 检查是否提供必要参数。
     */
    public void afterPropertiesSet() throws Exception {
        Assert.notNull(serviceCache,
                "A cache is required. Use setCache(Cache) to provide one.");
    }


}

 

 
 cacheInterceptor.xml缓存拦截器配置文件

 

<?xml version="1.0" encoding="GBK"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
    default-autowire="byName">
   
    <!-- 实际提供缓存服务的类 -->
   <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
    <!-- 缓存不会变动的服务  -->
   <bean id="constantSeviceCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">  
        <property name="cacheManager">
            <ref bean="cacheManager"/> 
        </property>  
        <property name="cacheName">  
            <value>constantSeviceCache</value>
        </property>  
    </bean>

 
    <!-- 缓存不会变动的服务  -->
    <bean id="constantSeviceCacheMethodCacheInterceptor" class="com.
heshen.cache.MethodCacheInterceptor">
         <property name="serviceCache">  
            <ref local="constantSeviceCache" />  
        </property>  
    </bean>
   
   
    <!--  缓存不会变动的服务 -->
<aop:config>
      <aop:aspect id="constantSeviceCacheOperation" ref="constantSeviceCacheMethodCacheInterceptor">
        <aop:pointcut id="
test1ConstantSeviceCacheCut" expression="execution(* com.heshen.service.impl.Test1ServiceImpl.*(..))"/>
        <aop:pointcut id="
test2ClassServiceCacheCut" expression="execution(* com.heshen.service.impl.Test2ServiceImpl.*(..))"/>
               
        <aop:around pointcut-ref="
test1ConstantSeviceCacheCut" method="doCacheOperation"/>        
        <aop:around pointcut-ref="
test2ClassServiceCacheCut" method="doCacheOperation"/>
      </aop:aspect>
    </aop:config>

    <!--  还可以继续配置其他的缓存切面 -->
<!--
<aop:config>
      <aop:aspect id="constantSeviceCacheOperation" ref="constantSeviceCacheMethodCacheInterceptor">
        <aop:pointcut id="test1ConstantSeviceCacheCut" expression="execution(* com.
heshen.service.impl.Test1ServiceImpl.*(..))"/>
        <aop:pointcut id="
test2ClassServiceCacheCut" expression="execution(* com.heshen.service.impl.Test2ServiceImpl.*(..))"/>
               
        <aop:around pointcut-ref="
test1ConstantSeviceCacheCut" method="doCacheOperation"/>        
        <aop:around pointcut-ref="
test2ClassServiceCacheCut" method="doCacheOperation"/>
      </aop:aspect>
    </aop:config>
-->
</beans>

 

cacheInterceptor.xml缓存拦截器配置文件

 

/**
*/
com.heshen.service.impl;


/**
 * 具体的service类
 * @author wanggang
   @version 2010-12-03
 *
 *       缓存处理
 */
public class
Test2ServiceImpl implements test2Service {

    private Logger logger = Logger.getLogger("
Test2ServiceImpl ");

    public void doSomeThing1(String a){
    }

   public String doSomeThing2(String arg1,String arg2){
    }

   ....
}


分享到:
评论

相关推荐

    cglib-2.2.jar,ehcache-spring-annotations-1.1.2.jar

    CGLIB提供了代理功能,使得Spring能对未实现接口的类进行AOP拦截,而Ehcache-spring-annotations则实现了Spring与Ehcache的整合,方便开发者通过注解方式管理缓存,提升应用程序性能。在实际项目中,合理利用这两个...

    EHCache 实例

    本文将详细介绍如何在Spring中配置和使用EHCache,以及通过拦截器实现方法结果的缓存。 首先,配置EHCache的核心是`ehcache.xml`文件。这个XML配置文件定义了缓存策略和行为。以下是一个简单的示例: ```xml ...

    spring整合struts.rar

    Spring 提供的缓存支持(如 EhCache 或 Redis)和 Struts2 的缓存拦截器可以帮助改善性能。 10. **安全性**:整合 Spring Security(原 Acegi Security)可以提供更高级别的安全控制,包括用户认证、授权、会话管理...

    《Java EE企业级应用开发教程Spring+Spring MVC+MyBatis》_源代码.zip

    9. **Chapter 16** - Spring与缓存:介绍Spring对缓存的支持,如EhCache和Redis。讲解如何配置缓存管理,提高应用程序性能。 10. **Chapter 17** - Spring Boot:简述Spring Boot快速开发框架,如何简化Spring应用...

    基于Struts2+Spring+Hibernate+MySql的注册登录系统.zip

    通过Spring的IoC容器,我们可以实现松耦合和更好的测试性。同时,Spring还提供了与Hibernate的集成,简化了数据库操作。 Hibernate是一个持久化框架,用于简化Java对象和数据库之间的交互。它提供了对象关系映射...

    struts2、spring、hibernate面试题集

    Spring通过代理模式实现AOP,支持方法、属性和构造器拦截。 4. Spring MVC的组成部分? 包括DispatcherServlet、HandlerMapping、Controller、ViewResolver和ModelAndView等。 三、Struts2面试题分析: 1. Struts...

    Spring3.0.5所有jar包及每个jar包作用说明文档

    4. **spring-aop.jar**:实现了AOP功能,允许开发者定义和应用切面,进行方法拦截,事务管理等。它包括了ProxyFactoryBean和AspectJ的集成。 5. **spring-expression.jar (SPeL)**:Spring表达式语言,提供了一种...

    spring 参考手册 pdf

    8. **Spring集成**:如与各种消息队列(MQ)、缓存系统(如Redis和 Ehcache)的集成,以及对EJB(Enterprise JavaBeans)的支持。 9. **测试**:介绍Spring提供的测试支持,包括单元测试、集成测试和端到端测试。 ...

    spring2.0-reference_final_zh_cn

    10. **缓存支持**:Spring 2.0 引入了对缓存的支持,如 EhCache 和 Hibernate 二級缓存,可以有效提高数据读取速度,降低数据库负载。 通过阅读这份《Spring 2.0 参考手册》,开发者可以全面了解 Spring 框架的核心...

    spring framework schema

    通过配置,可以定义哪些方法的结果应被缓存,以及缓存策略,如过期时间、大小限制等。 5. **AOP Schema**: `aop` schema涉及到面向切面编程,提供拦截器、通知和切面的配置。它允许开发者定义切点表达式,控制何时...

    spring3.1.3技术文档

    “SpringFramework Cache Abstraction”提到了Spring框架中的缓存抽象,它支持多种缓存解决方案,比如EhCache、Guava Cache和JCache,允许开发者以声明的方式配置缓存。 Spring 3.1.3还包括了对Hibernate 4.x的支持...

    静通Spring4.x各章节源代码

    9. **缓存**:Spring支持多种缓存机制,如 Ehcache、Redis,源码会展示如何配置和使用这些缓存。 10. **消息**:Spring的JMS和AMQP模块可以帮助实现消息驱动的应用,源码会涵盖消息生产者和消费者的设计。 通过...

    struts2.3.16+spring4.05+hibernate4.3.6环境搭建

    此外,为了提高性能和用户体验,可以考虑使用缓存技术如Redis或Ehcache。 总之,"struts2.3.16+spring4.05+hibernate4.3.6环境搭建"涉及到Java Web开发中的基础架构和组件集成,理解并掌握这个过程有助于开发者更好...

    Struts2+Spring+Mybatis框架jar

    1. ehcache-2.7.0.jar 和 ehcache-core-2.5.0.jar:这是EhCache库,一个内存缓存系统,可以用来缓存经常访问的数据,提高应用性能。 2. poi-ooxml-schemas-3.9.jar、xmlbeans-5.1.7.jar、poi-3.9.jar、poi-...

    struts2spring4hibernate4

    **Spring4** 是一个全面的企业级应用开发框架,支持AOP(面向切面编程)、DI(依赖注入)和IoC(控制反转)。在本例中,Spring4负责管理Bean的生命周期和装配,可以将Struts2的Action类和其他服务类纳入管理,实现...

    Struts-Hibernate-Spring推荐的最优组合配置

    3. **Spring**:Spring的IoC(Inversion of Control,控制反转)和DI(Dependency Injection,依赖注入)特性可以解耦代码,提高可测试性和可维护性。同时,Spring AOP用于实现横切关注点,如日志、事务管理等。在...

    springLearn

    2. Spring AOP:实现了面向切面编程,允许在不修改代码的情况下,进行方法拦截和日志记录等操作。 3. Spring MVC:为Web应用程序提供了模型-视图-控制器架构,使得开发RESTful API变得简单。 4. Spring JDBC和ORM...

    1. Spring初识-核心容器.pdf

    spring-context-support提供了支持缓存(例如EhCache)和任务调度(例如Quartz)的支持。spring-expression则提供了强大的表达式语言,用于在运行时查询和操作对象图。 2. AOP(面向切面编程):这个模块为Spring...

    有关hibernate、spring、struts的面试题

    6. **缓存机制**:Hibernate 提供了一级缓存(Session 内部缓存)和二级缓存(可选,如EhCache),提高性能。 7. **延迟加载**:Hibernate 支持延迟加载(Lazy Loading),只有在需要时才加载关联的对象或集合,减少...

    struts+hibernate+Spring面试题

    6. 缓存管理:Hibernate有第一级缓存(Session缓存)和第二级缓存(SessionFactory缓存),还支持第三方缓存(如EhCache)。 7. Hibernate优点:简化数据库操作,支持面向对象编程,提高开发效率,支持延迟加载,...

Global site tag (gtag.js) - Google Analytics