diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/BeanFactoryLocatorConfiguration.java b/src/main/java/org/springframework/data/gemfire/config/annotation/BeanFactoryLocatorConfiguration.java new file mode 100644 index 00000000..27e1018e --- /dev/null +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/BeanFactoryLocatorConfiguration.java @@ -0,0 +1,68 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.data.gemfire.config.annotation; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.gemfire.CacheFactoryBean; +import org.springframework.data.gemfire.support.GemfireBeanFactoryLocator; + +/** + * The {@link BeanFactoryLocatorConfiguration} class extends the Spring application configuration by enabling + * Spring Data GemFire/Geode's {@link GemfireBeanFactoryLocator} in order to auto-wire and configure any + * GemFire/Geode Objects declared in GemFire/Geode config (e.g. XML or properties). + * + * @author John Blum + * @see org.springframework.beans.factory.config.BeanPostProcessor + * @see org.springframework.context.annotation.Bean + * @see org.springframework.context.annotation.Configuration + * @see org.springframework.data.gemfire.CacheFactoryBean + * @see org.springframework.data.gemfire.config.annotation.EnableBeanFactoryLocator + * @see org.springframework.data.gemfire.support.GemfireBeanFactoryLocator + * @since 2.0.0 + */ +@Configuration +@SuppressWarnings("unused") +public class BeanFactoryLocatorConfiguration { + + /** + * Declares and registers a Spring {@link BeanPostProcessor} and post processes a Spring Data GemFire/Geode + * {@link CacheFactoryBean} by setting the {@literal useBeanFactoryLocator} property to {@literal true}. + * + * @return a Spring {@link BeanPostProcessor} used to post process the SDG {@link CacheFactoryBean}. + * @see org.springframework.beans.factory.config.BeanPostProcessor + */ + @Bean + public BeanPostProcessor cacheFactoryBeanPostProcessor() { + + return new BeanPostProcessor() { + + @Override + @SuppressWarnings("all") + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + + if (bean instanceof CacheFactoryBean) { + ((CacheFactoryBean) bean).setUseBeanFactoryLocator(true); + } + + return bean; + } + }; + } +} diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/EnableBeanFactoryLocator.java b/src/main/java/org/springframework/data/gemfire/config/annotation/EnableBeanFactoryLocator.java new file mode 100644 index 00000000..365b8fb8 --- /dev/null +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/EnableBeanFactoryLocator.java @@ -0,0 +1,53 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.data.gemfire.config.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.gemfire.support.GemfireBeanFactoryLocator; + +/** + * The {@link EnableBeanFactoryLocator} annotation annotates a Spring {@link Configuration @Configuration} class + * enabling SDG's {@link GemfireBeanFactoryLocator} in order to auto-wire and configure GemFire/Geode Objects + * declared in GemFire/Geode config. + * + * @author John Blum + * @see java.lang.annotation.Documented + * @see java.lang.annotation.Inherited + * @see java.lang.annotation.Retention + * @see java.lang.annotation.Target + * @see org.springframework.context.annotation.Configuration + * @see org.springframework.context.annotation.Import + * @see org.springframework.data.gemfire.support.GemfireBeanFactoryLocator + * @since 2.0.0 + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +@Documented +@Import(BeanFactoryLocatorConfiguration.class) +@SuppressWarnings("unused") +public @interface EnableBeanFactoryLocator { + +} diff --git a/src/test/java/org/springframework/data/gemfire/config/annotation/EnableBeanFactoryLocatorConfigurationIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/config/annotation/EnableBeanFactoryLocatorConfigurationIntegrationTests.java new file mode 100644 index 00000000..f8314560 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/config/annotation/EnableBeanFactoryLocatorConfigurationIntegrationTests.java @@ -0,0 +1,95 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.data.gemfire.config.annotation; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Optional; + +import org.junit.After; +import org.junit.Test; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.data.gemfire.CacheFactoryBean; +import org.springframework.data.gemfire.test.mock.annotation.EnableGemFireMocking; + +/** + * Integration test for {@link EnableBeanFactoryLocator} and {@link BeanFactoryLocatorConfiguration}. + * + * @author John Blum + * @see org.junit.Test + * @see org.springframework.context.ConfigurableApplicationContext + * @see org.springframework.data.gemfire.CacheFactoryBean + * @see org.springframework.data.gemfire.config.annotation.BeanFactoryLocatorConfiguration + * @see org.springframework.data.gemfire.config.annotation.EnableBeanFactoryLocator + * @see org.springframework.data.gemfire.test.mock.annotation.EnableGemFireMocking + * @since 2.0.0 + */ +public class EnableBeanFactoryLocatorConfigurationIntegrationTests { + + private ConfigurableApplicationContext applicationContext; + + @After + public void tearDown() { + Optional.ofNullable(this.applicationContext).ifPresent(ConfigurableApplicationContext::close); + } + + private ConfigurableApplicationContext newApplicationContext(Class... annotatedClasses) { + ConfigurableApplicationContext applicationContext = new AnnotationConfigApplicationContext(annotatedClasses); + applicationContext.registerShutdownHook(); + return applicationContext; + } + + @Test + public void gemfireBeanFactoryLocatorIsDisabled() { + + this.applicationContext = newApplicationContext(TestBeanFactoryLocatorDisabledConfiguration.class); + + assertThat(this.applicationContext).isNotNull(); + assertThat(this.applicationContext.containsBean("gemfireCache")).isTrue(); + + CacheFactoryBean gemfireCache = this.applicationContext.getBean("&gemfireCache", CacheFactoryBean.class); + + assertThat(gemfireCache).isNotNull(); + assertThat(gemfireCache.isUseBeanFactoryLocator()).isFalse(); + } + + @Test + public void gemfireBeanFactoryLocatorIsEnabled() { + + this.applicationContext = newApplicationContext(TestBeanFactoryLocatorEnabledConfiguration.class); + + assertThat(this.applicationContext).isNotNull(); + assertThat(this.applicationContext.containsBean("gemfireCache")).isTrue(); + + CacheFactoryBean gemfireCache = this.applicationContext.getBean("&gemfireCache", CacheFactoryBean.class); + + assertThat(gemfireCache).isNotNull(); + assertThat(gemfireCache.isUseBeanFactoryLocator()).isTrue(); + } + + @EnableGemFireMocking + @PeerCacheApplication + static class TestBeanFactoryLocatorDisabledConfiguration { + } + + @EnableGemFireMocking + @EnableBeanFactoryLocator + @PeerCacheApplication + static class TestBeanFactoryLocatorEnabledConfiguration { + } +}