0

使用 JCache 并启用缓存时,默认的 Spring boot 自动配置似乎会创建两个 hazelcast 实例(@EnableCaching

完整示例位于:https ://github.com/dirkvanrensburg/hazelcast-springboot-jcache

TLDR; 当通过 JCache 启用缓存时,有没有办法让 Spring Boot 的自动配置只创建一个 Hazelcast 实例?

我通过添加以下依赖项创建了一个演示 Spring Boot 项目:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>

    <dependency>
        <groupId>javax.cache</groupId>
        <artifactId>cache-api</artifactId>
    </dependency>

    <dependency>
        <groupId>com.hazelcast</groupId>
        <artifactId>hazelcast</artifactId>
    </dependency>

    <dependency>
        <groupId>com.hazelcast</groupId>
        <artifactId>hazelcast-spring</artifactId>
        <version>${hazelcast.version}</version>
    </dependency>

并添加@EnableCaching到 Application 类中,Spring 将自动配置 Hazelcast 但启动两个 hazelcast 实例,如日志所示,它们加入集群:

Members [2] {
    Member [192.168.1.157]:5701 - 3eabbe90-6815-49ff-8d93-9e4b12e67810
    Member [192.168.1.157]:5702 - e9c93366-2408-4726-965a-b21dcf897113 this
}

缓存有效,但我不想要两个 Hazelcast 实例。

哈克

我设法通过提供自己的缓存管理器使其工作:

@Bean
public CacheManager springHzProvider(HazelcastInstance instance) {
    return SpringHazelcastCachingProvider.getCacheManager(instance, null, new Properties());
}

并删除hazelcasthazelcast-spring依赖项并添加hazelcast-all

    <dependency>
        <groupId>com.hazelcast</groupId>
        <artifactId>hazelcast-all</artifactId>
        <version>${hazelcast.version}</version>
    </dependency>

但问题仍然是是否有更好的“正确”方法来实现这一目标?理想情况下,无需定义自定义缓存管理器并添加hazelcast-all

4

2 回答 2

3

@dvanrensburg 根据评论,作为临时解决方案,将该HazelcastAutoConfiguration类排除在自动配置之外。我已经记录了 Spring Boot https://github.com/spring-projects/spring-boot/issues/8275@EnableCaching的问题,因为我认为这是根本原因,如果触发了创建第二个实例,则不应创建第一的。

于 2017-02-13T10:06:25.790 回答
1

我在上面使用了 Neil 的解决方案,但遇到了无法自动装配由 JCache 配置创建的 Hazelcast 实例的情况。看起来该实例是在 Spring 之外创建并在应用程序上下文中注册的。

在配置中为实例命名

<instance-name>test</instance-name>

然后添加一个显式钩子以将实例带入上下文

@Bean
public HazelcastInstance getInstance() {
    return Hazelcast.getHazelcastInstanceByName("test");
}

效果很好。不会运行,HazelcastAutoconfiguration因为它对尚不存在的实例有条件。

我唯一担心的是,这在很大程度上依赖于这样一个事实,即对于 Spring Boot 1.5.1 版,JCache 配置会在 HazelcastAutoconfiguration 启动之前创建此实例。

更新 在优秀的 Spring Boot 社区的@snicoll 的帮助下,我找到了更好的解决方案。

只需明确告诉 Spring Boot 使用哪个 hazelcast 配置并命名 Hazelcast 实例。将以下内容放入application.properties spring.hazelcast.config=hazelcast.xml

示例见:https ://github.com/dirkvanrensburg/hazelcast-springboot-jcache/tree/fixed

于 2017-02-16T21:37:55.170 回答