SpringBoot中使用EhCacheManager

背景

在原有的项目中的一个工具类中,用到了cacheManager。

import net.sf.ehcache.CacheManager;
 
public class CacheHelper {

	private static CacheManager cacheManager = (CacheManager) SpringContextTools.getBean("ehCacheManager");
	....
}

这里用的cacheManager是ehcache的cacheManger,不是Spring中的org.springframework.cache.ehcache.EhCacheCacheManager。

使用的spring配置如下:

<bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
	<property name="configLocation" value="classpath:myEhcache.xml" />
</bean>

PS:在项目中只是使用了EhCache,并没有开启Spring的缓存注解。开启Spring缓存注解需要添加如下设置

<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
    <property name="cacheManager" ref="ehCacheManager"/>
</bean>

<!-- 启用缓存注解开关 -->
<cache:annotation-driven cache-manager="cacheManager"/>

新项目

Maven设置

<dependency>
	<groupId>net.sf.ehcache</groupId>
 	<artifactId>ehcache</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-cache</artifactId>
</dependency>

SpringBoot的配置类

新的项目使用SpringBoot,需要用到原项目中的工具类,于是创建一个配置类,用于创建EhCacheManager实例,提供给工具类使用。

@Configuration
public class CacheConfig {

	/**
	 * 给CacheHelper用的cacheManager
	 * 
	 * @param bean
	 * @return
	 */
	@Bean(name = "ehCacheManager")
	public CacheManager cacheManager(EhCacheManagerFactoryBean bean) {
		EhCacheManagerFactoryBean cacheManagerFactoryBean = new EhCacheManagerFactoryBean();
		cacheManagerFactoryBean.setConfigLocation(new ClassPathResource("myEhcache.xml"));
		cacheManagerFactoryBean.setShared(true);
		return bean.getObject();
	}
}

但是当使用bean.getObject()获取CacheManager时,总是取得null值。

PS: 在使用getObject()方法前手动调用afterPropertiesSet(),应该也可以解决null值问题。

查找问题

查看EhCacheManagerFactoryBean的源代码,发现属性cacheManager是在afterPropertiesSet()方法中被实例化。也就是说在SpringBoot项目的CacheConfig类中创建EhCacheManagerFactoryBean后,如果立即调用getObject(),这时cacheManager还没有被实例化,所以才会一直取得null值。

public class EhCacheManagerFactoryBean implements FactoryBean<CacheManager>, InitializingBean, DisposableBean {

    ......
	@Override
	public void afterPropertiesSet() throws CacheException {
        ......
		if (this.shared) {
			// Old-school EhCache singleton sharing...
			// No way to find out whether we actually created a new CacheManager
			// or just received an existing singleton reference.
			this.cacheManager = CacheManager.create(configuration);
		}
		else if (this.acceptExisting) {
			// EhCache 2.5+: Reusing an existing CacheManager of the same name.
			// Basically the same code as in CacheManager.getInstance(String),
			// just storing whether we're dealing with an existing instance.
			synchronized (CacheManager.class) {
				this.cacheManager = CacheManager.getCacheManager(this.cacheManagerName);
				if (this.cacheManager == null) {
					this.cacheManager = new CacheManager(configuration);
				}
				else {
					this.locallyManaged = false;
				}
			}
		}
		else {
			// Throwing an exception if a CacheManager of the same name exists already...
			this.cacheManager = new CacheManager(configuration);
		}
	}
}

修改SpringBoot配置类

@Configuration
public class CacheConfig {

	@Bean(name = "ehCacheManager")
	public CacheManager cacheManager(EhCacheManagerFactoryBean bean) {
		return bean.getObject();
	}

	@Bean
	public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() {
		EhCacheManagerFactoryBean cacheManagerFactoryBean = new EhCacheManagerFactoryBean();
		cacheManagerFactoryBean.setConfigLocation(new ClassPathResource("myEhcache.xml"));
		cacheManagerFactoryBean.setShared(true);
		// 设置完属性后,cacheManagerFactoryBean会执行afterProertiesSet()方法,
		// 所以不能在这里直接执行cacheManagerFactoryBean.getObject(),直接执行的话,因为在afterPropertiesSet()方法之前执行,所以:getObject()会得到null值
		return cacheManagerFactoryBean;
	}
}

修改后,可成功获取ehCacheManager。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值