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。
所以,我
- 将 spring-data-gemfire 版本升级到 1.8。2.RELEASE @ pom.xml,
- 修复了编译错误
(评论 gemfireCache.setLazyInitialize(true)
),
- 并将
gemfirePool.setLocators(Collections.singletonList(new InetSocketAddress(locatorHost, locatorPort)))
更改为 gemfirePool.addLocators(Collections.singletonList(new ConnectionEndpoint(locatorHost, locatorPort)))
、
测试用例折腾了
测试用例开始给我以下异常:
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 启动应用程序:
pom.xml
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
com.cdk.test
测试 GemfireLocators
0.0.1-快照
<parent>
<groupId>io.spring.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>2.0.6.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-gemfire</artifactId>
<version>1.8.2.RELEASE</version>
</dependency>
</dependencies>
Application.java
@SpringBootApplication
public class 申请 {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean(name = "region")
public ClientRegionFactoryBean region(ClientCache gemfireCache, Pool gemfirePool) {
ClientRegionFactoryBean versionedRegion = new ClientRegionFactoryBean();
versionedRegion.setName("region");
versionedRegion.setCache(gemfireCache);
versionedRegion.setPool(gemfirePool);
versionedRegion.setShortcut(ClientRegionShortcut.PROXY);
return versionedRegion;
}
@Bean
public ClientCacheFactoryBean gemfireCache(@Qualifier("gemfireProperties") Properties gemfireProperties,
Pool gemfirePool) {
ClientCacheFactoryBean gemfireCache = new ClientCacheFactoryBean();
gemfireCache.setPool(gemfirePool);
gemfireCache.setProperties(gemfireProperties);
return gemfireCache;
}
@Bean(name = GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME)
public PoolFactoryBean gemfirePool(@Value("${locator.host}") String host, @Value("${locator.port}") int port) {
PoolFactoryBean gemfirePool = new PoolFactoryBean();
gemfirePool.setName(GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME);
gemfirePool.setSubscriptionEnabled(true);
gemfirePool.addLocators(new ConnectionEndpoint(host, port));
return gemfirePool;
}
@Bean
public Properties gemfireProperties(@Value("${gemfire.log.level:config}") String logLevel) {
Properties gemfireProperties = new Properties();
gemfireProperties.setProperty("log-level", logLevel);
return gemfireProperties;
}
}
上面的代码也行不通,returns同样的异常。我尝试了上面的代码,默认版本 "spring-data-gemfire" 包含在 io.spring.platform
(1.7.4.RELEASE) 中,结果仍然相同。
------------POST 约翰的评论和参考程序--------------------
非常感谢约翰。您提供的示例对我有帮助,但是,我不得不对代码进行一些更改。下面是我的最终项目的样子(如果你注意到,我正在注入 GemfireCache
而不是 ClientCache
):
pom.xml
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
com.cdk.test
测试 GemfireLocators
0.0.1-快照
<parent>
<groupId>io.spring.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>2.0.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-gemfire</artifactId>
<version>1.8.2.RELEASE</version>
</dependency>
</dependencies>
Application.java
@SpringBootApplication
public class 申请 {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Resource(name = "myRegion")
private Region<String, Object> myRegion;
int intValue(Long value) {
return value.intValue();
}
String logLevel() {
return System.getProperty("gemfire.log-level", "config");
}
Properties gemfireProperties() {
Properties gemfireProperties = new Properties();
gemfireProperties.setProperty("log-level", logLevel());
return gemfireProperties;
}
@Bean
ClientCacheFactoryBean gemfireCache() {
ClientCacheFactoryBean gemfireCache = new ClientCacheFactoryBean();
gemfireCache.setClose(true);
gemfireCache.setProperties(gemfireProperties());
return gemfireCache;
}
@Bean(name = GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME)
PoolFactoryBean gemfirePool(@Value("${locator.host}") String host, @Value("${locator.port}") int port) {
PoolFactoryBean gemfirePool = new PoolFactoryBean();
gemfirePool.setKeepAlive(false);
gemfirePool.setSubscriptionEnabled(true);
gemfirePool.setThreadLocalConnections(false);
gemfirePool.addLocators(new ConnectionEndpoint(host, port));
return gemfirePool;
}
@Bean(name = "myRegion")
ClientRegionFactoryBean<String, Object> myRegion(@Value("${region.name}") String regionName, GemFireCache gemfireCache,
Pool gemfirePool) {
ClientRegionFactoryBean<String, Object> myRegion = new ClientRegionFactoryBean<>();
myRegion.setCache(gemfireCache);
myRegion.setName(regionName);
myRegion.setPool(gemfirePool);
myRegion.setShortcut(ClientRegionShortcut.PROXY);
return myRegion;
}
@Bean
PlatformTransactionManager gemfireTransactionManager(GemFireCache gemfireCache) {
return new GemfireTransactionManager((Cache) gemfireCache);
}
}
尝试使用 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
的需要定义 Cache
、ClientCache
和 GemFireCache
类型的参数。例如,您的 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
文件
我将我的 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。
所以,我
- 将 spring-data-gemfire 版本升级到 1.8。2.RELEASE @ pom.xml,
- 修复了编译错误
(评论gemfireCache.setLazyInitialize(true)
), - 并将
gemfirePool.setLocators(Collections.singletonList(new InetSocketAddress(locatorHost, locatorPort)))
更改为gemfirePool.addLocators(Collections.singletonList(new ConnectionEndpoint(locatorHost, locatorPort)))
、
测试用例折腾了
测试用例开始给我以下异常:
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 启动应用程序:
pom.xml
http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.cdk.test 测试 GemfireLocators 0.0.1-快照
<parent> <groupId>io.spring.platform</groupId> <artifactId>platform-bom</artifactId> <version>2.0.6.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j</artifactId> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-gemfire</artifactId> <version>1.8.2.RELEASE</version> </dependency> </dependencies>
Application.java
@SpringBootApplication public class 申请 {
public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean(name = "region") public ClientRegionFactoryBean region(ClientCache gemfireCache, Pool gemfirePool) { ClientRegionFactoryBean versionedRegion = new ClientRegionFactoryBean(); versionedRegion.setName("region"); versionedRegion.setCache(gemfireCache); versionedRegion.setPool(gemfirePool); versionedRegion.setShortcut(ClientRegionShortcut.PROXY); return versionedRegion; } @Bean public ClientCacheFactoryBean gemfireCache(@Qualifier("gemfireProperties") Properties gemfireProperties, Pool gemfirePool) { ClientCacheFactoryBean gemfireCache = new ClientCacheFactoryBean(); gemfireCache.setPool(gemfirePool); gemfireCache.setProperties(gemfireProperties); return gemfireCache; } @Bean(name = GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME) public PoolFactoryBean gemfirePool(@Value("${locator.host}") String host, @Value("${locator.port}") int port) { PoolFactoryBean gemfirePool = new PoolFactoryBean(); gemfirePool.setName(GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME); gemfirePool.setSubscriptionEnabled(true); gemfirePool.addLocators(new ConnectionEndpoint(host, port)); return gemfirePool; } @Bean public Properties gemfireProperties(@Value("${gemfire.log.level:config}") String logLevel) { Properties gemfireProperties = new Properties(); gemfireProperties.setProperty("log-level", logLevel); return gemfireProperties; }
}
上面的代码也行不通,returns同样的异常。我尝试了上面的代码,默认版本 "spring-data-gemfire" 包含在 io.spring.platform
(1.7.4.RELEASE) 中,结果仍然相同。
------------POST 约翰的评论和参考程序--------------------
非常感谢约翰。您提供的示例对我有帮助,但是,我不得不对代码进行一些更改。下面是我的最终项目的样子(如果你注意到,我正在注入 GemfireCache
而不是 ClientCache
):
pom.xml
http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.cdk.test 测试 GemfireLocators 0.0.1-快照
<parent> <groupId>io.spring.platform</groupId> <artifactId>platform-bom</artifactId> <version>2.0.5.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j</artifactId> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-gemfire</artifactId> <version>1.8.2.RELEASE</version> </dependency> </dependencies>
Application.java
@SpringBootApplication public class 申请 {
public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Resource(name = "myRegion") private Region<String, Object> myRegion; int intValue(Long value) { return value.intValue(); } String logLevel() { return System.getProperty("gemfire.log-level", "config"); } Properties gemfireProperties() { Properties gemfireProperties = new Properties(); gemfireProperties.setProperty("log-level", logLevel()); return gemfireProperties; } @Bean ClientCacheFactoryBean gemfireCache() { ClientCacheFactoryBean gemfireCache = new ClientCacheFactoryBean(); gemfireCache.setClose(true); gemfireCache.setProperties(gemfireProperties()); return gemfireCache; } @Bean(name = GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME) PoolFactoryBean gemfirePool(@Value("${locator.host}") String host, @Value("${locator.port}") int port) { PoolFactoryBean gemfirePool = new PoolFactoryBean(); gemfirePool.setKeepAlive(false); gemfirePool.setSubscriptionEnabled(true); gemfirePool.setThreadLocalConnections(false); gemfirePool.addLocators(new ConnectionEndpoint(host, port)); return gemfirePool; } @Bean(name = "myRegion") ClientRegionFactoryBean<String, Object> myRegion(@Value("${region.name}") String regionName, GemFireCache gemfireCache, Pool gemfirePool) { ClientRegionFactoryBean<String, Object> myRegion = new ClientRegionFactoryBean<>(); myRegion.setCache(gemfireCache); myRegion.setName(regionName); myRegion.setPool(gemfirePool); myRegion.setShortcut(ClientRegionShortcut.PROXY); return myRegion; } @Bean PlatformTransactionManager gemfireTransactionManager(GemFireCache gemfireCache) { return new GemfireTransactionManager((Cache) gemfireCache); }
}
尝试使用 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
的需要定义 Cache
、ClientCache
和 GemFireCache
类型的参数。例如,您的 gemfireTransactionManager
bean 可以定义为...
@Bean
public PlatformTransactionManager gemfireTransactionManager(GemFireCache gemfireCache) {
return new GemfireTransactionManager((Cache) gemfireCache));
}
NOTE:
ClientCache
extendsGemFireCache
.
同样,您的 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
文件