From 264f5335a32d57798970955a35298108688423a0 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 11 Aug 2016 23:42:16 +0200 Subject: [PATCH] Polishing --- .../beans/factory/BeanFactory.java | 10 ++-- .../beans/factory/NamedBean.java | 10 ++-- .../config/AutowireCapableBeanFactory.java | 56 ++++++++++++------- .../support/DefaultListableBeanFactory.java | 46 ++++++++------- .../setup/StubWebApplicationContext.java | 12 ++-- 5 files changed, 76 insertions(+), 58 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactory.java index 3c6bd4c8b6..49d235a659 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 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. @@ -153,12 +153,12 @@ public interface BeanFactory { /** * Return the bean instance that uniquely matches the given object type, if any. - * @param requiredType type the bean must match; can be an interface or superclass. - * {@code null} is disallowed. *

This method goes into {@link ListableBeanFactory} by-type lookup territory * but may also be translated into a conventional by-name lookup based on the name * of the given type. For more extensive retrieval operations across sets of beans, * use {@link ListableBeanFactory} and/or {@link BeanFactoryUtils}. + * @param requiredType type the bean must match; can be an interface or superclass. + * {@code null} is disallowed. * @return an instance of the single bean matching the required type * @throws NoSuchBeanDefinitionException if no bean of the given type was found * @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found @@ -188,12 +188,12 @@ public interface BeanFactory { * Return an instance, which may be shared or independent, of the specified bean. *

Allows for specifying explicit constructor arguments / factory method arguments, * overriding the specified default arguments (if any) in the bean definition. - * @param requiredType type the bean must match; can be an interface or superclass. - * {@code null} is disallowed. *

This method goes into {@link ListableBeanFactory} by-type lookup territory * but may also be translated into a conventional by-name lookup based on the name * of the given type. For more extensive retrieval operations across sets of beans, * use {@link ListableBeanFactory} and/or {@link BeanFactoryUtils}. + * @param requiredType type the bean must match; can be an interface or superclass. + * {@code null} is disallowed. * @param args arguments to use when creating a bean instance using explicit arguments * (only applied when creating a new instance as opposed to retrieving an existing one) * @return an instance of the bean diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/NamedBean.java b/spring-beans/src/main/java/org/springframework/beans/factory/NamedBean.java index e1e5ed33f5..9f2453ff65 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/NamedBean.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/NamedBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2006 the original author or authors. + * Copyright 2002-2016 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. @@ -17,10 +17,10 @@ package org.springframework.beans.factory; /** - * Counterpart of BeanNameAware. Returns the bean name of an object. + * Counterpart of {@link BeanNameAware}. Returns the bean name of an object. * - *

This interface can be introduced to avoid a brittle dependence - * on bean name in objects used with Spring IoC and Spring AOP. + *

This interface can be introduced to avoid a brittle dependence on + * bean name in objects used with Spring IoC and Spring AOP. * * @author Rod Johnson * @since 2.0 @@ -29,7 +29,7 @@ package org.springframework.beans.factory; public interface NamedBean { /** - * Return the name of this bean in a Spring bean factory. + * Return the name of this bean in a Spring bean factory, if known. */ String getBeanName(); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/AutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/AutowireCapableBeanFactory.java index ffa8849a25..ef7735792b 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/AutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/AutowireCapableBeanFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2016 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. @@ -21,6 +21,8 @@ import java.util.Set; import org.springframework.beans.BeansException; import org.springframework.beans.TypeConverter; import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.NoUniqueBeanDefinitionException; /** * Extension of the {@link org.springframework.beans.factory.BeanFactory} @@ -114,9 +116,9 @@ public interface AutowireCapableBeanFactory extends BeanFactory { *

Performs full initialization of the bean, including all applicable * {@link BeanPostProcessor BeanPostProcessors}. *

Note: This is intended for creating a fresh instance, populating annotated - * fields and methods as well as applying all standard bean initialiation callbacks. + * fields and methods as well as applying all standard bean initialization callbacks. * It does not imply traditional by-name or by-type autowiring of properties; - * use {@link #createBean(Class, int, boolean)} for that purposes. + * use {@link #createBean(Class, int, boolean)} for those purposes. * @param beanClass the class of the bean to create * @return the new bean instance * @throws BeansException if instantiation or wiring failed @@ -129,7 +131,7 @@ public interface AutowireCapableBeanFactory extends BeanFactory { *

Note: This is essentially intended for (re-)populating annotated fields and * methods, either for new instances or for deserialized instances. It does * not imply traditional by-name or by-type autowiring of properties; - * use {@link #autowireBeanProperties} for that purposes. + * use {@link #autowireBeanProperties} for those purposes. * @param existingBean the existing bean instance * @throws BeansException if wiring failed */ @@ -154,15 +156,6 @@ public interface AutowireCapableBeanFactory extends BeanFactory { */ Object configureBean(Object existingBean, String beanName) throws BeansException; - /** - * Resolve the specified dependency against the beans defined in this factory. - * @param descriptor the descriptor for the dependency - * @param beanName the name of the bean which declares the present dependency - * @return the resolved object, or {@code null} if none found - * @throws BeansException in dependency resolution failed - */ - Object resolveDependency(DependencyDescriptor descriptor, String beanName) throws BeansException; - //------------------------------------------------------------------------- // Specialized methods for fine-grained control over the bean lifecycle @@ -312,18 +305,39 @@ public interface AutowireCapableBeanFactory extends BeanFactory { */ void destroyBean(Object existingBean); + + //------------------------------------------------------------------------- + // Delegate methods for resolving injection points + //------------------------------------------------------------------------- + /** * Resolve the specified dependency against the beans defined in this factory. - * @param descriptor the descriptor for the dependency - * @param beanName the name of the bean which declares the present dependency - * @param autowiredBeanNames a Set that all names of autowired beans (used for - * resolving the present dependency) are supposed to be added to - * @param typeConverter the TypeConverter to use for populating arrays and - * collections + * @param descriptor the descriptor for the dependency (field/method/constructor) + * @param requestingBeanName the name of the bean which declares the given dependency * @return the resolved object, or {@code null} if none found - * @throws BeansException in dependency resolution failed + * @throws NoSuchBeanDefinitionException if no matching bean was found + * @throws NoUniqueBeanDefinitionException if more than one matching bean was found + * @throws BeansException if dependency resolution failed for any other reason + * @since 2.5 + * @see #resolveDependency(DependencyDescriptor, String, Set, TypeConverter) */ - Object resolveDependency(DependencyDescriptor descriptor, String beanName, + Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName) throws BeansException; + + /** + * Resolve the specified dependency against the beans defined in this factory. + * @param descriptor the descriptor for the dependency (field/method/constructor) + * @param requestingBeanName the name of the bean which declares the given dependency + * @param autowiredBeanNames a Set that all names of autowired beans (used for + * resolving the given dependency) are supposed to be added to + * @param typeConverter the TypeConverter to use for populating arrays and collections + * @return the resolved object, or {@code null} if none found + * @throws NoSuchBeanDefinitionException if no matching bean was found + * @throws NoUniqueBeanDefinitionException if more than one matching bean was found + * @throws BeansException if dependency resolution failed for any other reason + * @since 2.5 + * @see DependencyDescriptor + */ + Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName, Set autowiredBeanNames, TypeConverter typeConverter) throws BeansException; } 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 d74efb199c..88f498c58e 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-2015 the original author or authors. + * Copyright 2002-2016 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. @@ -32,7 +32,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; -import java.util.HashMap; import java.util.IdentityHashMap; import java.util.Iterator; import java.util.LinkedHashMap; @@ -336,6 +335,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto public T getBean(Class requiredType, Object... args) throws BeansException { Assert.notNull(requiredType, "Required type must not be null"); String[] beanNames = getBeanNamesForType(requiredType); + if (beanNames.length > 1) { ArrayList autowireCandidates = new ArrayList(); for (String beanName : beanNames) { @@ -347,11 +347,12 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto beanNames = autowireCandidates.toArray(new String[autowireCandidates.size()]); } } + if (beanNames.length == 1) { return getBean(beanNames[0], requiredType, args); } else if (beanNames.length > 1) { - Map candidates = new HashMap(); + Map candidates = new LinkedHashMap(); for (String beanName : beanNames) { candidates.put(beanName, getBean(beanName, requiredType, args)); } @@ -365,12 +366,12 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto } throw new NoUniqueBeanDefinitionException(requiredType, candidates.keySet()); } - else if (getParentBeanFactory() != null) { - return getParentBeanFactory().getBean(requiredType, args); - } - else { - throw new NoSuchBeanDefinitionException(requiredType); + + BeanFactory parent = getParentBeanFactory(); + if (parent != null) { + return parent.getBean(requiredType, args); } + throw new NoSuchBeanDefinitionException(requiredType); } @@ -648,13 +649,15 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto else if (containsSingleton(beanName)) { return isAutowireCandidate(beanName, new RootBeanDefinition(getType(beanName)), descriptor, resolver); } - else if (getParentBeanFactory() instanceof DefaultListableBeanFactory) { + + BeanFactory parent = getParentBeanFactory(); + if (parent instanceof DefaultListableBeanFactory) { // No bean definition found in this factory -> delegate to parent. - return ((DefaultListableBeanFactory) getParentBeanFactory()).isAutowireCandidate(beanName, descriptor, resolver); + return ((DefaultListableBeanFactory) parent).isAutowireCandidate(beanName, descriptor, resolver); } - else if (getParentBeanFactory() instanceof ConfigurableListableBeanFactory) { + else if (parent instanceof ConfigurableListableBeanFactory) { // If no DefaultListableBeanFactory, can't pass the resolver along. - return ((ConfigurableListableBeanFactory) getParentBeanFactory()).isAutowireCandidate(beanName, descriptor); + return ((ConfigurableListableBeanFactory) parent).isAutowireCandidate(beanName, descriptor); } else { return true; @@ -995,23 +998,24 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto //--------------------------------------------------------------------- @Override - public Object resolveDependency(DependencyDescriptor descriptor, String beanName, + public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName, Set autowiredBeanNames, TypeConverter typeConverter) throws BeansException { descriptor.initParameterNameDiscovery(getParameterNameDiscoverer()); if (javaUtilOptionalClass == descriptor.getDependencyType()) { - return new OptionalDependencyFactory().createOptionalDependency(descriptor, beanName); + return new OptionalDependencyFactory().createOptionalDependency(descriptor, requestingBeanName); } else if (ObjectFactory.class == descriptor.getDependencyType()) { - return new DependencyObjectFactory(descriptor, beanName); + return new DependencyObjectFactory(descriptor, requestingBeanName); } else if (javaxInjectProviderClass == descriptor.getDependencyType()) { - return new DependencyProviderFactory().createDependencyProvider(descriptor, beanName); + return new DependencyProviderFactory().createDependencyProvider(descriptor, requestingBeanName); } else { - Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, beanName); + Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary( + descriptor, requestingBeanName); if (result == null) { - result = doResolveDependency(descriptor, beanName, autowiredBeanNames, typeConverter); + result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); } return result; } @@ -1316,9 +1320,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto if (containsBeanDefinition(beanName)) { return getMergedLocalBeanDefinition(beanName).isPrimary(); } - BeanFactory parentFactory = getParentBeanFactory(); - return (parentFactory instanceof DefaultListableBeanFactory && - ((DefaultListableBeanFactory) parentFactory).isPrimary(beanName, beanInstance)); + BeanFactory parent = getParentBeanFactory(); + return (parent instanceof DefaultListableBeanFactory && + ((DefaultListableBeanFactory) parent).isPrimary(beanName, beanInstance)); } /** 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 9506223a72..b25eded4cf 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-2015 the original author or authors. + * Copyright 2002-2016 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. @@ -366,17 +366,17 @@ class StubWebApplicationContext implements WebApplicationContext { @Override public T createBean(Class beanClass) { - return BeanUtils.instantiate(beanClass); + return BeanUtils.instantiateClass(beanClass); } @Override public Object createBean(Class beanClass, int autowireMode, boolean dependencyCheck) { - return BeanUtils.instantiate(beanClass); + return BeanUtils.instantiateClass(beanClass); } @Override public Object autowire(Class beanClass, int autowireMode, boolean dependencyCheck) { - return BeanUtils.instantiate(beanClass); + return BeanUtils.instantiateClass(beanClass); } @Override @@ -393,12 +393,12 @@ class StubWebApplicationContext implements WebApplicationContext { } @Override - public Object resolveDependency(DependencyDescriptor descriptor, String beanName) { + public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName) { throw new UnsupportedOperationException("Dependency resolution not supported"); } @Override - public Object resolveDependency(DependencyDescriptor descriptor, String beanName, + public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName, Set autowiredBeanNames, TypeConverter typeConverter) { throw new UnsupportedOperationException("Dependency resolution not supported"); }