diff --git a/spring-beans/src/main/java/org/springframework/beans/BeanInfoFactory.java b/spring-beans/src/main/java/org/springframework/beans/BeanInfoFactory.java
index 2aefdc240d..fe26c29d85 100644
--- a/spring-beans/src/main/java/org/springframework/beans/BeanInfoFactory.java
+++ b/spring-beans/src/main/java/org/springframework/beans/BeanInfoFactory.java
@@ -23,17 +23,18 @@ import java.beans.IntrospectionException;
* Strategy for creating {@link BeanInfo} instances.
*
*
BeanInfoFactories are are instantiated by the {@link CachedIntrospectionResults},
- * which looks for {@code META-INF/spring.beanInfoFactories} files on the class path.
- * These files contain one or more {@code BeanInfoFactory} class names, each of a single
- * line. When a {@link BeanInfo} is to be created, the {@code CachedIntrospectionResults}
- * will iterate through the discovered factories, asking each one if it {@linkplain
- * #supports(Class) supports} the given bean class. If it does, {@link
- * #getBeanInfo(Class)} will be called; if not, the next factory will be queried. If none
- * of the factories support the class, an standard {@link BeanInfo} is created as a
- * default.
+ * by using the {@link org.springframework.core.io.support.SpringFactoriesLoader} utility
+ * class.
*
- *
Note that the {@link CachedIntrospectionResults} sorts the {@code BeanInfoFactory}
- * instances by {@link org.springframework.core.annotation.Order Order}, so that ones with
+ * When a {@link BeanInfo} is to be created, the {@code CachedIntrospectionResults}
+ * will iterate through the discovered factories, calling {@link
+ * #getBeanInfo(Class)} on each one. If {@code null} is returned, the next factory will
+ * be queried. If none of the factories support the class, an standard {@link BeanInfo}
+ * is created as a default.
+ *
+ *
Note that the {@link org.springframework.core.io.support.SpringFactoriesLoader}
+ * sorts the {@code BeanInfoFactory} instances by
+ * {@link org.springframework.core.annotation.Order @Order}, so that ones with
* a higher precedence come first.
*
* @author Arjen Poutsma
@@ -42,18 +43,10 @@ import java.beans.IntrospectionException;
public interface BeanInfoFactory {
/**
- * Indicates whether a bean with the given class is supported by this factory.
+ * Returns the bean info for the given class, if supported.
*
* @param beanClass the bean class
- * @return {@code true} if supported; {@code false} otherwise
- */
- boolean supports(Class> beanClass);
-
- /**
- * Returns the bean info for the given class.
- *
- * @param beanClass the bean class
- * @return the bean info
+ * @return the bean info, or {@code null} if not the given class is not supported
* @throws IntrospectionException in case of exceptions
*/
BeanInfo getBeanInfo(Class> beanClass) throws IntrospectionException;
diff --git a/spring-beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java b/spring-beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java
index c0da75ffcc..8da24fc802 100644
--- a/spring-beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java
+++ b/spring-beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java
@@ -20,25 +20,21 @@ import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
-import java.io.IOException;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import java.util.Properties;
import java.util.Set;
import java.util.WeakHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.springframework.core.annotation.AnnotationAwareOrderComparator;
-import org.springframework.core.io.support.PropertiesLoaderUtils;
+import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
@@ -64,12 +60,6 @@ import org.springframework.util.StringUtils;
*/
public class CachedIntrospectionResults {
- /**
- * The location to look for the bean info mapping files. Can be present in multiple JAR files.
- */
- public static final String BEAN_INFO_FACTORIES_LOCATION = "META-INF/spring.beanInfoFactories";
-
-
private static final Log logger = LogFactory.getLog(CachedIntrospectionResults.class);
/**
@@ -242,8 +232,8 @@ public class CachedIntrospectionResults {
BeanInfo beanInfo = null;
List beanInfoFactories = getBeanInfoFactories(beanClass.getClassLoader());
for (BeanInfoFactory beanInfoFactory : beanInfoFactories) {
- if (beanInfoFactory.supports(beanClass)) {
- beanInfo = beanInfoFactory.getBeanInfo(beanClass);
+ beanInfo = beanInfoFactory.getBeanInfo(beanClass);
+ if (beanInfo != null) {
break;
}
}
@@ -339,57 +329,12 @@ public class CachedIntrospectionResults {
if (beanInfoFactories == null) {
synchronized (beanInfoFactoriesMutex) {
if (beanInfoFactories == null) {
- try {
- Properties properties =
- PropertiesLoaderUtils.loadAllProperties(
- BEAN_INFO_FACTORIES_LOCATION, classLoader);
-
- if (logger.isDebugEnabled()) {
- logger.debug("Loaded BeanInfoFactories: " + properties.keySet());
- }
-
- List factories = new ArrayList(properties.size());
-
- for (Object key : properties.keySet()) {
- if (key instanceof String) {
- String className = (String) key;
- BeanInfoFactory factory = instantiateBeanInfoFactory(className, classLoader);
- factories.add(factory);
- }
- }
-
- Collections.sort(factories, new AnnotationAwareOrderComparator());
-
- beanInfoFactories = Collections.synchronizedList(factories);
- }
- catch (IOException ex) {
- throw new IllegalStateException(
- "Unable to load BeanInfoFactories from location [" + BEAN_INFO_FACTORIES_LOCATION + "]", ex);
- }
+ beanInfoFactories = Collections.synchronizedList(SpringFactoriesLoader
+ .loadFactories(BeanInfoFactory.class, classLoader));
}
}
}
return beanInfoFactories;
}
- private static BeanInfoFactory instantiateBeanInfoFactory(String className,
- ClassLoader classLoader) {
- try {
- Class> factoryClass = ClassUtils.forName(className, classLoader);
- if (!BeanInfoFactory.class.isAssignableFrom(factoryClass)) {
- throw new FatalBeanException(
- "Class [" + className + "] does not implement the [" +
- BeanInfoFactory.class.getName() + "] interface");
- }
- return (BeanInfoFactory) BeanUtils.instantiate(factoryClass);
- }
- catch (ClassNotFoundException ex) {
- throw new FatalBeanException(
- "BeanInfoFactory class [" + className + "] not found", ex);
- }
- catch (LinkageError err) {
- throw new FatalBeanException("Invalid BeanInfoFactory class [" + className +
- "]: problem with handler class file or dependent class", err);
- }
- }
}
diff --git a/spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfoFactory.java b/spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfoFactory.java
index 5f6256621f..2eafdea317 100644
--- a/spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfoFactory.java
+++ b/spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfoFactory.java
@@ -19,7 +19,6 @@ package org.springframework.beans;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
-
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
@@ -37,13 +36,21 @@ import org.springframework.core.Ordered;
* @since 3.2
* @see BeanInfoFactory
*/
-class ExtendedBeanInfoFactory implements Ordered, BeanInfoFactory {
+public class ExtendedBeanInfoFactory implements Ordered, BeanInfoFactory {
+
+ /**
+ * Return a new {@link ExtendedBeanInfo} for the given bean class.
+ */
+ public BeanInfo getBeanInfo(Class> beanClass) throws IntrospectionException {
+ return supports(beanClass) ?
+ new ExtendedBeanInfo(Introspector.getBeanInfo(beanClass)) : null;
+ }
/**
* Return whether the given bean class declares or inherits any non-void returning
* JavaBeans or indexed property setter methods.
*/
- public boolean supports(Class> beanClass) {
+ private boolean supports(Class> beanClass) {
for (Method method : beanClass.getMethods()) {
String methodName = method.getName();
Class>[] parameterTypes = method.getParameterTypes();
@@ -59,13 +66,6 @@ class ExtendedBeanInfoFactory implements Ordered, BeanInfoFactory {
return false;
}
- /**
- * Return a new {@link ExtendedBeanInfo} for the given bean class.
- */
- public BeanInfo getBeanInfo(Class> beanClass) throws IntrospectionException {
- return new ExtendedBeanInfo(Introspector.getBeanInfo(beanClass));
- }
-
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
diff --git a/spring-beans/src/main/resources/META-INF/spring.beanInfoFactories b/spring-beans/src/main/resources/META-INF/spring.beanInfoFactories
deleted file mode 100644
index 7a104edec2..0000000000
--- a/spring-beans/src/main/resources/META-INF/spring.beanInfoFactories
+++ /dev/null
@@ -1 +0,0 @@
-org.springframework.beans.ExtendedBeanInfoFactory
diff --git a/spring-beans/src/main/resources/META-INF/spring.factories b/spring-beans/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000000..b623047ec2
--- /dev/null
+++ b/spring-beans/src/main/resources/META-INF/spring.factories
@@ -0,0 +1 @@
+org.springframework.beans.BeanInfoFactory=org.springframework.beans.ExtendedBeanInfoFactory
\ No newline at end of file
diff --git a/spring-beans/src/test/java/org/springframework/beans/ExtendedBeanInfoFactoryTests.java b/spring-beans/src/test/java/org/springframework/beans/ExtendedBeanInfoFactoryTests.java
index d56b672e5b..d2ee119f81 100644
--- a/spring-beans/src/test/java/org/springframework/beans/ExtendedBeanInfoFactoryTests.java
+++ b/spring-beans/src/test/java/org/springframework/beans/ExtendedBeanInfoFactoryTests.java
@@ -18,11 +18,11 @@ package org.springframework.beans;
import java.beans.IntrospectionException;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
import org.junit.Test;
-import static org.hamcrest.CoreMatchers.*;
-import static org.junit.Assert.*;
-
/**
* Unit tests for {@link ExtendedBeanInfoTests}.
*
@@ -38,7 +38,7 @@ public class ExtendedBeanInfoFactoryTests {
class C {
public void setFoo(String s) { }
}
- assertThat(factory.supports(C.class), is(false));
+ assertThat(factory.getBeanInfo(C.class), nullValue());
}
@Test
@@ -47,7 +47,7 @@ public class ExtendedBeanInfoFactoryTests {
class C {
public C setFoo(String s) { return this; }
}
- assertThat(factory.supports(C.class), is(true));
+ assertThat(factory.getBeanInfo(C.class), notNullValue());
}
@Test
@@ -56,7 +56,7 @@ public class ExtendedBeanInfoFactoryTests {
class C {
public C setFoo(int i, String s) { return this; }
}
- assertThat(factory.supports(C.class), is(true));
+ assertThat(factory.getBeanInfo(C.class), notNullValue());
}
@Test
@@ -65,7 +65,7 @@ public class ExtendedBeanInfoFactoryTests {
class C {
void setBar(String s) { }
}
- assertThat(factory.supports(C.class), is(false));
+ assertThat(factory.getBeanInfo(C.class), nullValue());
}
@Test
@@ -74,7 +74,7 @@ public class ExtendedBeanInfoFactoryTests {
class C {
C setBar() { return this; }
}
- assertThat(factory.supports(C.class), is(false));
+ assertThat(factory.getBeanInfo(C.class), nullValue());
}
@Test
@@ -83,7 +83,7 @@ public class ExtendedBeanInfoFactoryTests {
class C {
C set(String s) { return this; }
}
- assertThat(factory.supports(C.class), is(false));
+ assertThat(factory.getBeanInfo(C.class), nullValue());
}
}