java - 带有 Ehcache 3.x 的 Spring Boot 2.x - @Autowired 服务在自定义 CacheEventListener 中为空
问题描述
我使用 Ehcache 作为缓冲区为连接到 WebSocket(Spring) 的所有客户端传递数据。
CacheEventListener 实现:
public class CacheListener implements CacheEventListener<ArrayList, MeasurementPoint> {
@Autowired
private SimpMessagingTemplate simpMessagingTemplate; //<-- This is null at runtime
@Override
public void onEvent(CacheEvent<? extends ArrayList, ? extends MeasurementPoint> cacheEvent) {
simpMessagingTemplate.convertAndSend("/topic/measurementsPoints", cacheEvent.getNewValue());
}
}
ehcache配置xml:
config
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns='http://www.ehcache.org/v3'
xsi:schemaLocation="
http://www.ehcache.org/v3
http://www.ehcache.org/schema/ehcache-core-3.7.xsd">
<!-- Default cache template -->
<cache-template name="default">
<resources>
<heap>1000</heap>
<offheap unit="MB">10</offheap>
</resources>
</cache-template>
<cache alias="measurementsCache" uses-template="default">
<key-type>java.util.ArrayList</key-type>
<value-type>br.com.petrobras.risersupervisory.model.MeasurementPoint</value-type>
<listeners>
<listener>
<class>br.com.petrobras.risersupervisory.framework.CacheListener</class>
<event-firing-mode>ASYNCHRONOUS</event-firing-mode>
<event-ordering-mode>UNORDERED</event-ordering-mode>
<events-to-fire-on>CREATED</events-to-fire-on>
<events-to-fire-on>UPDATED</events-to-fire-on>
</listener>
</listeners>
</cache>
</config>
我尝试遵循一些教程,但它们都在 CacheEventListener 实现中使用日志库或 System.out.println。
有什么办法可以在 CacheEventListener 中自动装配 @Service(Spring) 吗?这个实现是错误的吗?我找不到在 CacheEventListener 中使用 @Autowired 的单个示例。
Obs:不仅 SimpMessagingTemplate 在运行时为空。我也尝试过自动装配一个自定义类,结果是一样的。
Obs2:在搜索spring boot日志后,我相信在spring boot完成加载之前CacheEventListener已经绑定到缓存了。不确定这是否是问题所在。
解决方案
Obs2:在搜索spring boot日志后,我相信在spring boot完成加载之前CacheEventListener已经绑定到缓存了。不确定这是否是问题所在。
这暗示了您的问题,您不能将 spring bean 注入到非 spring 托管对象实例中。您可以使用一个简单的类为您提供对 spring 上下文的静态访问,以加载此处描述的 bean 。
@Component
public class SpringContext implements ApplicationContextAware {
private static ApplicationContext context;
public static <T extends Object> T getBean(Class<T> beanClass) {
return context.getBean(beanClass);
}
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException
{
// store ApplicationContext reference to access required beans later on
SpringContext.context = context;
}
}
SpringContext.getBean(YourBean.class);
如果您在 spring 上下文初始化之前尝试这样做,您可能仍然会遇到问题。值得一提的是,通过依赖spring-boot
支持ehcache 3.x。org.springframework.boot:spring-boot-starter-cache
我不知道这是否适合您的目的,但如果 ehcache 与 spring 集成可能会更容易。
推荐阅读
- c# - C# 程序无法使用 NPOI 库写入 Excel 文件
- ruby-on-rails - 向我的控制器添加一个操作,它将列表作为 JSON 返回
- python - python - 如何将输入作为整数放入由python中的空格分隔的列表中?
- javascript - 如何在选择选项中为特定单词设置颜色?
- javascript - 在 Vuex 存储中使用全局变量
- git - Git如何查找或添加.gitignore
- gunicorn - gunicorn 重启后不启动
- java - 从 azure Key vault 按值获取秘密名称
- ios - Tipsi 条纹不适用于 iOS 和 React Native
- angular - 角度输入应仅接受数字,但第一个数字不应为零