Spring @Cacheable注解类内部调用失效问题

Spring @Cacheable注解类内部调用失效问题_第1张图片

如图所示,getRecomendGoogs方法里面调用findImgUrlByName方法,在findImgUrlByName方法上使用@Cacheable注解的时候,并没有走缓存。

要解决这个问题,首先我们需要了解spring缓存的原理。spring cache的实现原理跟spring的事物管理类似,都是基于AOP的动态代理实现的:即都在方法调用前后 
去获取方法的名称、参数、返回值,然后根据方法名称、参数生成缓存的key(自定义的key例外),进行缓存。debug可以看到调用的实际上是groupUserBiz 
的代理类,基于cglib动态代理实现。当调用代理的方法时,代理可以整体控制实际的方法的入参和返回值。比如缓存结果,直接跳过执行实际的方法等。 

找到了原因之后,我们有两种解决方案

第一种:

把findImgUrlByName这个方法单独写到另外的一个类里面去,把内部调用搞成内间调用

 

第二种:

使用内部调用的时候,自己实例化一个类对象,让类走AOP,

写一个工具类

@Component
public class SpringContextUtil implements ApplicationContextAware {
	// Spring应用上下文环境
	private static ApplicationContext applicationContext;

	/**
	 * 实现ApplicationContextAware接口的回调方法,设置上下文环境
	 * 
	 * @param applicationContext
	 */
	public void setApplicationContext(ApplicationContext applicationContext) {
		SpringContextUtil.applicationContext = applicationContext;
	}

	/**
	 * @return ApplicationContext
	 */
	public static ApplicationContext getApplicationContext() {
		return applicationContext;
	}

	/**
	 * 获取对象
	 * 
	 * @param name
	 * @return Object
	 * @throws BeansException
	 */
	public static Object getBean(String name) throws BeansException {
		return applicationContext.getBean(name);
	}

	/**
	 * 通过类型获取对象
	 * 
	 * @param t
	 *            对象类型
	 * @return
	 * @throws BeansException
	 */
	public static  T getBean(Class t) throws BeansException {
		return applicationContext.getBean(t);
	}
}

在getRecomendGoogs方法调用findImgUrlByName的时候使用

WeCommonService weCommonService = SpringContextUtil.getBean(WeCommonService.class);自己实例化service

Spring @Cacheable注解类内部调用失效问题_第2张图片

 

你可能感兴趣的:(java)