You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by na...@apache.org on 2022/06/27 08:40:10 UTC

[ignite] branch master updated: IGNITE-17218 Added support of optional beans for SpringResource annotation injection. (#10106)

This is an automated email from the ASF dual-hosted git repository.

namelchev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 7ae58d7623d IGNITE-17218 Added support of optional beans for SpringResource annotation injection. (#10106)
7ae58d7623d is described below

commit 7ae58d7623d3f0b2d6787bc77e0373325aee00a5
Author: Mikhail Petrov <32...@users.noreply.github.com>
AuthorDate: Mon Jun 27 11:40:00 2022 +0300

    IGNITE-17218 Added support of optional beans for SpringResource annotation injection. (#10106)
---
 .../apache/ignite/resources/SpringResource.java    |  8 +++
 .../resource/GridResourceSpringBeanInjector.java   | 26 ++++++---
 .../GridSpringResourceInjectionSelfTest.java       | 67 ++++++++++++++++++++++
 .../processors/resource/spring-resource.xml        |  8 +++
 4 files changed, 100 insertions(+), 9 deletions(-)

diff --git a/modules/core/src/main/java/org/apache/ignite/resources/SpringResource.java b/modules/core/src/main/java/org/apache/ignite/resources/SpringResource.java
index d2b9f775c5d..53a02040f8f 100644
--- a/modules/core/src/main/java/org/apache/ignite/resources/SpringResource.java
+++ b/modules/core/src/main/java/org/apache/ignite/resources/SpringResource.java
@@ -122,6 +122,14 @@ public @interface SpringResource {
      */
     Class<?> resourceClass() default DEFAULT.class;
 
+    /**
+     * Determines whether the injection procedure should fail in case no beans with specified name or type are present
+     * in the Spring Context.
+     *
+     * @return Whether absence of the bean with specified parameters will result in {@code NoSuchBeanDefinitionException}.
+     */
+    boolean required() default true;
+
     /** Dummy class to compensate for impossibility of having default null value for annotation method. */
     final class DEFAULT {
         // No-op.
diff --git a/modules/spring/src/main/java/org/apache/ignite/internal/processors/resource/GridResourceSpringBeanInjector.java b/modules/spring/src/main/java/org/apache/ignite/internal/processors/resource/GridResourceSpringBeanInjector.java
index d4cb7f3660a..876e79fc093 100644
--- a/modules/spring/src/main/java/org/apache/ignite/internal/processors/resource/GridResourceSpringBeanInjector.java
+++ b/modules/spring/src/main/java/org/apache/ignite/internal/processors/resource/GridResourceSpringBeanInjector.java
@@ -23,6 +23,8 @@ import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.internal.managers.deployment.GridDeployment;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.resources.SpringResource;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
 import org.springframework.context.ApplicationContext;
 import org.springframework.util.StringUtils;
 
@@ -63,7 +65,8 @@ public class GridResourceSpringBeanInjector implements GridResourceInjector {
         if (springCtx != null) {
             Object bean = getBeanByResourceAnnotation(ann);
 
-            GridResourceUtils.inject(field.getField(), target, bean);
+            if (bean != null)
+                GridResourceUtils.inject(field.getField(), target, bean);
         }
     }
 
@@ -80,7 +83,8 @@ public class GridResourceSpringBeanInjector implements GridResourceInjector {
         if (springCtx != null) {
             Object bean = getBeanByResourceAnnotation(ann);
 
-            GridResourceUtils.inject(mtd.getMethod(), target, bean);
+            if (bean != null)
+                GridResourceUtils.inject(mtd.getMethod(), target, bean);
         }
     }
 
@@ -114,13 +118,17 @@ public class GridResourceSpringBeanInjector implements GridResourceInjector {
                 "but not both");
         }
 
-        Object bean;
-
-        if (!StringUtils.isEmpty(beanName))
-            bean = springCtx.getBean(beanName);
-        else
-            bean = springCtx.getBean(beanCls);
+        try {
+            return !StringUtils.isEmpty(beanName) ? springCtx.getBean(beanName) : springCtx.getBean(beanCls);
+        }
+        catch (NoUniqueBeanDefinitionException e) {
+            throw e;
+        }
+        catch (NoSuchBeanDefinitionException e) {
+            if (!annotation.required())
+                return null;
 
-        return bean;
+            throw e;
+        }
     }
 }
diff --git a/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/GridSpringResourceInjectionSelfTest.java b/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/GridSpringResourceInjectionSelfTest.java
index 42135bfdc12..0b9885d3fdd 100644
--- a/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/GridSpringResourceInjectionSelfTest.java
+++ b/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/GridSpringResourceInjectionSelfTest.java
@@ -282,6 +282,25 @@ public class GridSpringResourceInjectionSelfTest extends GridCommonAbstractTest
         }, grid, NoSuchBeanDefinitionException.class, "No bean named 'nonExistentResource' available");
     }
 
+    /** */
+    @Test
+    public void testClosureMethodWithNotRequiredWrongResourceName() {
+        grid.compute().call(new IgniteCallable<Object>() {
+            private AnotherDummyResourceBean dummyRsrcBean;
+
+            @SpringResource(resourceName = "nonExistentResource", required = false)
+            private void setDummyResourceBean(AnotherDummyResourceBean dummyRsrcBean) {
+                this.dummyRsrcBean = dummyRsrcBean;
+            }
+
+            @Override public Object call() {
+                assertNull(dummyRsrcBean);
+
+                return null;
+            }
+        });
+    }
+
     /**
      * Resource injection with non-existing resource class.
      */
@@ -304,6 +323,46 @@ public class GridSpringResourceInjectionSelfTest extends GridCommonAbstractTest
             ".GridSpringResourceInjectionSelfTest$AnotherDummyResourceBean' available");
     }
 
+
+    /** */
+    @Test
+    public void testClosureMethodWithDuplicatedResourceClass() {
+        assertError(new IgniteCallable<Object>() {
+            private DuplicatedResourceBean rsrcBean;
+
+            @SpringResource(resourceClass = DuplicatedResourceBean.class, required = false)
+            private void setDummyResourceBean(DuplicatedResourceBean rsrcBean) {
+                this.rsrcBean = rsrcBean;
+            }
+
+            @Override public Object call() {
+                fail();
+
+                return null;
+            }
+        }, grid, NoUniqueBeanDefinitionException.class, "No qualifying bean of type '" +
+            DuplicatedResourceBean.class.getName() + "' available: expected single matching bean but found 2");
+    }
+
+    /** */
+    @Test
+    public void testClosureMethodWithNotRequiredWrongResourceClass() {
+        grid.compute().call(new IgniteCallable<Object>() {
+            private AnotherDummyResourceBean dummyRsrcBean;
+
+            @SpringResource(resourceClass = AnotherDummyResourceBean.class, required = false)
+            private void setDummyResourceBean(AnotherDummyResourceBean dummyRsrcBean) {
+                this.dummyRsrcBean = dummyRsrcBean;
+            }
+
+            @Override public Object call() {
+                assertNull(dummyRsrcBean);
+
+                return null;
+            }
+        });
+    }
+
     /**
      * Resource injection with both resource and class set (ambiguity).
      */
@@ -377,4 +436,12 @@ public class GridSpringResourceInjectionSelfTest extends GridCommonAbstractTest
             // No-op.
         }
     }
+
+    /** Resource bean to test scenario with multiple beans of the same type in the Spring Context. */
+    private static class DuplicatedResourceBean {
+        /** */
+        public DuplicatedResourceBean() {
+            // No-op.
+        }
+    }
 }
diff --git a/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/spring-resource.xml b/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/spring-resource.xml
index 6baf1163bc1..31fb7f06288 100644
--- a/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/spring-resource.xml
+++ b/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/spring-resource.xml
@@ -24,4 +24,12 @@
     <bean id="dummyResourceBean"
           class="org.apache.ignite.internal.processors.resource.GridSpringResourceInjectionSelfTest$DummyResourceBean">
     </bean>
+
+    <bean id="firstDuplicatedTypeBean"
+          class="org.apache.ignite.internal.processors.resource.GridSpringResourceInjectionSelfTest$DuplicatedResourceBean">
+    </bean>
+
+    <bean id="secondDuplicatedTypeBean"
+          class="org.apache.ignite.internal.processors.resource.GridSpringResourceInjectionSelfTest$DuplicatedResourceBean">
+    </bean>
 </beans>