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>