Inject SpringManagedContext into Hazelcast configuration
This commit makes it possible to inject Spring managed beans into objects instantiated by Hazelcast. See gh-28801
This commit is contained in:
parent
6d55b687f7
commit
b875b55711
|
|
@ -25,8 +25,12 @@ import com.hazelcast.config.YamlConfigBuilder;
|
|||
import com.hazelcast.core.Hazelcast;
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
|
||||
import com.hazelcast.spring.context.SpringManagedContext;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
|
@ -60,10 +64,14 @@ class HazelcastServerConfiguration {
|
|||
static class HazelcastServerConfigFileConfiguration {
|
||||
|
||||
@Bean
|
||||
HazelcastInstance hazelcastInstance(HazelcastProperties properties, ResourceLoader resourceLoader)
|
||||
HazelcastInstance hazelcastInstance(HazelcastProperties properties, ResourceLoader resourceLoader,
|
||||
ObjectProvider<ConfigurationCustomizer> customizerProvider)
|
||||
throws IOException {
|
||||
Resource configLocation = properties.resolveConfigLocation();
|
||||
Config config = (configLocation != null) ? loadConfig(configLocation) : Config.load();
|
||||
customizerProvider.ifAvailable(c -> {
|
||||
c.customize(config);
|
||||
});
|
||||
config.setClassLoader(resourceLoader.getClassLoader());
|
||||
return getHazelcastInstance(config);
|
||||
}
|
||||
|
|
@ -93,7 +101,6 @@ class HazelcastServerConfiguration {
|
|||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnSingleCandidate(Config.class)
|
||||
static class HazelcastServerConfigConfiguration {
|
||||
|
||||
@Bean
|
||||
HazelcastInstance hazelcastInstance(Config config) {
|
||||
return getHazelcastInstance(config);
|
||||
|
|
@ -101,6 +108,29 @@ class HazelcastServerConfiguration {
|
|||
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
private interface ConfigurationCustomizer {
|
||||
void customize(Config configuration);
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(name = "com.hazelcast.spring.context.SpringManagedContext")
|
||||
static class HazelcastConfigCustomizerConfiguration {
|
||||
private final ApplicationContext applicationContext;
|
||||
|
||||
public HazelcastConfigCustomizerConfiguration(ApplicationContext applicationContext) {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ConfigurationCustomizer springManagedContextConfigurationCustomizer() {
|
||||
return configuration -> {
|
||||
SpringManagedContext springManagedContext = new SpringManagedContext(applicationContext);
|
||||
configuration.setManagedContext(springManagedContext);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link HazelcastConfigResourceCondition} that checks if the
|
||||
* {@code spring.hazelcast.config} configuration key is defined.
|
||||
|
|
|
|||
|
|
@ -22,14 +22,21 @@ import com.hazelcast.config.Config;
|
|||
import com.hazelcast.config.QueueConfig;
|
||||
import com.hazelcast.core.Hazelcast;
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
import com.hazelcast.map.EntryProcessor;
|
||||
import com.hazelcast.map.IMap;
|
||||
import com.hazelcast.spring.context.SpringAware;
|
||||
import com.hazelcast.spring.context.SpringManagedContext;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.runner.ContextConsumer;
|
||||
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
|
@ -164,6 +171,55 @@ class HazelcastAutoConfigurationServerTests {
|
|||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void defaultConfigFile_injectManagedContext() {
|
||||
this.contextRunner.run((context) -> {
|
||||
HazelcastInstance hz = context.getBean(HazelcastInstance.class);
|
||||
IMap<Integer, Integer> map = hz.getMap("myMap");
|
||||
boolean contextInjected = map.executeOnKey(42, new SpringAwareEntryProcessor<>());
|
||||
assertThat(contextInjected).isEqualTo(true);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void defaultConfigFile_injectManagedContext_SpringHazelcastModuleNotAvailable() {
|
||||
this.contextRunner
|
||||
.withClassLoader(new FilteredClassLoader(SpringManagedContext.class))
|
||||
.run((context) -> {
|
||||
HazelcastInstance hz = context.getBean(HazelcastInstance.class);
|
||||
IMap<Integer, Integer> map = hz.getMap("myMap");
|
||||
boolean contextInjected = map.executeOnKey(42, new SpringAwareEntryProcessor<>());
|
||||
assertThat(contextInjected).isEqualTo(false);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void explicitConfigFile_injectManagedContext() {
|
||||
this.contextRunner
|
||||
.withSystemProperties(HazelcastServerConfiguration.CONFIG_SYSTEM_PROPERTY
|
||||
+ "=classpath:org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.yaml")
|
||||
.run((context) -> {
|
||||
HazelcastInstance hz = context.getBean(HazelcastInstance.class);
|
||||
IMap<Integer, Integer> map = hz.getMap("myMap");
|
||||
boolean contextInjected = map.executeOnKey(42, new SpringAwareEntryProcessor<>());
|
||||
assertThat(contextInjected).isEqualTo(true);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void explicitConfigFile_injectManagedContext_SpringHazelcastModuleNotAvailable() {
|
||||
this.contextRunner
|
||||
.withClassLoader(new FilteredClassLoader(SpringManagedContext.class))
|
||||
.withSystemProperties(HazelcastServerConfiguration.CONFIG_SYSTEM_PROPERTY
|
||||
+ "=classpath:org/springframework/boot/autoconfigure/hazelcast/hazelcast-specific.yaml")
|
||||
.run((context) -> {
|
||||
HazelcastInstance hz = context.getBean(HazelcastInstance.class);
|
||||
IMap<Integer, Integer> map = hz.getMap("myMap");
|
||||
boolean contextInjected = map.executeOnKey(42, new SpringAwareEntryProcessor<>());
|
||||
assertThat(contextInjected).isEqualTo(false);
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class HazelcastConfigWithName {
|
||||
|
||||
|
|
@ -174,6 +230,17 @@ class HazelcastAutoConfigurationServerTests {
|
|||
|
||||
}
|
||||
|
||||
@SpringAware
|
||||
static class SpringAwareEntryProcessor<K, V> implements EntryProcessor<K, V, Boolean> {
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Override
|
||||
public Boolean process(Map.Entry<K, V> entry) {
|
||||
return context != null;
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class HazelcastConfigNoName {
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue