#18 - Explicitly declare bean definitions target type for plugin registries.

We now use the API introduced in Spring Framework 4.3.3 to explicitly declare a ResolvableType for the BeanDefinition of the plugin registries. This allows to autowire registries as PluginRegisty<Foo, …> and PluginRegistry<Bar, …> without using explicit qualifiers.
This commit is contained in:
Oliver Gierke
2016-08-30 11:53:32 +02:00
parent 1feb021ee3
commit a800aa0ecc
2 changed files with 33 additions and 14 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012 the original author or authors.
* Copyright 2012-2016 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.
@@ -16,13 +16,18 @@
package org.springframework.plugin.core.config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.AutowireCandidateQualifier;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.ResolvableType;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.plugin.core.OrderAwarePluginRegistry;
import org.springframework.plugin.core.Plugin;
import org.springframework.plugin.core.PluginRegistry;
import org.springframework.plugin.core.support.PluginRegistryFactoryBean;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
@@ -41,15 +46,17 @@ public class PluginRegistriesBeanDefinitionRegistrar implements ImportBeanDefini
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
Class<?>[] types = (Class<?>[]) importingClassMetadata.getAnnotationAttributes(
EnablePluginRegistries.class.getName()).get("value");
Class<?>[] types = (Class<?>[]) importingClassMetadata
.getAnnotationAttributes(EnablePluginRegistries.class.getName()).get("value");
for (Class<?> type : types) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(PluginRegistryFactoryBean.class);
builder.addPropertyValue("type", type);
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
RootBeanDefinition beanDefinition = (RootBeanDefinition) builder.getBeanDefinition();
beanDefinition.setTargetType(getTargetType(type));
Qualifier annotation = type.getAnnotation(Qualifier.class);
// If the plugin interface has a Qualifier annotation, propagate that to the bean definition of the registry
@@ -60,9 +67,25 @@ public class PluginRegistriesBeanDefinitionRegistrar implements ImportBeanDefini
}
// Default
String beanName = annotation == null ? StringUtils.uncapitalize(type.getSimpleName() + "Registry") : annotation
.value();
String beanName = annotation == null ? StringUtils.uncapitalize(type.getSimpleName() + "Registry")
: annotation.value();
registry.registerBeanDefinition(beanName, builder.getBeanDefinition());
}
}
/**
* Returns the target type of the {@link PluginRegistry} for the given plugin type.
*
* @param pluginType must not be {@literal null}.
* @return
*/
private static ResolvableType getTargetType(Class<?> pluginClass) {
Assert.notNull(pluginClass, "Plugin type must not be null!");
ResolvableType delimiterType = ResolvableType.forClass(Plugin.class, pluginClass).getGeneric(0);
ResolvableType pluginType = ResolvableType.forClass(pluginClass);
return ResolvableType.forClassWithGenerics(OrderAwarePluginRegistry.class, pluginType, delimiterType);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012 the original author or authors.
* Copyright 2012-2016 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.
@@ -50,9 +50,7 @@ public class EnablePluginRegistriesIntegrationTest {
}
}
@Autowired
@Qualifier("samplePluginRegistry")
PluginRegistry<SamplePlugin, String> registry;
@Autowired PluginRegistry<SamplePlugin, String> registry;
@Test
public void registersPluginRegistries() {
@@ -60,9 +58,7 @@ public class EnablePluginRegistriesIntegrationTest {
}
@Qualifier("myQualifier")
interface AnotherPlugin extends Plugin<String> {
}
interface AnotherPlugin extends Plugin<String> {}
static class AnotherSamplePluginImplementation implements AnotherPlugin {