Java Spring Gemfire xml 配置

Java Config for Spring Gemfire xml

我将我的 Gemfire 的 "client-cache.xml" 定义如下:

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:gfe="http://www.springframework.org/schema/gemfire"
   xsi:schemaLocation="http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
                       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <gfe:pool id="client" subscription-enabled="true">
    <gfe:locator host="localhost" port="41114"/>
    </gfe:pool>

    <gfe:client-cache pool-name="client"/>

    <gfe:client-region id="dataRegion" name="dataRegion" pool-name="client" shortcut="PROXY"/>

</beans>

我想创建相应的 Java 配置。

我试过以下配置:

@Resource
private Cache gemfireCache;

@Resource
private Pool client;

@Bean
public PoolFactoryBean client() {
    PoolFactoryBean client = new PoolFactoryBean();
    client.setSubscriptionEnabled(true);
    client.addLocators(new ConnectionEndpoint("localhost", 41114));
    return client;
}

@Bean
public ClientRegionFactoryBean<String, AbstractContent> dataRegion() {
    ClientRegionFactoryBean<String, AbstractContent> dataRegionFactory = new ClientRegionFactoryBean<>();
    dataRegionFactory.setPoolName("client");
    dataRegionFactory.setName("dataRegion");
    dataRegionFactory.setShortcut(ClientRegionShortcut.PROXY);
    return dataRegionFactory;
}

@Bean
public ClientCacheFactoryBean gemfireCache() {
    ClientCacheFactoryBean clientCacheFactory = new ClientCacheFactoryBean();
    clientCacheFactory.setPoolName("client");
    clientCacheFactory.setPdxSerializer(mappingPdxSerializer());
    return clientCacheFactory;
}

@Bean
public PlatformTransactionManager gemfireTransactionManager() throws Exception {
    return new GemfireTransactionManager(gemfireCache);
}

但是,我将 运行 保留为异常:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.gemstone.gemfire.cache.client.ClientCache] is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:372)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:369)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:332)
at org.springframework.data.gemfire.client.PoolFactoryBean.eagerlyInitializeClientCacheIfNotPresent(PoolFactoryBean.java:218)
at org.springframework.data.gemfire.client.PoolFactoryBean.getObject(PoolFactoryBean.java:171)
at org.springframework.data.gemfire.client.PoolFactoryBean.getObject(PoolFactoryBean.java:65)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:168)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:103)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1590)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:317)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:296)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)

难道不能把上面的XML改成Java的配置吗?

如有任何帮助,我们将不胜感激。 谢谢。

===============根据约翰的评论编辑如下==============

@约翰,

我尝试了@ sample test case for gemfire client 中提到的示例,并且示例原样运行良好。 我正在使用定位器,该示例在定位器配置下运行良好 gemfirePool.setLocators(Collections.singletonList(new InetSocketAddress(host, port)))。 但是,根据 Pivotal 支持的建议,我正在使用 spring-data-gemfire 版本 1.8.2.RELEASE。 所以,我

测试用例折腾了

测试用例开始给我以下异常:

java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:228)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:230)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:249)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access[=16=]0(ParentRunner.java:58)
    at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'gemfireCache' defined in io.pivotal.gemfire.cache.client.SpringGemFireClientCacheTest$SpringGemFireClientConfiguration: Unsatisfied dependency expressed through constructor argument with index 1 of type [com.gemstone.gemfire.cache.client.Pool]: : Error creating bean with name 'gemfirePool': FactoryBean threw exception on object creation; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.gemstone.gemfire.cache.client.ClientCache] is defined; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gemfirePool': FactoryBean threw exception on object creation; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.gemstone.gemfire.cache.client.ClientCache] is defined
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:464)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:753)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:125)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:109)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:261)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
    ... 25 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gemfirePool': FactoryBean threw exception on object creation; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.gemstone.gemfire.cache.client.ClientCache] is defined
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:175)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:103)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1585)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:254)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1192)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813)
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
    ... 43 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.gemstone.gemfire.cache.client.ClientCache] is defined
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:372)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:332)
    at org.springframework.data.gemfire.client.PoolFactoryBean.eagerlyInitializeClientCacheIfNotPresent(PoolFactoryBean.java:218)
    at org.springframework.data.gemfire.client.PoolFactoryBean.getObject(PoolFactoryBean.java:171)
    at org.springframework.data.gemfire.client.PoolFactoryBean.getObject(PoolFactoryBean.java:65)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:168)
    ... 52 more

看来,这是 spring-data-gemfire 1.8.2.RELEASE 的问题。 我不太确定我是否应该简单地恢复到 1.6。2.RELEASE 并且,如果恢复到以前的修订版我会失去什么。

我创建了另一个示例 spring 启动应用程序:

上面的代码也行不通,returns同样的异常。我尝试了上面的代码,默认版本 "spring-data-gemfire" 包含在 io.spring.platform (1.7.4.RELEASE) 中,结果仍然相同。

------------POST 约翰的评论和参考程序--------------------

非常感谢约翰。您提供的示例对我有帮助,但是,我不得不对代码进行一些更改。下面是我的最终项目的样子(如果你注意到,我正在注入 GemfireCache 而不是 ClientCache):

尝试使用 bean 方法而不是@Resource,例如

return new GemfireTransactionManager(gemfireCache());

NoSuchBeanDefinitionException 属于应用程序 Java 配置中注入的 Cache 引用 class...

@Resource
private Cache gemfireCache

NOTE: you might prefer to use @Inject or Spring's @Autowired annotation instead, since this is technically more accurate.

这里的问题是在你的 Spring 中没有 Spring 定义类型为“Cache”的 bean Java 配置。

如果您 look more closely at the ClientCacheFactoryBean, getObjectType() method, which Spring uses to inspect bean (definitions) during autowiring of application components "by type", you see that it returns ClientCache.class. Technically, ClientCacheFactoryBean.getObjectType() also returns the actual cache object's type, but I do not recall when Spring inspects the available bean definitions to resolve type dependencies. Plus, I think the Spring container also maintains a type-to-bean mapping (a.k.a. cache) during parsing. The only reason the later is relevant is because GemFire only has 1 implementation of Cache and ClientCache, and that implementation, namely GemFireCacheImpl 实现了这两个接口。所以,它看起来应该是可以解决的,但是...

无论如何,所有这些都是为了更清楚地解释异常。

很遗憾,您不能使用...

return new GemfireTransactionManager(gemfireCache());

由于 gemfireCache() bean 定义 "method" returns ClientCacheFactoryBean 的实例和 GemfireTransactionManager 构造函数需要 Cache 的实例.

但是,您可以根据 SDG FactoryBeans 的需要定义 CacheClientCacheGemFireCache 类型的参数。例如,您的 gemfireTransactionManager bean 可以定义为...

@Bean
public PlatformTransactionManager gemfireTransactionManager(GemFireCache gemfireCache) {
  return new GemfireTransactionManager((Cache) gemfireCache));
}

NOTE: ClientCache extends GemFireCache.

同样,您的 Region bean 定义,“dataRegion”也期望并可以采用这样的缓存实例...

@Bean
public ClientRegionFactoryBean<String, AbstractContent> dataRegion(ClientCache gemfireCache, Pool gemfirePool) {
  ...
  dataRegion.setCache(gemfireCache);
  dataRegion.setPool(gemfirePool);
  ...
}

另请注意,我可以传递对 GemFire 池的引用,区域 应该将其用于对集群服务器的数据访问操作。

Spring 将 Java 配置 @Bean 定义方法参数视为 "type dependencies",因此您可以只定义相关 bean 组件所需的预期结果 bean 类型(例如 "gemfireTransactionManager" 需要 "Cache" bean 依赖)。

一般来说,从XML切换到Java配置是没有问题的。事实上,我鼓励它,甚至在我的示例中越来越多地使用 Java 配置(从 instance). In time I plan to convert most of the spring-gemfire-examples 到使用 Spring Boot 和Java配置。

说到 spring-gemfire-examples, there is also an example with Java config. But, I think this example demonstrates a peer cache. So, you may find the examples in 3 更有帮助,因为我使用 XML 和 Java 比较和对比了 GemFire 本机配置和 Spring 配置。

例如,我的 ClientCache Java 配置示例同时具有 GemFire 缓存 server Java config and client Java config.

无论如何,希望这对您有所帮助,如果您还有其他问题,请随时与我们联系。

干杯, 约翰

更新 - 2016-07-19

此问题的示例(和测试)使用您的 GemFire 缓存客户端,Spring Java 配置提供 here

运行 spring 使用 Geode 启动测试我有这样的启动错误(路径已编辑):

Invalid bean definition with name 'gemfireCache' defined in class path resource... CacheServerConfiguration... There is already... ClientCacheConfiguration... defined in class path resource... bound

已通过添加修复 spring.main.allow-bean-definition-overriding=true 到我的 application.properties 文件