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配置如下:


	

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


    




新项目

Maven设置


	net.sf.ehcache
 	ehcache


	org.springframework.boot
	spring-boot-starter-cache

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, 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。

你可能感兴趣的:(SpringFramework,SpringBoot)