From 79bfd720a3462ef8e9266c7888f620d5be607848 Mon Sep 17 00:00:00 2001 From: Vladimir Orany Date: Mon, 8 Oct 2018 14:49:02 +0200 Subject: [PATCH] mn qualifier for spring bean no longer ignored --- build.gradle | 2 +- .../grails/GrailsMicronautBeanFactory.java | 89 +++++++++++++++++++ .../grails/GrailsMicronautBeanProcessor.java | 4 +- .../GrailsMicronautBeanProcessorSpec.groovy | 39 +++++++- 4 files changed, 131 insertions(+), 3 deletions(-) create mode 100644 micronaut-grails/src/main/groovy/com/agorapulse/micronaut/grails/GrailsMicronautBeanFactory.java diff --git a/build.gradle b/build.gradle index 1912c1baa..0e4acd7cf 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ allprojects { group 'com.agorapulse' - version "${micronautVersion}.4" + version "${micronautVersion}.5" repositories { jcenter() diff --git a/micronaut-grails/src/main/groovy/com/agorapulse/micronaut/grails/GrailsMicronautBeanFactory.java b/micronaut-grails/src/main/groovy/com/agorapulse/micronaut/grails/GrailsMicronautBeanFactory.java new file mode 100644 index 000000000..63daf099c --- /dev/null +++ b/micronaut-grails/src/main/groovy/com/agorapulse/micronaut/grails/GrailsMicronautBeanFactory.java @@ -0,0 +1,89 @@ +/* + * Copyright 2017-2018 original 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 com.agorapulse.micronaut.grails; + +import io.micronaut.context.DefaultApplicationContext; +import io.micronaut.context.Qualifier; +import io.micronaut.context.exceptions.BeanInstantiationException; +import org.springframework.beans.factory.FactoryBean; + +import java.util.Optional; + +/** + * A spring FactoryBean for adding Micronaut beans to a + * Spring application context. + * + * @author jeffbrown + * @author musketyr + * @since 1.0 + */ +class GrailsMicronautBeanFactory implements FactoryBean { + + private Class micronautBeanType; + private DefaultApplicationContext micronautContext; + private Qualifier micronautQualifier; + private boolean isMicronautSingleton; + + /** + * @param micronautBeanType The type of bean this factory will create + */ + public void setMicronautBeanType(Class micronautBeanType) { + this.micronautBeanType = micronautBeanType; + } + + /** + * @param micronautContext The Micronaut application context + */ + public void setMicronautContext(DefaultApplicationContext micronautContext) { + this.micronautContext = micronautContext; + } + + /** + * + * @param isMicronautSingleton indicates if the Micronaut bean is a singleton + */ + public void setMicronautSingleton(boolean isMicronautSingleton) { + this.isMicronautSingleton = isMicronautSingleton; + } + + /** + * @param micronautQualifier micronaut qualifier of the bean + */ + public void setMicronautQualifier(Qualifier micronautQualifier) { + this.micronautQualifier = micronautQualifier; + } + + @Override + public Object getObject() throws Exception { + Optional bean = micronautContext.findBean(micronautBeanType, micronautQualifier); + if (bean.isPresent()) { + return bean.get(); + } + + throw new BeanInstantiationException("Could Not Create Bean [" + micronautBeanType + "]"); + } + + @Override + public Class getObjectType() { + return micronautBeanType; + } + + @Override + public boolean isSingleton() { + return isMicronautSingleton; + } +} diff --git a/micronaut-grails/src/main/groovy/com/agorapulse/micronaut/grails/GrailsMicronautBeanProcessor.java b/micronaut-grails/src/main/groovy/com/agorapulse/micronaut/grails/GrailsMicronautBeanProcessor.java index cb5faee4e..842694272 100644 --- a/micronaut-grails/src/main/groovy/com/agorapulse/micronaut/grails/GrailsMicronautBeanProcessor.java +++ b/micronaut-grails/src/main/groovy/com/agorapulse/micronaut/grails/GrailsMicronautBeanProcessor.java @@ -118,6 +118,7 @@ public static GrailsMicronautBeanProcessor.Builder builder(PropertyTranslatingCu private static final String MICRONAUT_BEAN_TYPE_PROPERTY_NAME = "micronautBeanType"; private static final String MICRONAUT_CONTEXT_PROPERTY_NAME = "micronautContext"; + private static final String MICRONAUT_QUALIFIER_PROPERTY_NAME = "micronautQualifier"; private static final String MICRONAUT_SINGLETON_PROPERTY_NAME = "micronautSingleton"; private DefaultBeanContext micronautContext; @@ -158,8 +159,9 @@ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) BeanDefinition definition = firstBean.orElseThrow(()-> new IllegalArgumentException("There is no candidate for " + micronautBeanQualifier)); final BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder - .rootBeanDefinition("io.micronaut.spring.beans.MicronautSpringBeanFactory"); + .rootBeanDefinition(GrailsMicronautBeanFactory.class); beanDefinitionBuilder.addPropertyValue(MICRONAUT_BEAN_TYPE_PROPERTY_NAME, definition.getBeanType()); + beanDefinitionBuilder.addPropertyValue(MICRONAUT_QUALIFIER_PROPERTY_NAME, micronautBeanQualifier); beanDefinitionBuilder.addPropertyValue(MICRONAUT_CONTEXT_PROPERTY_NAME, micronautContext); beanDefinitionBuilder.addPropertyValue(MICRONAUT_SINGLETON_PROPERTY_NAME, definition.isSingleton()); diff --git a/micronaut-grails/src/test/groovy/com/agorapulse/micronaut/grails/GrailsMicronautBeanProcessorSpec.groovy b/micronaut-grails/src/test/groovy/com/agorapulse/micronaut/grails/GrailsMicronautBeanProcessorSpec.groovy index 02f26e793..94e81c1e1 100644 --- a/micronaut-grails/src/test/groovy/com/agorapulse/micronaut/grails/GrailsMicronautBeanProcessorSpec.groovy +++ b/micronaut-grails/src/test/groovy/com/agorapulse/micronaut/grails/GrailsMicronautBeanProcessorSpec.groovy @@ -1,6 +1,7 @@ package com.agorapulse.micronaut.grails import com.agorapulse.remember.Remember +import io.micronaut.context.annotation.Factory import io.micronaut.context.annotation.Primary import io.micronaut.context.annotation.Prototype import io.micronaut.context.annotation.Requires @@ -42,6 +43,13 @@ class GrailsMicronautBeanProcessorSpec extends Specification { applicationContext.getBean('someInterface') instanceof SomeInterface applicationContext.getBean('someInterface') instanceof SomeImplementation applicationContext.getBean('gadget') instanceof SomeGadget + + applicationContext.getBean('two') instanceof SomeNamed + applicationContext.getBean('one') instanceof SomeNamed + + applicationContext.getBean('one').name == 'one' + applicationContext.getBean('two').name == 'two' + // see https://github.com/micronaut-projects/micronaut-core/issues/679 // applicationContext.getBean('otherMinion') instanceof OtherMinion when: @@ -79,6 +87,8 @@ class GrailsConfig { .addByType('someInterface', SomeInterface) .addByStereotype('prototype', Prototype) .addByName('gadget') + .addByName('one') + .addByName('two') // see https://github.com/micronaut-projects/micronaut-core/issues/679 // .addByQualifiers('otherMinion', Qualifiers.byName('other'), Qualifiers.byType(Minion)) .build() @@ -89,7 +99,34 @@ class GrailsConfig { interface SomeInterface { } @Singleton -class SomeImplementation implements SomeInterface { } +class SomeImplementation implements SomeInterface {} + +class SomeNamed { + final String name + + SomeNamed(String name) { + this.name = name + } +} + +@Factory +class SomeNamedFactory { + + @io.micronaut.context.annotation.Bean + @Singleton + @Named('one') + SomeNamed one() { + return new SomeNamed('one') + } + + @io.micronaut.context.annotation.Bean + @Singleton + @Named('two') + SomeNamed two() { + return new SomeNamed('two') + } + +} @Primary @Singleton