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 389f19c9e48..2642e72d7ae 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -353,9 +353,31 @@ public interface ListableBeanFactory extends BeanFactory {
* @since 3.0
* @see #getBeanNamesForAnnotation
* @see #getBeansWithAnnotation
+ * @see #getType(String)
*/
@Nullable
A findAnnotationOnBean(String beanName, Class annotationType)
throws NoSuchBeanDefinitionException;
+ /**
+ * 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, as well as checking the bean's factory method (if any).
+ * @param beanName the name of the bean to look for annotations on
+ * @param annotationType the type of annotation to look for
+ * (at class, interface or factory method level of the specified bean)
+ * @param allowFactoryBeanInit whether a {@code FactoryBean} may get initialized
+ * just for the purpose of determining its object type
+ * @return the annotation of the given type if found, or {@code null} otherwise
+ * @throws NoSuchBeanDefinitionException if there is no bean with the given name
+ * @since 5.3.14
+ * @see #getBeanNamesForAnnotation
+ * @see #getBeansWithAnnotation
+ * @see #getType(String, boolean)
+ */
+ @Nullable
+ A findAnnotationOnBean(
+ String beanName, Class annotationType, boolean allowFactoryBeanInit)
+ 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 048612fbed7..b019ef5361f 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -730,14 +730,23 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
public A findAnnotationOnBean(String beanName, Class annotationType)
throws NoSuchBeanDefinitionException {
- return findMergedAnnotationOnBean(beanName, annotationType)
+ return findAnnotationOnBean(beanName, annotationType, true);
+ }
+
+ @Override
+ @Nullable
+ public A findAnnotationOnBean(
+ String beanName, Class annotationType, boolean allowFactoryBeanInit)
+ throws NoSuchBeanDefinitionException {
+
+ return findMergedAnnotationOnBean(beanName, annotationType, allowFactoryBeanInit)
.synthesize(MergedAnnotation::isPresent).orElse(null);
}
private MergedAnnotation findMergedAnnotationOnBean(
- String beanName, Class annotationType) {
+ String beanName, Class annotationType, boolean allowFactoryBeanInit) {
- Class> beanType = getType(beanName);
+ Class> beanType = getType(beanName, allowFactoryBeanInit);
if (beanType != null) {
MergedAnnotation annotation =
MergedAnnotations.from(beanType, SearchStrategy.TYPE_HIERARCHY).get(annotationType);
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 a5430120dfd..1105ead3e12 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -459,7 +459,16 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
public A findAnnotationOnBean(String beanName, Class annotationType)
throws NoSuchBeanDefinitionException {
- Class> beanType = getType(beanName);
+ return findAnnotationOnBean(beanName, annotationType, true);
+ }
+
+ @Override
+ @Nullable
+ public A findAnnotationOnBean(
+ String beanName, Class annotationType, boolean allowFactoryBeanInit)
+ throws NoSuchBeanDefinitionException {
+
+ Class> beanType = getType(beanName, allowFactoryBeanInit);
return (beanType != null ? AnnotatedElementUtils.findMergedAnnotation(beanType, annotationType) : null);
}
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 aca706e82c1..38243b17944 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
@@ -1331,6 +1331,16 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
return getBeanFactory().findAnnotationOnBean(beanName, annotationType);
}
+ @Override
+ @Nullable
+ public A findAnnotationOnBean(
+ String beanName, Class annotationType, boolean allowFactoryBeanInit)
+ throws NoSuchBeanDefinitionException {
+
+ assertBeanFactoryActive();
+ return getBeanFactory().findAnnotationOnBean(beanName, annotationType, allowFactoryBeanInit);
+ }
+
//---------------------------------------------------------------------
// Implementation of HierarchicalBeanFactory interface
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 c5271e8d18e..4a64b49d994 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -314,6 +314,15 @@ class StubWebApplicationContext implements WebApplicationContext {
return this.beanFactory.findAnnotationOnBean(beanName, annotationType);
}
+ @Override
+ @Nullable
+ public A findAnnotationOnBean(
+ String beanName, Class annotationType, boolean allowFactoryBeanInit)
+ throws NoSuchBeanDefinitionException {
+
+ return this.beanFactory.findAnnotationOnBean(beanName, annotationType, allowFactoryBeanInit);
+ }
+
//---------------------------------------------------------------------
// Implementation of HierarchicalBeanFactory interface