From a800aa0ecc5afd5e8813e79aea7ca1cddd48cce6 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Tue, 30 Aug 2016 11:53:32 +0200 Subject: [PATCH] #18 - Explicitly declare bean definitions target type for plugin registries. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 and PluginRegistry without using explicit qualifiers. --- ...uginRegistriesBeanDefinitionRegistrar.java | 37 +++++++++++++++---- ...EnablePluginRegistriesIntegrationTest.java | 10 ++--- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/org/springframework/plugin/core/config/PluginRegistriesBeanDefinitionRegistrar.java b/core/src/main/java/org/springframework/plugin/core/config/PluginRegistriesBeanDefinitionRegistrar.java index 419f698..20256bf 100644 --- a/core/src/main/java/org/springframework/plugin/core/config/PluginRegistriesBeanDefinitionRegistrar.java +++ b/core/src/main/java/org/springframework/plugin/core/config/PluginRegistriesBeanDefinitionRegistrar.java @@ -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); + } } diff --git a/core/src/test/java/org/springframework/plugin/core/config/EnablePluginRegistriesIntegrationTest.java b/core/src/test/java/org/springframework/plugin/core/config/EnablePluginRegistriesIntegrationTest.java index 63f69b3..8160b55 100644 --- a/core/src/test/java/org/springframework/plugin/core/config/EnablePluginRegistriesIntegrationTest.java +++ b/core/src/test/java/org/springframework/plugin/core/config/EnablePluginRegistriesIntegrationTest.java @@ -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 registry; + @Autowired PluginRegistry registry; @Test public void registersPluginRegistries() { @@ -60,9 +58,7 @@ public class EnablePluginRegistriesIntegrationTest { } @Qualifier("myQualifier") - interface AnotherPlugin extends Plugin { - - } + interface AnotherPlugin extends Plugin {} static class AnotherSamplePluginImplementation implements AnotherPlugin {