【100分】【在线等】Spring+ibatis+ehcache MethodCacheInterceptor的invoke方法没有执行

Gueis 2013-10-29 10:28:15
小弟最新做一个项目 需要使用到Spring+ibatis+ehcache 参照网上的资料自己写了一些配置 可惜MethodCacheInterceptor的invoke方法始终没有执行。想请各位高人指点迷津

这个是Tomcat启动log信息 其中MethodCacheInterceptor已经被初始化了

2013-10-29 10:17:24,179 INFO [org.springframework.cache.ehcache.EhCacheManagerFactoryBean] main org.springframework.cache.ehcache.EhCacheManagerFactoryBean.afterPropertiesSet(EhCacheManagerFactoryBean.java:100) - <Initializing EHCache CacheManager>
2013-10-29 10:17:26,693 INFO [net.sf.ehcache.util.UpdateChecker] net.sf.ehcache.CacheManager@7b7d8769 net.sf.ehcache.util.UpdateChecker.doCheck(UpdateChecker.java:98) - <New update(s) found: 2.6.5 [http://www.terracotta.org/confluence/display/release/Release+Notes+Ehcache+Core+2.6]. Please check http://ehcache.org for the latest version.>
2013-10-29 10:17:30,781 INFO [com.gaotime.datadictionary.utils.MethodCacheInterceptor] main com.gaotime.datadictionary.utils.MethodCacheInterceptor.afterPropertiesSet(MethodCacheInterceptor.java:30) - <[ name = lowFreCache status = STATUS_ALIVE eternal = false overflowToDisk = true maxEntriesLocalHeap = 100000 maxEntriesLocalDisk = 500000 memoryStoreEvictionPolicy = LFU timeToLiveSeconds = 28800 timeToIdleSeconds = 28800 diskPersistent = false diskExpiryThreadIntervalSeconds = 120 cacheEventListeners: net.sf.ehcache.statistics.LiveCacheStatisticsWrapper hitCount = 0 memoryStoreHitCount = 0 diskStoreHitCount = 0 missCountNotFound = 0 missCountExpired = 0 maxBytesLocalHeap = 0 overflowToOffHeap = false maxBytesLocalOffHeap = 0 maxBytesLocalDisk = 0 pinned = false ] A cache is required. Use setCache(Cache) to provide one.>


这个是ehcache文件

<?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">
<diskStore path="java.io.tmpdir/ehcache" />
<defaultCache maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="600"
timeToLiveSeconds="600"
overflowToDisk="true"
diskSpoolBufferSizeMB="30"
maxElementsOnDisk="50000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"/>

<!-- 8小时更新缓存 -->
<cache name="lowFreCache"
maxElementsInMemory="100000"
maxElementsOnDisk="500000"
eternal="false"
overflowToDisk="true"
diskPersistent="false"
diskSpoolBufferSizeMB="30"
timeToIdleSeconds="28800"
timeToLiveSeconds="28800"
memoryStoreEvictionPolicy="LFU" />
</ehcache>


这个是applicationContext-cache.xml配置ehcache

<?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"
xmlns:ehcache="http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring"
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
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring
http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring/ehcache-spring-1.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

<!-- cacheManager工厂类,指定ehcache.xml的位置 -->
<bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:configLocation="classpath:/cache/ehcache.xml" p:shared="true"/>

<!--声明cacheManager -->
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"
p:cacheManager-ref="cacheManagerFactory" />

<!-- 8小时更新缓存 -->
<bean id="lowFreCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager" ref="cacheManagerFactory" />
<property name="cacheName" value="lowFreCache" />
</bean>
<bean id="lowFreMethodCacheInterceptor" class="com.gaotime.datadictionary.utils.MethodCacheInterceptor">
<property name="cache" ref="lowFreCache"/>
</bean>
<bean id="lowFreMethodCachePointCut" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice" ref="lowFreMethodCacheInterceptor" />
<property name="patterns">
<list> <value>com.gaotime.datadictionary.kernel.service.impl.DataDictionaryServiceImpl\.getTableStructureInfoMap</value>
</list>
</property>
</bean>
</beans>


这个是MethodCacheInterceptor类代码


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.apache.log4j.Logger;
import org.springframework.beans.factory.InitializingBean;

/**
* <b>function:</b> 缓存方法拦截器代码
* @file MethodCacheInterceptor.java
* @project Ehcache
* @version 1.0
*/
public class MethodCacheInterceptor implements MethodInterceptor, InitializingBean {

private static final Logger log = Logger.getLogger(MethodCacheInterceptor.class);

private Cache cache;

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

public void afterPropertiesSet() throws Exception {
log.info(cache + " A cache is required. Use setCache(Cache) to provide one.");
}

public Object invoke(MethodInvocation invocation) throws Throwable {
String targetName = invocation.getThis().getClass().getName();
String methodName = invocation.getMethod().getName();
Object[] arguments = invocation.getArguments();
Object result;

String cacheKey = getCacheKey(targetName, methodName, arguments);
Element element = null;
try{
synchronized (this) {
element = cache.get(cacheKey);
if (element == null) {
// log.info(cacheKey + " Added to the cache: " + cache.getName());
result = invocation.proceed();
element = new Element(cacheKey, (Serializable) result);
cache.put(element);
} else {
// log.info(cacheKey + " Use Cached: " + cache.getName());
}
}
}catch(Exception e){
e.printStackTrace();
log.error(e.getMessage());
}
return element.getValue();
}

/**
* <b>function:</b> 返回具体的方法全路径名称 参数
* @param targetName 全路径
* @param methodName 方法名称
* @param arguments 参数
* @return 完整方法名称
*/
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();
}
}


这个是classpath信息

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="conf"/>
<classpathentry kind="lib" path="WebRoot/WEB-INF/lib/ehcache-core-2.5.0.jar"/>
<classpathentry kind="lib" path="WebRoot/WEB-INF/lib/ehcache-web-2.0.4.jar"/>
<classpathentry kind="output" path="WebRoot/WEB-INF/classes"/>
</classpath>



这个是applicationContext.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:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-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/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">
<context:annotation-config/>
<!-- ① :对 web 包中的所有类进行扫描,以完成 Bean 创建和自动依赖注入的功能 -->
<context:component-scan base-package="com.gaotime.datadictionary.web.controller" />
<!-- ② :启动 Spring MVC 的注解功能,完成请求和注解 POJO 的映射 -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="mappingJacksonHttpMessageConverter" />
</list>
</property>
</bean>
<!-- ③ :对模型视图名称的解析,即在模型视图名称添加前后缀 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />
<!-- Controller层异常处理 -->
<bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="defaultErrorView">
<value>error/error</value>
</property>
</bean>
<bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
<import resource="spring/applicationContext-cache.xml"/>
</beans>
...全文
198 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
woaizhengxin 2013-12-23
  • 打赏
  • 举报
回复
哥们,问题解决了吗?
Defonds 2013-10-29
  • 打赏
  • 举报
回复
你先用普通 Java 调用 ClassPathXmlApplicationContext 整合看看能成功不
Gueis 2013-10-29
  • 打赏
  • 举报
回复
帖子置顶!!
Gueis 2013-10-29
  • 打赏
  • 举报
回复
已经确认过了 全部都是最新的了
zhuweisyyc 2013-10-29
  • 打赏
  • 举报
回复
引用 7 楼 Gueis 的回复:
谢谢zhuweisyyc! 我改了一下表达式 在ClassPathXmlApplicationContext方式下 MethodCacheInterceptor及invoke方法可以被调用到了 但是将Tomcat启动后直接从前台页面运行的话 仍旧无法调用到invoke方法 请各位大哥指教! 具体内容如下: 这个是applicationContext-cache.xml文件中修改的内容

    <bean id="lowFreMethodCachePointCut"    class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
        <property name="advice" ref="lowFreMethodCacheInterceptor" />
        <property name="patterns">
            <list>
                 <!--股票行情代码  -->
                <value>.*get.*</value> 
            </list>
        </property>
    </bean> 
调用的Controller类及方法,如下:

@Controller
public class DataDictionaryController {
	@Autowired
	private DataDictionaryService dataDictionaryService;

	/**
	 * 取得数据表结构
	 * 
	 * @param request
	 * @param response
	 * @param model
	 * @return
	 */
	@RequestMapping("/getTableStructureInfo.do")
	public String getTableStructureInfo(HttpServletRequest request, HttpServletResponse response, ModelMap model) throws ServletException, ParseException {
		dict_logger.info("取得数据表结构 START");
		
		// 数据表名称
		String table = Utils.trim(request.getParameter("table"));
		
		// 检索条件
		Map param = new HashMap();
		param.put("code", table);
		
		Map tableBasicInfo = dataDictionaryService.getTableBasicInfo(param);
		model.put("tableBasicInfo", tableBasicInfo);
		
		// 取得数据表字段
		String[] columns = GaotimeConstants.TABLE_STRUCT_COLUMNS.split(" ");
		List<LinkedMap> lstColumns = Utils.getColumnsList(columns);
		param.put("lstColumns", lstColumns);
		
		try {
			Map tableStructureInfo = dataDictionaryService.getTableStructureInfoMap(param);
			model.putAll(tableStructureInfo);
			int counts = dataDictionaryService.getTableDataCounts(param);
			model.put("datasize",counts);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
				
		dict_logger.info("取得数据表结构 END");
		return "rightframe";
	}
调用的ServiceImpl类及方法,如下:

	/**
	 * 数据字典数据表结构
	 * @param param
	 * @return
	 */
	public Map getTableStructureInfoMap(Map param) {
		Map map = new HashMap();
		
		// 取得资产负债表展示字段
		List<LinkedMap> columnList = (List<LinkedMap>) param.get("lstColumns");
		
		// 取得资产负债表数据
		List<LinkedMap> dataInfoList = this.getBaseDao().getTableStructureInfo(param);
		
		// 取得字段说明信息
		getColumnRemarkInfo(dataInfoList);
		
		if (!dataInfoList.isEmpty()) {
			map = getStockDataList(dataInfoList, columnList, null, null, null);
		}
		
		return map;
	}
先确认下你改的东西已经发布到Tomcat下面了。
Gueis 2013-10-29
  • 打赏
  • 举报
回复
谢谢zhuweisyyc! 我改了一下表达式 在ClassPathXmlApplicationContext方式下 MethodCacheInterceptor及invoke方法可以被调用到了 但是将Tomcat启动后直接从前台页面运行的话 仍旧无法调用到invoke方法 请各位大哥指教! 具体内容如下: 这个是applicationContext-cache.xml文件中修改的内容

    <bean id="lowFreMethodCachePointCut"    class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
        <property name="advice" ref="lowFreMethodCacheInterceptor" />
        <property name="patterns">
            <list>
                 <!--股票行情代码  -->
                <value>.*get.*</value> 
            </list>
        </property>
    </bean> 
调用的Controller类及方法,如下:

@Controller
public class DataDictionaryController {
	@Autowired
	private DataDictionaryService dataDictionaryService;

	/**
	 * 取得数据表结构
	 * 
	 * @param request
	 * @param response
	 * @param model
	 * @return
	 */
	@RequestMapping("/getTableStructureInfo.do")
	public String getTableStructureInfo(HttpServletRequest request, HttpServletResponse response, ModelMap model) throws ServletException, ParseException {
		dict_logger.info("取得数据表结构 START");
		
		// 数据表名称
		String table = Utils.trim(request.getParameter("table"));
		
		// 检索条件
		Map param = new HashMap();
		param.put("code", table);
		
		Map tableBasicInfo = dataDictionaryService.getTableBasicInfo(param);
		model.put("tableBasicInfo", tableBasicInfo);
		
		// 取得数据表字段
		String[] columns = GaotimeConstants.TABLE_STRUCT_COLUMNS.split(" ");
		List<LinkedMap> lstColumns = Utils.getColumnsList(columns);
		param.put("lstColumns", lstColumns);
		
		try {
			Map tableStructureInfo = dataDictionaryService.getTableStructureInfoMap(param);
			model.putAll(tableStructureInfo);
			int counts = dataDictionaryService.getTableDataCounts(param);
			model.put("datasize",counts);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
				
		dict_logger.info("取得数据表结构 END");
		return "rightframe";
	}
调用的ServiceImpl类及方法,如下:

	/**
	 * 数据字典数据表结构
	 * @param param
	 * @return
	 */
	public Map getTableStructureInfoMap(Map param) {
		Map map = new HashMap();
		
		// 取得资产负债表展示字段
		List<LinkedMap> columnList = (List<LinkedMap>) param.get("lstColumns");
		
		// 取得资产负债表数据
		List<LinkedMap> dataInfoList = this.getBaseDao().getTableStructureInfo(param);
		
		// 取得字段说明信息
		getColumnRemarkInfo(dataInfoList);
		
		if (!dataInfoList.isEmpty()) {
			map = getStockDataList(dataInfoList, columnList, null, null, null);
		}
		
		return map;
	}
zhuweisyyc 2013-10-29
  • 打赏
  • 举报
回复
引用 5 楼 Gueis 的回复:
您指的代码是否存在? 还是表达式语法有问题? 如果是代码是否存在的话这个应该没问题 Impl文件直接可以点开看到 如果是表达式有问题 请教如何写是正确的呢? 小弟是spring初学者 请多多指教
我指的是表达式,你可以找下SpringAOP的切面表达式语法,你的语法有误。 http://www.iteye.com/topic/1120750
Gueis 2013-10-29
  • 打赏
  • 举报
回复
您指的代码是否存在? 还是表达式语法有问题? 如果是代码是否存在的话这个应该没问题 Impl文件直接可以点开看到 如果是表达式有问题 请教如何写是正确的呢? 小弟是spring初学者 请多多指教
zhuweisyyc 2013-10-29
  • 打赏
  • 举报
回复
建议检查下切面的代码是否正确 <bean id="lowFreMethodCachePointCut" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice" ref="lowFreMethodCacheInterceptor" /> <property name="patterns"> <list> <value>com.gaotime.datadictionary.kernel.service.impl.DataDictionaryServiceImpl\.getTableStructureInfoMap</value> </list> </property> </bean>
Gueis 2013-10-29
  • 打赏
  • 举报
回复
参照版主的建议 前面测了一下 也不能调用到

81,092

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧