Spring 使用 LoadTimeWeaving 使用 Couchbase 进行缓存 - 奇怪的是不工作
Spring Cache With Couchbase Using LoadTimeWeaving - Strangely Not Working
我正在使用注释在现有 spring 项目上添加 Spring 缓存。我使用 Couchbase 作为缓存提供程序。我想使用 AspectJ 的加载时间编织来允许私有方法调用和 case class 方法调用也被缓存。
我已经被这个问题困扰了三天,我已经阅读了数十篇文章、文档和示例,但这个东西就是行不通。
这就是我所做的 -
@Configuration
@EnableSpringConfigured
@EnableAspectJAutoProxy
@EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.ENABLED)
@EnableTransactionManagement
@EnableRetry
@PropertySource(
value = {"classpath:application.properties", "classpath:${spring.profiles.active}.properties"},
ignoreResourceNotFound = true)
public class BeanConfig implements LoadTimeWeavingConfigurer {
... various beans here ...
@Override
public LoadTimeWeaver getLoadTimeWeaver() {
return new TomcatLoadTimeWeaver();// because I'm using Tomcat 7
}
@Bean
public InstrumentationLoadTimeWeaver loadTimeWeaver() throws Throwable {
return new InstrumentationLoadTimeWeaver();
}
}
@Configuration
@EnableSpringConfigured
@EnableCaching(mode = AdviceMode.ASPECTJ)
@ComponentScan(basePackages = "com.foo.bar.dao.cache.couchbase")
public class CacheConfigurer extends CachingConfigurerSupport {
@Bean
@Override
public CacheManager cacheManager() {
... cachemanager configuration here ...
}
}
然后我在 class 上的 DAO 方法上有 @Chacheable
,而不是在接口上。
最后,在我的 Tomcat 7 的 $CATALINA_HOME/conf/context.xml 我有 -
<Context>
<Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
</Context>
我在 pom.xml(它是一个 Maven 项目)中添加了以下依赖项 -
- couchbase-spring-缓存
- spring-方面
- aspectjweaver
- aspectjrt
- spring-仪器
- spring-仪器-tomcat
如果我不使用 LTW 缓存,则可以很好地处理通过接口到达的方法调用(它应该如此)。但是在我启用 LTW 缓存后根本不起作用 - 任何方法调用都没有缓存,也没有错误。
有没有人尝试过将 LTW 用于 Spring 带 couchbase 的缓存?我在这里遗漏了什么或做错了什么?
我在 Spring 4.3.5.Release.
更新-
这是我复制这种情况的最少代码 - https://github.com/harshilsharma63/spring-boilerplate-with-cache
忘记 class 基于加载器的加载时间编织,尤其是 Tomcat < 8.0。你会遇到很多与 class 加载顺序相关的问题,一些 classes 在 spring 安装他的 weaving classloader 之前加载,你会最终会遇到一些难以调试的问题 classes 没有被编织等。相反,请使用 java 代理。
以下是如何通过切换到 java 基于代理的编织来修复 Tomcat 7 的配置:
- 删除
@EnableLoadTimeWeaving
个注释。
- 从
context.xml
中删除 <Loader loaderClass...
。
- 将
-javaagent:/path/to/aspectjweaver.jar
添加到您的 JVM 启动参数。
如果您愿意转到 Tomcat 8,请执行以下步骤:
- 将
@EnableLoadTimeWeaving(aspectjWeaving=ENABLED)
移动到单独的配置class,我们将其命名为WeavingConfig
。
- 更改您的
WebInitializer
class 以便 getRootConfigClasses()
您 return 仅 WeavingConfig.class
.
- 将其他必需的配置 class 移至
getServletConfigClasses()
。
- 从
context.xml
、@EnableAspectJAutoProxy
. 中删除不需要的配置,例如 <Loader loaderClass...
- 利润。
当然最好还是只用编译时织入
我正在使用注释在现有 spring 项目上添加 Spring 缓存。我使用 Couchbase 作为缓存提供程序。我想使用 AspectJ 的加载时间编织来允许私有方法调用和 case class 方法调用也被缓存。
我已经被这个问题困扰了三天,我已经阅读了数十篇文章、文档和示例,但这个东西就是行不通。
这就是我所做的 -
@Configuration
@EnableSpringConfigured
@EnableAspectJAutoProxy
@EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.ENABLED)
@EnableTransactionManagement
@EnableRetry
@PropertySource(
value = {"classpath:application.properties", "classpath:${spring.profiles.active}.properties"},
ignoreResourceNotFound = true)
public class BeanConfig implements LoadTimeWeavingConfigurer {
... various beans here ...
@Override
public LoadTimeWeaver getLoadTimeWeaver() {
return new TomcatLoadTimeWeaver();// because I'm using Tomcat 7
}
@Bean
public InstrumentationLoadTimeWeaver loadTimeWeaver() throws Throwable {
return new InstrumentationLoadTimeWeaver();
}
}
@Configuration
@EnableSpringConfigured
@EnableCaching(mode = AdviceMode.ASPECTJ)
@ComponentScan(basePackages = "com.foo.bar.dao.cache.couchbase")
public class CacheConfigurer extends CachingConfigurerSupport {
@Bean
@Override
public CacheManager cacheManager() {
... cachemanager configuration here ...
}
}
然后我在 class 上的 DAO 方法上有 @Chacheable
,而不是在接口上。
最后,在我的 Tomcat 7 的 $CATALINA_HOME/conf/context.xml 我有 -
<Context>
<Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
</Context>
我在 pom.xml(它是一个 Maven 项目)中添加了以下依赖项 -
- couchbase-spring-缓存
- spring-方面
- aspectjweaver
- aspectjrt
- spring-仪器
- spring-仪器-tomcat
如果我不使用 LTW 缓存,则可以很好地处理通过接口到达的方法调用(它应该如此)。但是在我启用 LTW 缓存后根本不起作用 - 任何方法调用都没有缓存,也没有错误。
有没有人尝试过将 LTW 用于 Spring 带 couchbase 的缓存?我在这里遗漏了什么或做错了什么?
我在 Spring 4.3.5.Release.
更新-
这是我复制这种情况的最少代码 - https://github.com/harshilsharma63/spring-boilerplate-with-cache
忘记 class 基于加载器的加载时间编织,尤其是 Tomcat < 8.0。你会遇到很多与 class 加载顺序相关的问题,一些 classes 在 spring 安装他的 weaving classloader 之前加载,你会最终会遇到一些难以调试的问题 classes 没有被编织等。相反,请使用 java 代理。
以下是如何通过切换到 java 基于代理的编织来修复 Tomcat 7 的配置:
- 删除
@EnableLoadTimeWeaving
个注释。 - 从
context.xml
中删除<Loader loaderClass...
。 - 将
-javaagent:/path/to/aspectjweaver.jar
添加到您的 JVM 启动参数。
如果您愿意转到 Tomcat 8,请执行以下步骤:
- 将
@EnableLoadTimeWeaving(aspectjWeaving=ENABLED)
移动到单独的配置class,我们将其命名为WeavingConfig
。 - 更改您的
WebInitializer
class 以便getRootConfigClasses()
您 return 仅WeavingConfig.class
. - 将其他必需的配置 class 移至
getServletConfigClasses()
。 - 从
context.xml
、@EnableAspectJAutoProxy
. 中删除不需要的配置,例如 - 利润。
<Loader loaderClass...
当然最好还是只用编译时织入