使用依赖 jar 中的 Spring CacheManager
Using a Spring CacheManager from dependent jar
我有几个 WAR 项目,其中包含对某个实用程序 JAR 项目的依赖项。我希望能够通过使用 spring 的 @Cacheable 注释从实用程序缓存某些方法,所以我尝试在实用程序项目上创建一个配置文件,我可以在其中定义一个可以处理缓存的 CacheManager bean的方法。配置文件如下所示:
(请注意,我使用的是 Redis 缓存实现,但 spring 配置对于其他缓存提供程序应该非常相似)
@Configuration
@EnableCaching
public class RedisConfig {
@Value("${redis.hostUrl}")
private String hostUrl = null;
@Value("${redis.port}")
private Integer port = null;
@Value("${redis.defaultExpiration}")
private Integer defaultExpiration = null;
@Bean
public JedisConnectionFactory redisConnectionFactory() {
JedisConnectionFactory = new JedisConnectionFactory();
// Defaults
redisConnectionFactory.setHostName(hostUrl);
redisConnectionFactory.setPort(port);
return redisConnectionFactory;
}
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory cf) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(cf);
return redisTemplate;
}
@Bean
public CacheManager cacheManager(RedisTemplate redisTemplate) {
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
// Number of seconds before expiration. Defaults to unlimited (0)
cacheManager.setDefaultExpiration(defaultExpiration);
cacheManager.setUsePrefix(true);
List<String> cacheNames = new ArrayList<String>();
cacheNames.add("testing");
cacheManager.setCacheNames(cacheNames);
return cacheManager;
}
}
我很确定配置本身不是问题,因为我在其他 WAR 模块中有类似的配置文件,并且缓存在这些模块上工作正常。但是,由于这是一个由其他模块加载的 JAR,我猜测 CacheManager 没有被 Spring.
获取
在依赖于 utils 项目的项目 A 中,我有如下方法(为简单起见进行了编辑;忽略无效语法):
@RequestMapping(...)
@ResponseBody
public Dto methodA(...) {
//The relevant part
testCachedMethod(value);
cachedMethodFromProjectB(value);
}
@Cacheable(value="testing")
public String testCachedMethod(String value) {
return value;
}
项目 B 是另一个 WAR,它有自己的 CacheManager(不依赖于实用程序),并且有使用 @Cacheable 缓存的类似方法。如果我点击项目 A 的 methodA,来自项目 B 的缓存会得到正确存储,但来自项目 A 的 cachedMethod 不会在缓存中存储任何内容(来自使用 @Cacheable 注释的 utils 项目的方法也不会)。我也尝试了另一种方法,直接在项目 A 上创建 CacheManager,但它也无法在 utils 项目中缓存带注释的方法(我更愿意在 utils 项目上声明管理器,以便它可以被其他模块重用).
我知道 Spring 正在正确初始化 utils 项目中的 bean,因为如果项目 A 的上下文 属性 占位符找不到 属性 文件,则项目 A 无法 运行对于缓存配置文件中的 @Value 注释。所以我假设 CacheManager bean 在那里,但不知何故它不起作用。关于我做错了什么的任何想法,或者是否甚至可以使用依赖 JAR 中的 CacheManager(如果可能,使用 Java 配置)?我正在使用 Spring 3.2.0.RELEASE.
几天来一直在努力解决这个问题,非常感谢您的帮助。
原来是 spring 缓存抽象的默认代理模式的问题。缓存注释不起作用的所有方法都被同一对象中的其他方法调用。我可以在 CacheManager bean 上使用 @Autowire 正确操作依赖 jar 项目的缓存并手动执行缓存操作。虽然应该可以通过启用 AspectJ 织入模式来使用注释,但我不想通过处理依赖模块中的织入来增加更多的复杂性。
我有几个 WAR 项目,其中包含对某个实用程序 JAR 项目的依赖项。我希望能够通过使用 spring 的 @Cacheable 注释从实用程序缓存某些方法,所以我尝试在实用程序项目上创建一个配置文件,我可以在其中定义一个可以处理缓存的 CacheManager bean的方法。配置文件如下所示:
(请注意,我使用的是 Redis 缓存实现,但 spring 配置对于其他缓存提供程序应该非常相似)
@Configuration
@EnableCaching
public class RedisConfig {
@Value("${redis.hostUrl}")
private String hostUrl = null;
@Value("${redis.port}")
private Integer port = null;
@Value("${redis.defaultExpiration}")
private Integer defaultExpiration = null;
@Bean
public JedisConnectionFactory redisConnectionFactory() {
JedisConnectionFactory = new JedisConnectionFactory();
// Defaults
redisConnectionFactory.setHostName(hostUrl);
redisConnectionFactory.setPort(port);
return redisConnectionFactory;
}
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory cf) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(cf);
return redisTemplate;
}
@Bean
public CacheManager cacheManager(RedisTemplate redisTemplate) {
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
// Number of seconds before expiration. Defaults to unlimited (0)
cacheManager.setDefaultExpiration(defaultExpiration);
cacheManager.setUsePrefix(true);
List<String> cacheNames = new ArrayList<String>();
cacheNames.add("testing");
cacheManager.setCacheNames(cacheNames);
return cacheManager;
}
}
我很确定配置本身不是问题,因为我在其他 WAR 模块中有类似的配置文件,并且缓存在这些模块上工作正常。但是,由于这是一个由其他模块加载的 JAR,我猜测 CacheManager 没有被 Spring.
获取在依赖于 utils 项目的项目 A 中,我有如下方法(为简单起见进行了编辑;忽略无效语法):
@RequestMapping(...)
@ResponseBody
public Dto methodA(...) {
//The relevant part
testCachedMethod(value);
cachedMethodFromProjectB(value);
}
@Cacheable(value="testing")
public String testCachedMethod(String value) {
return value;
}
项目 B 是另一个 WAR,它有自己的 CacheManager(不依赖于实用程序),并且有使用 @Cacheable 缓存的类似方法。如果我点击项目 A 的 methodA,来自项目 B 的缓存会得到正确存储,但来自项目 A 的 cachedMethod 不会在缓存中存储任何内容(来自使用 @Cacheable 注释的 utils 项目的方法也不会)。我也尝试了另一种方法,直接在项目 A 上创建 CacheManager,但它也无法在 utils 项目中缓存带注释的方法(我更愿意在 utils 项目上声明管理器,以便它可以被其他模块重用).
我知道 Spring 正在正确初始化 utils 项目中的 bean,因为如果项目 A 的上下文 属性 占位符找不到 属性 文件,则项目 A 无法 运行对于缓存配置文件中的 @Value 注释。所以我假设 CacheManager bean 在那里,但不知何故它不起作用。关于我做错了什么的任何想法,或者是否甚至可以使用依赖 JAR 中的 CacheManager(如果可能,使用 Java 配置)?我正在使用 Spring 3.2.0.RELEASE.
几天来一直在努力解决这个问题,非常感谢您的帮助。
原来是 spring 缓存抽象的默认代理模式的问题。缓存注释不起作用的所有方法都被同一对象中的其他方法调用。我可以在 CacheManager bean 上使用 @Autowire 正确操作依赖 jar 项目的缓存并手动执行缓存操作。虽然应该可以通过启用 AspectJ 织入模式来使用注释,但我不想通过处理依赖模块中的织入来增加更多的复杂性。