简体   繁体   中英

Spring-MVC + Spring-websocket + @Cacheable don't work

I have got a project on Spring-MVC and Spring-websockets and I try to plug cache on my service layer. These are my configuration:

@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

 }

and my websocket configuration:

@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);
  }
}

I want to use @Cacheable annotation on my service layer:

@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

}

but if I have included annotation @EnableWebSocketMessageBroker then the cache doesn't work, because aop interceptors do not use it, so if I haven't included @EnableWebSocketMessageBroker then cache and AOP interceptors work well.

The documentation on the websocket I found this information:

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 (eg 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" />

I tried use @EnableCaching(proxyTargetClass = true) , but it didn't help.

Has anyone encountered this problem?

I decided this problem: I changed mode in @EnableAsync(mode = AdviceMode.ASPECTJ) and it works. I think it depends of the order initialization BeanPostProcessors

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM