diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactoryUtils.java b/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactoryUtils.java index 2c37b5dfa6..50b3400754 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactoryUtils.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactoryUtils.java @@ -106,6 +106,8 @@ public abstract class BeanFactoryUtils { } + // Retrieval of bean names + /** * Count all beans in any hierarchy in which this factory participates. * Includes counts of ancestor bean factories. @@ -113,6 +115,7 @@ public abstract class BeanFactoryUtils { * with the same name) are only counted once. * @param lbf the bean factory * @return count of beans including those defined in ancestor factories + * @see #beanNamesIncludingAncestors */ public static int countBeansIncludingAncestors(ListableBeanFactory lbf) { return beanNamesIncludingAncestors(lbf).length; @@ -140,6 +143,7 @@ public abstract class BeanFactoryUtils { * @param type the type that beans must match (as a {@code ResolvableType}) * @return the array of matching bean names, or an empty array if none * @since 4.2 + * @see ListableBeanFactory#getBeanNamesForType(ResolvableType) */ public static String[] beanNamesForTypeIncludingAncestors(ListableBeanFactory lbf, ResolvableType type) { Assert.notNull(lbf, "ListableBeanFactory must not be null"); @@ -166,6 +170,7 @@ public abstract class BeanFactoryUtils { * @param lbf the bean factory * @param type the type that beans must match (as a {@code Class}) * @return the array of matching bean names, or an empty array if none + * @see ListableBeanFactory#getBeanNamesForType(Class) */ public static String[] beanNamesForTypeIncludingAncestors(ListableBeanFactory lbf, Class type) { Assert.notNull(lbf, "ListableBeanFactory must not be null"); @@ -200,6 +205,7 @@ public abstract class BeanFactoryUtils { * for this flag will initialize FactoryBeans and "factory-bean" references. * @param type the type that beans must match * @return the array of matching bean names, or an empty array if none + * @see ListableBeanFactory#getBeanNamesForType(Class, boolean, boolean) */ public static String[] beanNamesForTypeIncludingAncestors( ListableBeanFactory lbf, Class type, boolean includeNonSingletons, boolean allowEagerInit) { @@ -217,6 +223,35 @@ public abstract class BeanFactoryUtils { return result; } + /** + * Get all bean names whose {@code Class} has the supplied {@link Annotation} + * type, including those defined in ancestor factories, without creating any bean + * instances yet. Will return unique names in case of overridden bean definitions. + * @param lbf the bean factory + * @param annotationType the type of annotation to look for + * @return the array of matching bean names, or an empty array if none + * @since 5.0 + * @see ListableBeanFactory#getBeanNamesForAnnotation(Class) + */ + public static String[] beanNamesForAnnotationIncludingAncestors( + ListableBeanFactory lbf, Class annotationType) { + + Assert.notNull(lbf, "ListableBeanFactory must not be null"); + String[] result = lbf.getBeanNamesForAnnotation(annotationType); + if (lbf instanceof HierarchicalBeanFactory) { + HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf; + if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) { + String[] parentResult = beanNamesForAnnotationIncludingAncestors( + (ListableBeanFactory) hbf.getParentBeanFactory(), annotationType); + result = mergeNamesWithParent(result, parentResult, hbf); + } + } + return result; + } + + + // Retrieval of bean instances + /** * Return all beans of the given type or subtypes, also picking up beans defined in * ancestor bean factories if the current bean factory is a HierarchicalBeanFactory. @@ -233,6 +268,7 @@ public abstract class BeanFactoryUtils { * @param type type of bean to match * @return the Map of matching bean instances, or an empty Map if none * @throws BeansException if a bean could not be created + * @see ListableBeanFactory#getBeansOfType(Class) */ public static Map beansOfTypeIncludingAncestors(ListableBeanFactory lbf, Class type) throws BeansException { @@ -280,6 +316,7 @@ public abstract class BeanFactoryUtils { * for this flag will initialize FactoryBeans and "factory-bean" references. * @return the Map of matching bean instances, or an empty Map if none * @throws BeansException if a bean could not be created + * @see ListableBeanFactory#getBeansOfType(Class, boolean, boolean) */ public static Map beansOfTypeIncludingAncestors( ListableBeanFactory lbf, Class type, boolean includeNonSingletons, boolean allowEagerInit) @@ -303,7 +340,6 @@ public abstract class BeanFactoryUtils { return result; } - /** * Return a single bean of the given type or subtypes, also picking up beans * defined in ancestor bean factories if the current bean factory is a @@ -325,6 +361,7 @@ public abstract class BeanFactoryUtils { * @throws NoSuchBeanDefinitionException if no bean of the given type was found * @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found * @throws BeansException if the bean could not be created + * @see #beansOfTypeIncludingAncestors(ListableBeanFactory, Class) */ public static T beanOfTypeIncludingAncestors(ListableBeanFactory lbf, Class type) throws BeansException { @@ -333,31 +370,6 @@ public abstract class BeanFactoryUtils { return uniqueBean(type, beansOfType); } - /** - * Get all bean names whose {@code Class} has the supplied {@link Annotation} - * type, including those defined in ancestor factories, without creating any bean - * instances yet. Will return unique names in case of overridden bean definitions. - * @param lbf the bean factory - * @param annotationType the type of annotation to look for - * @return the array of matching bean names, or an empty array if none - * @since 5.0 - */ - public static String[] beanNamesForAnnotationIncludingAncestors( - ListableBeanFactory lbf, Class annotationType) { - - Assert.notNull(lbf, "ListableBeanFactory must not be null"); - String[] result = lbf.getBeanNamesForAnnotation(annotationType); - if (lbf instanceof HierarchicalBeanFactory) { - HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf; - if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) { - String[] parentResult = beanNamesForAnnotationIncludingAncestors( - (ListableBeanFactory) hbf.getParentBeanFactory(), annotationType); - result = mergeNamesWithParent(result, parentResult, hbf); - } - } - return result; - } - /** * Return a single bean of the given type or subtypes, also picking up beans * defined in ancestor bean factories if the current bean factory is a @@ -386,6 +398,7 @@ public abstract class BeanFactoryUtils { * @throws NoSuchBeanDefinitionException if no bean of the given type was found * @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found * @throws BeansException if the bean could not be created + * @see #beansOfTypeIncludingAncestors(ListableBeanFactory, Class, boolean, boolean) */ public static T beanOfTypeIncludingAncestors( ListableBeanFactory lbf, Class type, boolean includeNonSingletons, boolean allowEagerInit) @@ -410,6 +423,7 @@ public abstract class BeanFactoryUtils { * @throws NoSuchBeanDefinitionException if no bean of the given type was found * @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found * @throws BeansException if the bean could not be created + * @see ListableBeanFactory#getBeansOfType(Class) */ public static T beanOfType(ListableBeanFactory lbf, Class type) throws BeansException { Assert.notNull(lbf, "ListableBeanFactory must not be null"); @@ -440,6 +454,7 @@ public abstract class BeanFactoryUtils { * @throws NoSuchBeanDefinitionException if no bean of the given type was found * @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found * @throws BeansException if the bean could not be created + * @see ListableBeanFactory#getBeansOfType(Class, boolean, boolean) */ public static T beanOfType( ListableBeanFactory lbf, Class type, boolean includeNonSingletons, boolean allowEagerInit) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java index 8c71b36346..850c4070d6 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java @@ -56,7 +56,7 @@ import org.springframework.web.servlet.HandlerMapping; * @author Rossen Stoyanchev * @author Juergen Hoeller * @since 3.1 - * @param The mapping for a {@link HandlerMethod} containing the conditions + * @param the mapping for a {@link HandlerMethod} containing the conditions * needed to match the handler method to incoming request. */ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMapping implements InitializingBean { @@ -182,6 +182,7 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap /** * Detects handler methods at initialization. + * @see #initHandlerMethods */ @Override public void afterPropertiesSet() { @@ -190,9 +191,9 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap /** * Scan beans in the ApplicationContext, detect and register handler methods. - * @see #isHandler(Class) - * @see #getMappingForMethod(Method, Class) - * @see #handlerMethodsInitialized(Map) + * @see #isHandler + * @see #detectHandlerMethods + * @see #handlerMethodsInitialized */ protected void initHandlerMethods() { if (logger.isDebugEnabled()) { @@ -223,15 +224,16 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap } /** - * Look for handler methods in a handler. - * @param handler the bean name of a handler or a handler instance + * Look for handler methods in the specified handler bean. + * @param handler either a bean name or an actual handler instance + * @see #getMappingForMethod */ - protected void detectHandlerMethods(final Object handler) { + protected void detectHandlerMethods(Object handler) { Class handlerType = (handler instanceof String ? obtainApplicationContext().getType((String) handler) : handler.getClass()); if (handlerType != null) { - final Class userType = ClassUtils.getUserClass(handlerType); + Class userType = ClassUtils.getUserClass(handlerType); Map methods = MethodIntrospector.selectMethods(userType, (MethodIntrospector.MetadataLookup) method -> { try { @@ -474,7 +476,6 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap /** * A registry that maintains all mappings to handler methods, exposing methods * to perform lookups and providing concurrent access. - * *

Package-private for testing purposes. */ class MappingRegistry { @@ -542,11 +543,11 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap try { HandlerMethod handlerMethod = createHandlerMethod(handler, method); assertUniqueMethodMapping(handlerMethod, mapping); + this.mappingLookup.put(mapping, handlerMethod); if (logger.isInfoEnabled()) { logger.info("Mapped \"" + mapping + "\" onto " + handlerMethod); } - this.mappingLookup.put(mapping, handlerMethod); List directUrls = getDirectUrls(mapping); for (String url : directUrls) { @@ -754,6 +755,7 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap private static class EmptyHandler { + @SuppressWarnings("unused") public void handle() { throw new UnsupportedOperationException("Not implemented"); }