You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by jd...@apache.org on 2010/02/13 17:31:14 UTC

svn commit: r909844 - /wicket/trunk/wicket-spring/src/main/java/org/apache/wicket/spring/injection/annot/AnnotProxyFieldValueFactory.java

Author: jdonnerstag
Date: Sat Feb 13 16:31:14 2010
New Revision: 909844

URL: http://svn.apache.org/viewvc?rev=909844&view=rev
Log:
WICKET-2737 fixed reduce number of SpringBeanLocator#getBeanNameOfClass calls.

Modified:
    wicket/trunk/wicket-spring/src/main/java/org/apache/wicket/spring/injection/annot/AnnotProxyFieldValueFactory.java

Modified: wicket/trunk/wicket-spring/src/main/java/org/apache/wicket/spring/injection/annot/AnnotProxyFieldValueFactory.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-spring/src/main/java/org/apache/wicket/spring/injection/annot/AnnotProxyFieldValueFactory.java?rev=909844&r1=909843&r2=909844&view=diff
==============================================================================
--- wicket/trunk/wicket-spring/src/main/java/org/apache/wicket/spring/injection/annot/AnnotProxyFieldValueFactory.java (original)
+++ wicket/trunk/wicket-spring/src/main/java/org/apache/wicket/spring/injection/annot/AnnotProxyFieldValueFactory.java Sat Feb 13 16:31:14 2010
@@ -17,12 +17,20 @@
 package org.apache.wicket.spring.injection.annot;
 
 import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
 import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.wicket.injection.IFieldValueFactory;
 import org.apache.wicket.proxy.LazyInitProxyFactory;
 import org.apache.wicket.spring.ISpringContextLocator;
 import org.apache.wicket.spring.SpringBeanLocator;
+import org.apache.wicket.util.lang.Generics;
+import org.apache.wicket.util.string.Strings;
+import org.springframework.beans.factory.BeanFactoryUtils;
+import org.springframework.context.ApplicationContext;
 
 /**
  * {@link IFieldValueFactory} that uses {@link LazyInitProxyFactory} to create proxies for Spring
@@ -60,7 +68,11 @@
 {
 	private final ISpringContextLocator contextLocator;
 
-	private final ConcurrentHashMap<SpringBeanLocator, Object> cache = new ConcurrentHashMap<SpringBeanLocator, Object>();
+	private final ConcurrentHashMap<SpringBeanLocator, Object> cache = Generics
+			.newConcurrentHashMap();
+
+	private final ConcurrentHashMap<Class< ? >, String> beanNameCache = Generics
+			.newConcurrentHashMap();
 
 	private final boolean wrapInProxies;
 
@@ -98,8 +110,7 @@
 	{
 		if (field.isAnnotationPresent(SpringBean.class))
 		{
-			SpringBean annot = field.getAnnotation(SpringBean.class);
-			SpringBeanLocator locator = new SpringBeanLocator(annot.name(), field.getType(),
+			SpringBeanLocator locator = new SpringBeanLocator(getBeanName(field), field.getType(),
 					contextLocator);
 
 			// only check the cache if the bean is a singleton
@@ -130,6 +141,78 @@
 	}
 
 	/**
+	 * 
+	 * @param field
+	 * @return bean name
+	 */
+	private String getBeanName(final Field field)
+	{
+		SpringBean annot = field.getAnnotation(SpringBean.class);
+
+		String name = annot.name();
+		if (Strings.isEmpty(name))
+		{
+			name = beanNameCache.get(field.getType());
+			if (name == null)
+			{
+				name = getBeanNameOfClass(contextLocator.getSpringContext(), field.getType());
+				beanNameCache.put(field.getType(), name);
+			}
+		}
+		return name;
+	}
+
+	/**
+	 * Returns the name of the Bean as registered to Spring. Throws IllegalState exception if none
+	 * or more than one beans are found.
+	 * 
+	 * @param ctx
+	 *            spring application context
+	 * @param clazz
+	 *            bean class
+	 * @throws IllegalStateException
+	 * @return spring name of the bean
+	 */
+	private final String getBeanNameOfClass(ApplicationContext ctx, Class< ? > clazz)
+	{
+		// get the list of all possible matching beans
+		List<String> names = new ArrayList<String>(Arrays.asList(BeanFactoryUtils
+				.beanNamesForTypeIncludingAncestors(ctx, clazz)));
+
+		// filter out beans that are not condidates for autowiring
+		Iterator<String> it = names.iterator();
+		while (it.hasNext())
+		{
+			final String possibility = it.next();
+			if (BeanFactoryUtils.isFactoryDereference(possibility) ||
+					possibility.startsWith("scopedTarget."))
+			{
+				it.remove();
+			}
+		}
+
+		if (names.isEmpty())
+		{
+			throw new IllegalStateException("bean of type [" + clazz.getName() + "] not found");
+		}
+		else if (names.size() > 1)
+		{
+			StringBuilder msg = new StringBuilder();
+			msg.append("more then one bean of type [");
+			msg.append(clazz.getName());
+			msg.append("] found, you have to specify the name of the bean ");
+			msg.append("(@SpringBean(name=\"foo\")) in order to resolve this conflict. ");
+			msg.append("Matched beans: ");
+			msg.append(Strings.join(",", names.toArray(new String[0])));
+			throw new IllegalStateException(msg.toString());
+		}
+		else
+		{
+			return names.get(0);
+		}
+	}
+
+	/**
 	 * @see org.apache.wicket.injection.IFieldValueFactory#supportsField(java.lang.reflect.Field)
 	 */
 	public boolean supportsField(Field field)