spring缓存很大程度上是围绕切面构建的。
在执行加有@Cacheable、@CachePut、@CacheEivt、@Caching等注解的方法(当然也可加在类上或者接口方法上,实现接口的方法都会执行缓存操作)。都会先进入CacheAspectSupport 类中。
执行getCache方法。
遍历所有配置的缓存(在指定的cache.xml中指定缓存名字)
然后查看是否存在这个缓存(不存在直接抛异常,这个要在xml中添加对应的缓存名字)。
具体步骤
- 启用缓存
在javaconfig中添加@EnableCaching - 配置EhCacheCacheManager
配置EhCacheManagerFactoryBean bean(指定一个ConfigLocation,也就是Ehcache.xml的classpathresource),然后把这个bean注入到 EhCacheCacheManager
FactoryBean接口
EhCacheManagerFactoryBean 类实现了FactoryBean接口
在查找上下文的时候,如果知道实现了FactoryBean接口就会调用getObject方法返回的对象注入到spring上下文。
afterPropertiesSet方法,在EhCacheManagerFactoryBean对象构建成功后调用(因为实现了InitializingBean)在这个方法中根据classpathresource得到CacheManager
关于EhCacheManagerFactoryBean 和 FactoryBean
//源码中给本对象添加cacheManager
//然后在查找上下文的时候就会调用getObject获取到这个cacheManager
public void afterPropertiesSet() throws CacheException, IOException {
logger.info("Initializing EhCache CacheManager");
InputStream is = (this.configLocation != null ? this.configLocation.getInputStream() : null);
try {
Configuration configuration = (is != null ?
ConfigurationFactory.parseConfiguration(is) : ConfigurationFactory.parseConfiguration());
if (this.cacheManagerName != null) {
configuration.setName(this.cacheManagerName);
}
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);
}
}
finally {
if (is != null) {
is.close();
}
}
}
配置EhcacheCacheManager
@Configuration
@EnableCaching
public class CachingConfig {
@Bean
public EhCacheCacheManager cacheManager(CacheManager cm) {
//cm就是下面的 EhcacheManagerFactoryBean,上面关于FactoryBean是解释
return new EhCacheCacheManager(cm);
}
@Bean
public EhCacheManagerFactoryBean ehcache() {
EhCacheManagerFactoryBean ehCacheFactoryBean =
new EhCacheManagerFactoryBean();
ehCacheFactoryBean.setConfigLocation(
new ClassPathResource("spittr/cache/ehcache.xml"));
return ehCacheFactoryBean;
}
}
使用缓存
//然后就可以使用这几个注解了 @Cacheable等
//spitterCache在ehcache.xml中配置,一般缓存用户信息、系统信息
@Cacheable(value = "spitterCache")
public Spitter findOne(long id) {
// try {
// Thread.sleep(5000L);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
return jdbcTemplate.queryForObject(
SELECT_SPITTER + " where id=?", new SpitterRowMapper(), id);
}
网友评论