[ 
https://issues.apache.org/jira/browse/WICKET-7170?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18041082#comment-18041082
 ] 

ASF GitHub Bot commented on WICKET-7170:
----------------------------------------

martin-g commented on code in PR #1311:
URL: https://github.com/apache/wicket/pull/1311#discussion_r2568681861


##########
wicket-spring/src/main/java/org/apache/wicket/spring/injection/annot/AnnotProxyFieldValueFactory.java:
##########
@@ -249,36 +251,21 @@ private String getBeanNameOfClass(final 
ApplicationContext ctx, final Class<?> c
 
                if (names.size() > 1)
                {
-                       if (ctx instanceof AbstractApplicationContext)
-                       {
-                               List<String> primaries = new ArrayList<>();
-                               for (String name : names)
-                               {
-                                       BeanDefinition beanDef = 
getBeanDefinition(
-                                               
((AbstractApplicationContext)ctx).getBeanFactory(), name);
-                                       if (beanDef instanceof 
AbstractBeanDefinition)
-                                       {
-                                               if (beanDef.isPrimary())
-                                               {
-                                                       primaries.add(name);
-                                               }
-                                       }
-                               }
-                               if (primaries.size() == 1)
-                               {
-                                       return primaries.get(0);
-                               }
-                       }
-                       
-                       //use field name to find a match
-                       int nameIndex = names.indexOf(fieldName);
-                       
-                       if (nameIndex > -1)
-                       {
-                               return names.get(nameIndex);
+                       // Check, if we can reduce the set of beannames to 
exactly one beanname probing the following criterias:
+                       // 1. Ist there exactly one bean marked as primary?

Review Comment:
   ```suggestion
                        // 1. Is there exactly one bean marked as primary?
   ```



##########
wicket-spring/src/main/java/org/apache/wicket/spring/injection/annot/AnnotProxyFieldValueFactory.java:
##########
@@ -295,6 +282,36 @@ else if(!names.isEmpty())
                return null;
        }
 
+       private String detectPrimaryBeanName(final ApplicationContext ctx, 
final List<String> beanNames) {

Review Comment:
   ```suggestion
        private String detectPrimaryBeanName(final ApplicationContext ctx, 
final List<String> beanNames)
        {
   ```



##########
wicket-spring/src/main/java/org/apache/wicket/spring/injection/annot/AnnotProxyFieldValueFactory.java:
##########
@@ -249,36 +251,21 @@ private String getBeanNameOfClass(final 
ApplicationContext ctx, final Class<?> c
 
                if (names.size() > 1)
                {
-                       if (ctx instanceof AbstractApplicationContext)
-                       {
-                               List<String> primaries = new ArrayList<>();
-                               for (String name : names)
-                               {
-                                       BeanDefinition beanDef = 
getBeanDefinition(
-                                               
((AbstractApplicationContext)ctx).getBeanFactory(), name);
-                                       if (beanDef instanceof 
AbstractBeanDefinition)
-                                       {
-                                               if (beanDef.isPrimary())
-                                               {
-                                                       primaries.add(name);
-                                               }
-                                       }
-                               }
-                               if (primaries.size() == 1)
-                               {
-                                       return primaries.get(0);
-                               }
-                       }
-                       
-                       //use field name to find a match
-                       int nameIndex = names.indexOf(fieldName);
-                       
-                       if (nameIndex > -1)
-                       {
-                               return names.get(nameIndex);
+                       // Check, if we can reduce the set of beannames to 
exactly one beanname probing the following criterias:
+                       // 1. Ist there exactly one bean marked as primary?
+                       // 2. Is there a bean with the same name as the field?
+                       // 3. Is there exactly one bean marked as default 
candidate?
+                       final String exactMatchBeanName = 
Optional.ofNullable(detectPrimaryBeanName(ctx, names))
+                         .or(() -> 
Optional.ofNullable(detectBeanNameByFieldname(fieldName, names)))

Review Comment:
   ```suggestion
                          .or(() -> 
Optional.ofNullable(detectBeanNameByFieldName(fieldName, names)))
   ```



##########
wicket-spring/src/main/java/org/apache/wicket/spring/injection/annot/AnnotProxyFieldValueFactory.java:
##########
@@ -295,6 +282,36 @@ else if(!names.isEmpty())
                return null;
        }
 
+       private String detectPrimaryBeanName(final ApplicationContext ctx, 
final List<String> beanNames) {
+               return detectBeanName(ctx, beanNames, 
AbstractBeanDefinition::isPrimary);
+       }
+
+       private String detectDefaultCandidateBeanName(final ApplicationContext 
ctx, final List<String> beanNames) {
+               return detectBeanName(ctx, beanNames, 
AbstractBeanDefinition::isDefaultCandidate);
+       }
+
+       private String detectBeanName(final ApplicationContext ctx, final 
List<String> beanNames, final Predicate<AbstractBeanDefinition> predicate) {
+               final List<String> found = new ArrayList<>();
+               if (ctx instanceof AbstractApplicationContext 
abstractApplicationContext)
+               {
+                       final ConfigurableListableBeanFactory beanFactory = 
abstractApplicationContext.getBeanFactory();
+                       for (final String beanName : beanNames)
+                       {
+                               final BeanDefinition beanDefinition = 
getBeanDefinition(beanFactory, beanName);
+                               if (beanDefinition instanceof 
AbstractBeanDefinition abstractBeanDefinition && 
predicate.test(abstractBeanDefinition))
+                               {
+                                       found.add(beanName);
+                               }
+                       }
+               }
+               return found.size() == 1 ? found.get(0) : null;
+       }
+
+       private String detectBeanNameByFieldname(final String fieldName, final 
List<String> beanNames) {

Review Comment:
   ```suggestion
        private String detectBeanNameByFieldName(final String fieldName, final 
List<String> beanNames) 
        {
   ```



##########
wicket-spring/src/main/java/org/apache/wicket/spring/injection/annot/AnnotProxyFieldValueFactory.java:
##########
@@ -249,36 +251,21 @@ private String getBeanNameOfClass(final 
ApplicationContext ctx, final Class<?> c
 
                if (names.size() > 1)
                {
-                       if (ctx instanceof AbstractApplicationContext)
-                       {
-                               List<String> primaries = new ArrayList<>();
-                               for (String name : names)
-                               {
-                                       BeanDefinition beanDef = 
getBeanDefinition(
-                                               
((AbstractApplicationContext)ctx).getBeanFactory(), name);
-                                       if (beanDef instanceof 
AbstractBeanDefinition)
-                                       {
-                                               if (beanDef.isPrimary())
-                                               {
-                                                       primaries.add(name);
-                                               }
-                                       }
-                               }
-                               if (primaries.size() == 1)
-                               {
-                                       return primaries.get(0);
-                               }
-                       }
-                       
-                       //use field name to find a match
-                       int nameIndex = names.indexOf(fieldName);
-                       
-                       if (nameIndex > -1)
-                       {
-                               return names.get(nameIndex);
+                       // Check, if we can reduce the set of beannames to 
exactly one beanname probing the following criterias:
+                       // 1. Ist there exactly one bean marked as primary?
+                       // 2. Is there a bean with the same name as the field?
+                       // 3. Is there exactly one bean marked as default 
candidate?
+                       final String exactMatchBeanName = 
Optional.ofNullable(detectPrimaryBeanName(ctx, names))
+                         .or(() -> 
Optional.ofNullable(detectBeanNameByFieldname(fieldName, names)))
+                         .orElseGet(() -> detectDefaultCandidateBeanName(ctx, 
names));
+
+                       // If so: take that beanname
+                       if (exactMatchBeanName != null) {

Review Comment:
   ```suggestion
                        if (exactMatchBeanName != null)
                        {
   ```



##########
wicket-spring/src/test/java/org/apache/wicket/spring/injection/annot/AnnotProxyFieldValueFactoryDefaultCandidateTest.java:
##########
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.wicket.spring.injection.annot;
+
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+
+import java.lang.reflect.Field;
+import java.util.stream.Stream;
+
+import org.apache.wicket.proxy.ILazyInitProxy;
+import org.apache.wicket.proxy.IProxyTargetLocator;
+import org.apache.wicket.spring.test.ApplicationContextMock;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+
+import jakarta.inject.Inject;
+import jakarta.inject.Named;

Review Comment:
   ```suggestion
   ```



##########
wicket-spring/src/main/java/org/apache/wicket/spring/injection/annot/AnnotProxyFieldValueFactory.java:
##########
@@ -295,6 +282,36 @@ else if(!names.isEmpty())
                return null;
        }
 
+       private String detectPrimaryBeanName(final ApplicationContext ctx, 
final List<String> beanNames) {
+               return detectBeanName(ctx, beanNames, 
AbstractBeanDefinition::isPrimary);
+       }
+
+       private String detectDefaultCandidateBeanName(final ApplicationContext 
ctx, final List<String> beanNames) {
+               return detectBeanName(ctx, beanNames, 
AbstractBeanDefinition::isDefaultCandidate);
+       }
+
+       private String detectBeanName(final ApplicationContext ctx, final 
List<String> beanNames, final Predicate<AbstractBeanDefinition> predicate) {

Review Comment:
   ```suggestion
        private String detectBeanName(final ApplicationContext ctx, final 
List<String> beanNames, final Predicate<AbstractBeanDefinition> predicate)
        {
   ```



##########
wicket-spring/src/main/java/org/apache/wicket/spring/injection/annot/AnnotProxyFieldValueFactory.java:
##########
@@ -295,6 +282,36 @@ else if(!names.isEmpty())
                return null;
        }
 
+       private String detectPrimaryBeanName(final ApplicationContext ctx, 
final List<String> beanNames) {
+               return detectBeanName(ctx, beanNames, 
AbstractBeanDefinition::isPrimary);
+       }
+
+       private String detectDefaultCandidateBeanName(final ApplicationContext 
ctx, final List<String> beanNames) {

Review Comment:
   ```suggestion
        private String detectDefaultCandidateBeanName(final ApplicationContext 
ctx, final List<String> beanNames)
        {
   ```



##########
wicket-spring/src/test/java/org/apache/wicket/spring/injection/annot/AnnotProxyFieldValueFactoryDefaultCandidateTest.java:
##########
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.wicket.spring.injection.annot;
+
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNull;

Review Comment:
   ```suggestion
   ```





> SpringInjector / AnnotProxyFieldValueFactory does not consider 
> defaultCandidate
> -------------------------------------------------------------------------------
>
>                 Key: WICKET-7170
>                 URL: https://issues.apache.org/jira/browse/WICKET-7170
>             Project: Wicket
>          Issue Type: Bug
>          Components: wicket-spring
>    Affects Versions: 10.7.0
>            Reporter: Hans Schäfer
>            Priority: Major
>
> Spring considers the defaultCandidate-Flag, supplementary to the 
> autowireCandidate-Flag. This ist currently not supported by SpringInjector / 
> AnnotProxyFieldValueFactory.
> Assume 2 Beans of the same Class / Type: one is autowiredCandidate=true / 
> defaultCandidate=true, the second is autowireCandidate=true but 
> defaultCandidate = false.
> Spring always chosses the first one for autowiring, if no explicit beanName 
> is given.
> Wicket complains about 2 beans of same type.
> Spring had a similar issue when creating proxies for beans with 
> defaultCandidate = false:
> [https://github.com/spring-projects/spring-framework/issues/35626]
> There is a Pull Request that fixes this issue: 
> [https://github.com/apache/wicket/pull/1310]
>  



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to