Add @CloudScan annotation that registers services and application instance info beans
This commit is contained in:
@@ -10,6 +10,7 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.cloud.Cloud;
|
||||
import org.springframework.cloud.CloudFactory;
|
||||
import org.springframework.cloud.app.ApplicationInstanceInfo;
|
||||
import org.springframework.cloud.config.java.ServiceScan;
|
||||
import org.springframework.cloud.service.GenericCloudServiceConnectorFactory;
|
||||
import org.springframework.cloud.service.ServiceInfo;
|
||||
@@ -21,7 +22,7 @@ import org.springframework.cloud.service.ServiceInfo;
|
||||
*
|
||||
* Usage:
|
||||
* Most applications should use either the Java config using {@link ServiceScan} annotation
|
||||
* or XML config using <cloud:service-scan/> that introduce a bean of this type lgically
|
||||
* or XML config using <cloud:service-scan/> that introduce a bean of this type logically
|
||||
* equivalent to:
|
||||
* <pre>
|
||||
* <bean class="org.cloudfoundry.runtime.service.CloudServicesScanner"/>
|
||||
@@ -44,9 +45,9 @@ import org.springframework.cloud.service.ServiceInfo;
|
||||
* @author Ramnivas Laddad
|
||||
*
|
||||
*/
|
||||
public class ServiceScanHelper {
|
||||
public class CloudScanHelper {
|
||||
private static final String CLOUD_FACTORY_BEAN_NAME = "__cloud_factory__";
|
||||
private static Logger logger = Logger.getLogger(ServiceScanHelper.class.getName());
|
||||
private static Logger logger = Logger.getLogger(CloudScanHelper.class.getName());
|
||||
|
||||
private Cloud cloud;
|
||||
|
||||
@@ -58,6 +59,17 @@ public class ServiceScanHelper {
|
||||
registerServiceBean(registry, serviceInfo);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerApplicationInstanceBean(BeanDefinitionRegistry registry) {
|
||||
initializeCloud(registry);
|
||||
|
||||
BeanDefinitionBuilder definitionBuilder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(ApplicationInstanceInfoWrapper.class);
|
||||
definitionBuilder.addConstructorArgValue(cloud);
|
||||
definitionBuilder.getRawBeanDefinition().setAttribute(
|
||||
"factoryBeanObjectType", ApplicationInstanceInfo.class);
|
||||
registry.registerBeanDefinition("spring.cloud.appplicationInstanceInfo", definitionBuilder.getBeanDefinition());
|
||||
}
|
||||
|
||||
private void initializeCloud(BeanDefinitionRegistry registry) {
|
||||
if (cloud != null) {
|
||||
@@ -113,5 +125,27 @@ public class ServiceScanHelper {
|
||||
}
|
||||
}
|
||||
|
||||
public static class ApplicationInstanceInfoWrapper implements FactoryBean<ApplicationInstanceInfo> {
|
||||
private Cloud cloud;
|
||||
|
||||
public ApplicationInstanceInfoWrapper(Cloud cloud) {
|
||||
this.cloud = cloud;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApplicationInstanceInfo getObject() throws Exception {
|
||||
return cloud.getApplicationInstanceInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return ApplicationInstanceInfo.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package org.springframework.cloud.config.java;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.cloud.app.ApplicationInstanceInfo;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* Add this annotation to an @{@link Configuration} class to have a bean for each
|
||||
* service bound to the app as well as one for {@link ApplicationInstanceInfo} added to
|
||||
* the application context.
|
||||
*
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* @CloudScan
|
||||
* public class CloudConfiguration {
|
||||
* // may (optionally) extend AbstractCloudConfiguration
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* This annotation is similar to @ComponentScan in Spring, which scans for classes
|
||||
* with the @Component classes and creates a bean for each. @CloudScan, in the same
|
||||
* spirit, scans services bound to the app and creates a bean for each. It also creates a bean
|
||||
* of {@link ApplicationInstanceInfo} class to expose information about the application instance.
|
||||
*
|
||||
* Upon service scanning, if there is a unique bean of for service type, you can inject it
|
||||
* using the following code (shows Redis, but the same scheme works for all services):
|
||||
* <pre>
|
||||
* @Autowired RedisConnectionFactory redisConnectionFactory;
|
||||
* </pre>
|
||||
*
|
||||
* If there are more than one services of a type, you can use the @Qualifier annotation
|
||||
* as in the following code:
|
||||
* <pre>
|
||||
* @Autowired @Qualifier("service-name1") RedisConnectionFactory redisConnectionFactory;
|
||||
* @Autowired @Qualifier("service-name2") RedisConnectionFactory redisConnectionFactory;
|
||||
* </pre>
|
||||
*
|
||||
* Similarly, application can have {@link ApplicationInstanceInfo} injected as follows:
|
||||
* <pre>
|
||||
* @Autowired ApplicationInstanceInfo applicationInstanceInfo;
|
||||
* </pre>
|
||||
*
|
||||
* Note the difference between @{@link ServiceScan} and this annotation. While the former only
|
||||
* adds beans for each bound service, the @{@link CloudScan} annotation also adds a
|
||||
* bean for {@link ApplicationInstanceInfo}.
|
||||
*
|
||||
* @see ServiceScan
|
||||
* @author Ramnivas Laddad
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Documented
|
||||
@Import(CloudScanConfiguration.class)
|
||||
public @interface CloudScan {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.springframework.cloud.config.java;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.cloud.app.ApplicationInstanceInfo;
|
||||
import org.springframework.cloud.config.CloudScanHelper;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
|
||||
/**
|
||||
* Introduces beans for each bound service and one for {@link ApplicationInstanceInfo}
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
* @see CloudScan
|
||||
*/
|
||||
@Configuration
|
||||
public class CloudScanConfiguration extends ServiceScanConfiguration {
|
||||
private CloudScanHelper helper = new CloudScanHelper();
|
||||
|
||||
@Override
|
||||
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) throws BeansException {
|
||||
super.registerBeanDefinitions(importingClassMetadata, registry);
|
||||
helper.registerApplicationInstanceBean(registry);
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package org.springframework.cloud.config.java;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.cloud.config.ServiceScanHelper;
|
||||
import org.springframework.cloud.config.CloudScanHelper;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
@@ -15,7 +15,7 @@ import org.springframework.core.type.AnnotationMetadata;
|
||||
*/
|
||||
@Configuration
|
||||
public class ServiceScanConfiguration implements ImportBeanDefinitionRegistrar {
|
||||
private ServiceScanHelper helper = new ServiceScanHelper();
|
||||
private CloudScanHelper helper = new CloudScanHelper();
|
||||
|
||||
@Override
|
||||
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) throws BeansException {
|
||||
|
||||
@@ -6,7 +6,7 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
|
||||
import org.springframework.cloud.config.ServiceScanHelper;
|
||||
import org.springframework.cloud.config.CloudScanHelper;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
@@ -47,7 +47,7 @@ public class CloudNamespaceHandler extends NamespaceHandlerSupport {
|
||||
}
|
||||
|
||||
public static class ServiceScanBeanFactoryProcessor implements BeanFactoryPostProcessor {
|
||||
private ServiceScanHelper helper = new ServiceScanHelper();
|
||||
private CloudScanHelper helper = new CloudScanHelper();
|
||||
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.springframework.cloud.config.java;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.cloud.app.ApplicationInstanceInfo;
|
||||
import org.springframework.cloud.config.AbstractCloudConfigServiceScanTest;
|
||||
import org.springframework.cloud.service.ServiceInfo;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Test for the {@link CloudScan} annotation
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
*
|
||||
*/
|
||||
public class CloudScanJavaConfigTest extends AbstractCloudConfigServiceScanTest {
|
||||
protected ApplicationContext getTestApplicationContext(ServiceInfo... serviceInfos) {
|
||||
return getTestApplicationContext(CloudScanJavaConfigTestConfig.class, serviceInfos);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cloudScanIntroducesApplicationInstanceInfo() {
|
||||
ApplicationContext testContext = getTestApplicationContext();
|
||||
|
||||
assertNotNull(testContext.getBean(ApplicationInstanceInfo.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@CloudScan
|
||||
class CloudScanJavaConfigTestConfig {
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user