Spring-MVC + Spring-websocket + @Cacheable 不起作用
Spring-MVC + Spring-websocket + @Cacheable don't work
我有一个关于 Spring-MVC 和 Spring-websockets 的项目,我尝试在我的服务层上插入缓存。这些是我的配置:
@Configuration
@ComponentScan(basePackages = {
"com.example"
})
@PropertySource("classpath:/configuration.properties")
@EnableWebMvc
@EnableAspectJAutoProxy(proxyTargetClass = true)
@EnableCaching
public class WebAppConfig extends WebMvcConfigurerAdapter {
@Bean
public EhCacheManagerFactoryBean ehcache() {
EhCacheManagerFactoryBean ehCache = new EhCacheManagerFactoryBean();
ehCache.setConfigLocation(new ClassPathResource("ehcache.xml"));
ehCache.setShared(true);
return ehCache;
}
@Bean
public CacheManager cacheManager() {
return new EhCacheCacheManager(ehcache().getObject());
}
//...different settings by mvc
}
和我的 websocket 配置:
@Configuration
@EnableAsync
@EnableWebSocket
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/queue/", "/topic/");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/locations").withSockJS();
}
@Override
public void configureClientOutboundChannel(ChannelRegistration registration) {
registration.taskExecutor().corePoolSize(4).maxPoolSize(10);
}
}
我想在我的服务层上使用 @Cacheable
注释:
@Service
public class StoreServiceImpl implements StoreService {
private static final Log logger = LogFactory.getLog(StoreServiceImpl.class);
@Autowired
private StoreRepository storeRepository;
@Override
@Cacheable("stores")
public Store findById(String storeId) {
return storeRepository.findById(storeId);
}
//... others methods
}
但是如果我包含注释 @EnableWebSocketMessageBroker
则缓存不起作用,因为 aop 拦截器不使用它,所以
如果我没有包含 @EnableWebSocketMessageBroker
那么缓存和 AOP 拦截器就可以正常工作。
关于websocket的文档我找到了这个信息:
In some cases a controller may need to be decorated with an AOP proxy
at runtime. One example is if you choose to have @Transactional
annotations directly on the controller. When this is the case, for
controllers specifically, we recommend using class-based proxying.
This is typically the default choice with controllers. However if a
controller must implement an interface that is not a Spring Context
callback (e.g. InitializingBean
, *Aware, etc), you may need to
explicitly configure class-based proxying. For example with
<tx:annotation-driven />
, change to <tx:annotation-driven proxy-target-class="true" />
我尝试使用 @EnableCaching(proxyTargetClass = true)
,但没有用。
有人遇到过这个问题吗?
我决定这个问题:
我在 @EnableAsync(mode = AdviceMode.ASPECTJ) 中更改了模式并且它有效。
我认为这取决于顺序初始化 BeanPostProcessors
我有一个关于 Spring-MVC 和 Spring-websockets 的项目,我尝试在我的服务层上插入缓存。这些是我的配置:
@Configuration
@ComponentScan(basePackages = {
"com.example"
})
@PropertySource("classpath:/configuration.properties")
@EnableWebMvc
@EnableAspectJAutoProxy(proxyTargetClass = true)
@EnableCaching
public class WebAppConfig extends WebMvcConfigurerAdapter {
@Bean
public EhCacheManagerFactoryBean ehcache() {
EhCacheManagerFactoryBean ehCache = new EhCacheManagerFactoryBean();
ehCache.setConfigLocation(new ClassPathResource("ehcache.xml"));
ehCache.setShared(true);
return ehCache;
}
@Bean
public CacheManager cacheManager() {
return new EhCacheCacheManager(ehcache().getObject());
}
//...different settings by mvc
}
和我的 websocket 配置:
@Configuration
@EnableAsync
@EnableWebSocket
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/queue/", "/topic/");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/locations").withSockJS();
}
@Override
public void configureClientOutboundChannel(ChannelRegistration registration) {
registration.taskExecutor().corePoolSize(4).maxPoolSize(10);
}
}
我想在我的服务层上使用 @Cacheable
注释:
@Service
public class StoreServiceImpl implements StoreService {
private static final Log logger = LogFactory.getLog(StoreServiceImpl.class);
@Autowired
private StoreRepository storeRepository;
@Override
@Cacheable("stores")
public Store findById(String storeId) {
return storeRepository.findById(storeId);
}
//... others methods
}
但是如果我包含注释 @EnableWebSocketMessageBroker
则缓存不起作用,因为 aop 拦截器不使用它,所以
如果我没有包含 那么缓存和 AOP 拦截器就可以正常工作。@EnableWebSocketMessageBroker
关于websocket的文档我找到了这个信息:
In some cases a controller may need to be decorated with an AOP proxy at runtime. One example is if you choose to have
@Transactional
annotations directly on the controller. When this is the case, for controllers specifically, we recommend using class-based proxying. This is typically the default choice with controllers. However if a controller must implement an interface that is not a Spring Context callback (e.g.InitializingBean
, *Aware, etc), you may need to explicitly configure class-based proxying. For example with<tx:annotation-driven />
, change to<tx:annotation-driven proxy-target-class="true" />
我尝试使用 @EnableCaching(proxyTargetClass = true)
,但没有用。
有人遇到过这个问题吗?
我决定这个问题: 我在 @EnableAsync(mode = AdviceMode.ASPECTJ) 中更改了模式并且它有效。 我认为这取决于顺序初始化 BeanPostProcessors