diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/ListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/ListableBeanFactory.java index 5f5b643f156..f95875c1a8d 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/ListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/ListableBeanFactory.java @@ -212,23 +212,36 @@ public interface ListableBeanFactory extends BeanFactory { throws BeansException; /** - * Find all beans whose {@code Class} has the supplied {@link java.lang.annotation.Annotation} type. + * Find all beans whose {@code Class} has the supplied {@link Annotation} type, + * without creating any bean instances yet. + * @param annotationType the type of annotation to look for + * @return the names of all matching beans + * @since 4.0 + */ + String[] getBeanNamesForAnnotation(Class annotationType); + + /** + * Find all beans whose {@code Class} has the supplied {@link Annotation} type, + * returning a Map of bean names with corresponding bean instances. * @param annotationType the type of annotation to look for * @return a Map with the matching beans, containing the bean names as * keys and the corresponding bean instances as values * @throws BeansException if a bean could not be created + * @since 3.0 */ - Map getBeansWithAnnotation(Class annotationType) - throws BeansException; + Map getBeansWithAnnotation(Class annotationType) throws BeansException; /** - * Find a {@link Annotation} of {@code annotationType} on the specified + * Find an {@link Annotation} of {@code annotationType} on the specified * bean, traversing its interfaces and super classes if no annotation can be * found on the given class itself. * @param beanName the name of the bean to look for annotations on * @param annotationType the annotation class to look for * @return the annotation of the given type found, or {@code null} + * @throws NoSuchBeanDefinitionException if there is no bean with the given name + * @since 3.0 */ - A findAnnotationOnBean(String beanName, Class annotationType); + A findAnnotationOnBean(String beanName, Class annotationType) + throws NoSuchBeanDefinitionException; } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java index c476f6e9161..bffe7d19915 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java @@ -487,6 +487,23 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto return result; } + @Override + public String[] getBeanNamesForAnnotation(Class annotationType) { + List results = new ArrayList(); + for (String beanName : getBeanDefinitionNames()) { + BeanDefinition beanDefinition = getBeanDefinition(beanName); + if (!beanDefinition.isAbstract() && findAnnotationOnBean(beanName, annotationType) != null) { + results.add(beanName); + } + } + for (String beanName : getSingletonNames()) { + if (!results.contains(beanName) && findAnnotationOnBean(beanName, annotationType) != null) { + results.add(beanName); + } + } + return results.toArray(new String[results.size()]); + } + @Override public Map getBeansWithAnnotation(Class annotationType) { Map results = new LinkedHashMap(); @@ -511,7 +528,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto * if not found on the exposed bean reference (e.g. in case of a proxy). */ @Override - public A findAnnotationOnBean(String beanName, Class annotationType) { + public A findAnnotationOnBean(String beanName, Class annotationType) + throws NoSuchBeanDefinitionException{ + A ann = null; Class beanType = getType(beanName); if (beanType != null) { diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java index f61b87e1af8..6901a5e21ca 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java @@ -276,6 +276,17 @@ public class StaticListableBeanFactory implements ListableBeanFactory { return matches; } + @Override + public String[] getBeanNamesForAnnotation(Class annotationType) { + List results = new ArrayList(); + for (String beanName : this.beans.keySet()) { + if (findAnnotationOnBean(beanName, annotationType) != null) { + results.add(beanName); + } + } + return results.toArray(new String[results.size()]); + } + @Override public Map getBeansWithAnnotation(Class annotationType) throws BeansException { @@ -290,7 +301,9 @@ public class StaticListableBeanFactory implements ListableBeanFactory { } @Override - public A findAnnotationOnBean(String beanName, Class annotationType) { + public A findAnnotationOnBean(String beanName, Class annotationType) + throws NoSuchBeanDefinitionException{ + return AnnotationUtils.findAnnotation(getType(beanName), annotationType); } diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java index c8a2815ca8b..83603287892 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java @@ -172,6 +172,9 @@ public class DefaultListableBeanFactoryTests { assertTrue("prototype not instantiated", !DummyFactory.wasPrototypeCreated()); String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false); assertEquals(0, beanNames.length); + beanNames = lbf.getBeanNamesForAnnotation(SuppressWarnings.class); + assertEquals(0, beanNames.length); + assertFalse(lbf.containsSingleton("x1")); assertTrue(lbf.containsBean("x1")); assertTrue(lbf.containsBean("&x1")); @@ -201,6 +204,9 @@ public class DefaultListableBeanFactoryTests { assertTrue("prototype not instantiated", !DummyFactory.wasPrototypeCreated()); String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false); assertEquals(0, beanNames.length); + beanNames = lbf.getBeanNamesForAnnotation(SuppressWarnings.class); + assertEquals(0, beanNames.length); + assertFalse(lbf.containsSingleton("x1")); assertTrue(lbf.containsBean("x1")); assertTrue(lbf.containsBean("&x1")); @@ -229,6 +235,9 @@ public class DefaultListableBeanFactoryTests { assertTrue("prototype not instantiated", !DummyFactory.wasPrototypeCreated()); String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false); assertEquals(0, beanNames.length); + beanNames = lbf.getBeanNamesForAnnotation(SuppressWarnings.class); + assertEquals(0, beanNames.length); + assertFalse(lbf.containsSingleton("x1")); assertTrue(lbf.containsBean("x1")); assertTrue(lbf.containsBean("&x1")); diff --git a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java index 728476f495e..5d6950f1611 100644 --- a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java @@ -1071,6 +1071,12 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader return getBeanFactory().getBeansOfType(type, includeNonSingletons, allowEagerInit); } + @Override + public String[] getBeanNamesForAnnotation(Class annotationType) { + assertBeanFactoryActive(); + return getBeanFactory().getBeanNamesForAnnotation(annotationType); + } + @Override public Map getBeansWithAnnotation(Class annotationType) throws BeansException { @@ -1080,7 +1086,9 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader } @Override - public A findAnnotationOnBean(String beanName, Class annotationType) { + public A findAnnotationOnBean(String beanName, Class annotationType) + throws NoSuchBeanDefinitionException{ + assertBeanFactoryActive(); return getBeanFactory().findAnnotationOnBean(beanName, annotationType); } diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/StubWebApplicationContext.java b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/StubWebApplicationContext.java index 7192a9fca61..d2db9a443a5 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/StubWebApplicationContext.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/StubWebApplicationContext.java @@ -238,6 +238,11 @@ class StubWebApplicationContext implements WebApplicationContext { return this.beanFactory.getBeansOfType(type, includeNonSingletons, allowEagerInit); } + @Override + public String[] getBeanNamesForAnnotation(Class annotationType) { + return this.beanFactory.getBeanNamesForAnnotation(annotationType); + } + @Override public Map getBeansWithAnnotation(Class annotationType) throws BeansException { @@ -246,7 +251,9 @@ class StubWebApplicationContext implements WebApplicationContext { } @Override - public A findAnnotationOnBean(String beanName, Class annotationType) { + public A findAnnotationOnBean(String beanName, Class annotationType) + throws NoSuchBeanDefinitionException{ + return this.beanFactory.findAnnotationOnBean(beanName, annotationType); }