Skip to content

Commit 79a5696

Browse files
committed
PersistenceAnnotationBeanPostProcessor obtains default EntityManagerFactory via getBean(Class) algorithm
Issue: SPR-7549 (cherry picked from commit 6157fad)
1 parent 0bc0453 commit 79a5696

File tree

7 files changed

+210
-97
lines changed

7 files changed

+210
-97
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/BeanFactory.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2015 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -153,12 +153,12 @@ public interface BeanFactory {
153153

154154
/**
155155
* Return the bean instance that uniquely matches the given object type, if any.
156-
* @param requiredType type the bean must match; can be an interface or superclass.
157-
* {@code null} is disallowed.
158156
* <p>This method goes into {@link ListableBeanFactory} by-type lookup territory
159157
* but may also be translated into a conventional by-name lookup based on the name
160158
* of the given type. For more extensive retrieval operations across sets of beans,
161159
* use {@link ListableBeanFactory} and/or {@link BeanFactoryUtils}.
160+
* @param requiredType type the bean must match; can be an interface or superclass.
161+
* {@code null} is disallowed.
162162
* @return an instance of the single bean matching the required type
163163
* @throws NoSuchBeanDefinitionException if no bean of the given type was found
164164
* @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found

spring-beans/src/main/java/org/springframework/beans/factory/NamedBean.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2006 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,10 +17,10 @@
1717
package org.springframework.beans.factory;
1818

1919
/**
20-
* Counterpart of BeanNameAware. Returns the bean name of an object.
20+
* Counterpart of {@link BeanNameAware}. Returns the bean name of an object.
2121
*
22-
* <p>This interface can be introduced to avoid a brittle dependence
23-
* on bean name in objects used with Spring IoC and Spring AOP.
22+
* <p>This interface can be introduced to avoid a brittle dependence on
23+
* bean name in objects used with Spring IoC and Spring AOP.
2424
*
2525
* @author Rod Johnson
2626
* @since 2.0
@@ -29,7 +29,7 @@
2929
public interface NamedBean {
3030

3131
/**
32-
* Return the name of this bean in a Spring bean factory.
32+
* Return the name of this bean in a Spring bean factory, if known.
3333
*/
3434
String getBeanName();
3535

spring-beans/src/main/java/org/springframework/beans/factory/config/AutowireCapableBeanFactory.java

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import org.springframework.beans.BeansException;
2222
import org.springframework.beans.TypeConverter;
2323
import org.springframework.beans.factory.BeanFactory;
24+
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
25+
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
2426

2527
/**
2628
* Extension of the {@link org.springframework.beans.factory.BeanFactory}
@@ -154,15 +156,6 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
154156
*/
155157
Object configureBean(Object existingBean, String beanName) throws BeansException;
156158

157-
/**
158-
* Resolve the specified dependency against the beans defined in this factory.
159-
* @param descriptor the descriptor for the dependency
160-
* @param beanName the name of the bean which declares the present dependency
161-
* @return the resolved object, or {@code null} if none found
162-
* @throws BeansException if dependency resolution failed
163-
*/
164-
Object resolveDependency(DependencyDescriptor descriptor, String beanName) throws BeansException;
165-
166159

167160
//-------------------------------------------------------------------------
168161
// Specialized methods for fine-grained control over the bean lifecycle
@@ -312,18 +305,55 @@ Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String be
312305
*/
313306
void destroyBean(Object existingBean);
314307

308+
309+
//-------------------------------------------------------------------------
310+
// Delegate methods for resolving injection points
311+
//-------------------------------------------------------------------------
312+
313+
/**
314+
* Resolve the bean instance that uniquely matches the given object type, if any,
315+
* including its bean name.
316+
* <p>This is effectively a variant of {@link #getBean(Class)} which preserves the
317+
* bean name of the matching instance.
318+
* @param requiredType type the bean must match; can be an interface or superclass.
319+
* {@code null} is disallowed.
320+
* @return the bean name plus bean instance
321+
* @throws NoSuchBeanDefinitionException if no bean of the given type was found
322+
* @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found
323+
* @throws BeansException if the bean could not be created
324+
* @since 4.3.3
325+
* @see #getBean(Class)
326+
*/
327+
<T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException;
328+
329+
/**
330+
* Resolve the specified dependency against the beans defined in this factory.
331+
* @param descriptor the descriptor for the dependency
332+
* @param requestingBeanName the name of the bean which declares the present dependency
333+
* @return the resolved object, or {@code null} if none found
334+
* @throws NoSuchBeanDefinitionException if no matching bean was found
335+
* @throws NoUniqueBeanDefinitionException if more than one matching bean was found
336+
* @throws BeansException if dependency resolution failed for any other reason
337+
* @see #resolveDependency(DependencyDescriptor, String, Set, TypeConverter)
338+
* @since 2.5
339+
*/
340+
Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName) throws BeansException;
341+
315342
/**
316343
* Resolve the specified dependency against the beans defined in this factory.
317344
* @param descriptor the descriptor for the dependency
318-
* @param beanName the name of the bean which declares the present dependency
319-
* @param autowiredBeanNames a Set that all names of autowired beans (used for
320-
* resolving the present dependency) are supposed to be added to
321-
* @param typeConverter the TypeConverter to use for populating arrays and
322-
* collections
345+
* @param requestingBeanName the name of the bean which declares the present dependency
346+
* @param autowiredBeanNames a Set that all names of autowired beans (used for resolving
347+
* the present dependency) are supposed to be added to
348+
* @param typeConverter the TypeConverter to use for populating arrays and collections
323349
* @return the resolved object, or {@code null} if none found
324-
* @throws BeansException if dependency resolution failed
350+
* @throws NoSuchBeanDefinitionException if no matching bean was found
351+
* @throws NoUniqueBeanDefinitionException if more than one matching bean was found
352+
* @throws BeansException if dependency resolution failed for any other reason
353+
* @see DependencyDescriptor
354+
* @since 2.5
325355
*/
326-
Object resolveDependency(DependencyDescriptor descriptor, String beanName,
356+
Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName,
327357
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException;
328358

329359
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2002-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.beans.factory.config;
18+
19+
import org.springframework.beans.factory.NamedBean;
20+
21+
/**
22+
* A simple holder for a given bean name plus bean instance.
23+
*
24+
* @author Juergen Hoeller
25+
* @since 4.3.3
26+
* @see AutowireCapableBeanFactory#resolveNamedBean(Class)
27+
*/
28+
public class NamedBeanHolder<T> implements NamedBean {
29+
30+
private final String beanName;
31+
32+
private final T beanInstance;
33+
34+
35+
/**
36+
* Create a new holder for the given bean name plus instance.
37+
*/
38+
public NamedBeanHolder(String beanName, T beanInstance) {
39+
this.beanName = beanName;
40+
this.beanInstance = beanInstance;
41+
}
42+
43+
44+
@Override
45+
public String getBeanName() {
46+
return this.beanName;
47+
}
48+
49+
/**
50+
* Return the corresponding bean instance.
51+
*/
52+
public T getBeanInstance() {
53+
return this.beanInstance;
54+
}
55+
56+
}

spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java

Lines changed: 77 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import java.util.Collection;
3333
import java.util.Collections;
3434
import java.util.Comparator;
35-
import java.util.HashMap;
3635
import java.util.IdentityHashMap;
3736
import java.util.Iterator;
3837
import java.util.LinkedHashMap;
@@ -62,11 +61,13 @@
6261
import org.springframework.beans.factory.ObjectProvider;
6362
import org.springframework.beans.factory.SmartFactoryBean;
6463
import org.springframework.beans.factory.SmartInitializingSingleton;
64+
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
6565
import org.springframework.beans.factory.config.BeanDefinition;
6666
import org.springframework.beans.factory.config.BeanDefinitionHolder;
6767
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
6868
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
6969
import org.springframework.beans.factory.config.DependencyDescriptor;
70+
import org.springframework.beans.factory.config.NamedBeanHolder;
7071
import org.springframework.core.OrderComparator;
7172
import org.springframework.core.ResolvableType;
7273
import org.springframework.core.annotation.AnnotationUtils;
@@ -336,43 +337,15 @@ public <T> T getBean(Class<T> requiredType) throws BeansException {
336337

337338
@Override
338339
public <T> T getBean(Class<T> requiredType, Object... args) throws BeansException {
339-
Assert.notNull(requiredType, "Required type must not be null");
340-
String[] beanNames = getBeanNamesForType(requiredType);
341-
if (beanNames.length > 1) {
342-
ArrayList<String> autowireCandidates = new ArrayList<String>();
343-
for (String beanName : beanNames) {
344-
if (!containsBeanDefinition(beanName) || getBeanDefinition(beanName).isAutowireCandidate()) {
345-
autowireCandidates.add(beanName);
346-
}
347-
}
348-
if (autowireCandidates.size() > 0) {
349-
beanNames = autowireCandidates.toArray(new String[autowireCandidates.size()]);
350-
}
351-
}
352-
if (beanNames.length == 1) {
353-
return getBean(beanNames[0], requiredType, args);
354-
}
355-
else if (beanNames.length > 1) {
356-
Map<String, Object> candidates = new HashMap<String, Object>();
357-
for (String beanName : beanNames) {
358-
candidates.put(beanName, getBean(beanName, requiredType, args));
359-
}
360-
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
361-
if (primaryCandidate != null) {
362-
return getBean(primaryCandidate, requiredType, args);
363-
}
364-
String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
365-
if (priorityCandidate != null) {
366-
return getBean(priorityCandidate, requiredType, args);
367-
}
368-
throw new NoUniqueBeanDefinitionException(requiredType, candidates.keySet());
369-
}
370-
else if (getParentBeanFactory() != null) {
371-
return getParentBeanFactory().getBean(requiredType, args);
340+
NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args);
341+
if (namedBean != null) {
342+
return namedBean.getBeanInstance();
372343
}
373-
else {
374-
throw new NoSuchBeanDefinitionException(requiredType);
344+
BeanFactory parent = getParentBeanFactory();
345+
if (parent != null) {
346+
return parent.getBean(requiredType, args);
375347
}
348+
throw new NoSuchBeanDefinitionException(requiredType);
376349
}
377350

378351

@@ -652,13 +625,15 @@ protected boolean isAutowireCandidate(String beanName, DependencyDescriptor desc
652625
else if (containsSingleton(beanName)) {
653626
return isAutowireCandidate(beanName, new RootBeanDefinition(getType(beanName)), descriptor, resolver);
654627
}
655-
else if (getParentBeanFactory() instanceof DefaultListableBeanFactory) {
628+
629+
BeanFactory parent = getParentBeanFactory();
630+
if (parent instanceof DefaultListableBeanFactory) {
656631
// No bean definition found in this factory -> delegate to parent.
657-
return ((DefaultListableBeanFactory) getParentBeanFactory()).isAutowireCandidate(beanName, descriptor, resolver);
632+
return ((DefaultListableBeanFactory) parent).isAutowireCandidate(beanName, descriptor, resolver);
658633
}
659-
else if (getParentBeanFactory() instanceof ConfigurableListableBeanFactory) {
634+
else if (parent instanceof ConfigurableListableBeanFactory) {
660635
// If no DefaultListableBeanFactory, can't pass the resolver along.
661-
return ((ConfigurableListableBeanFactory) getParentBeanFactory()).isAutowireCandidate(beanName, descriptor);
636+
return ((ConfigurableListableBeanFactory) parent).isAutowireCandidate(beanName, descriptor);
662637
}
663638
else {
664639
return true;
@@ -999,24 +974,74 @@ private void clearByTypeCache() {
999974
//---------------------------------------------------------------------
1000975

1001976
@Override
1002-
public Object resolveDependency(DependencyDescriptor descriptor, String beanName,
977+
public <T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException {
978+
NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, (Object[]) null);
979+
if (namedBean != null) {
980+
return namedBean;
981+
}
982+
BeanFactory parent = getParentBeanFactory();
983+
if (parent instanceof AutowireCapableBeanFactory) {
984+
return ((AutowireCapableBeanFactory) parent).resolveNamedBean(requiredType);
985+
}
986+
return null;
987+
}
988+
989+
private <T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType, Object... args) throws BeansException {
990+
Assert.notNull(requiredType, "Required type must not be null");
991+
String[] beanNames = getBeanNamesForType(requiredType);
992+
if (beanNames.length > 1) {
993+
ArrayList<String> autowireCandidates = new ArrayList<String>();
994+
for (String beanName : beanNames) {
995+
if (!containsBeanDefinition(beanName) || getBeanDefinition(beanName).isAutowireCandidate()) {
996+
autowireCandidates.add(beanName);
997+
}
998+
}
999+
if (!autowireCandidates.isEmpty()) {
1000+
beanNames = autowireCandidates.toArray(new String[autowireCandidates.size()]);
1001+
}
1002+
}
1003+
if (beanNames.length == 1) {
1004+
String beanName = beanNames[0];
1005+
return new NamedBeanHolder<T>(beanName, getBean(beanName, requiredType, args));
1006+
}
1007+
else if (beanNames.length > 1) {
1008+
Map<String, Object> candidates = new LinkedHashMap<String, Object>();
1009+
for (String beanName : beanNames) {
1010+
candidates.put(beanName, getBean(beanName, requiredType, args));
1011+
}
1012+
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
1013+
if (primaryCandidate != null) {
1014+
return new NamedBeanHolder<T>(primaryCandidate, getBean(primaryCandidate, requiredType, args));
1015+
}
1016+
String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
1017+
if (priorityCandidate != null) {
1018+
return new NamedBeanHolder<T>(priorityCandidate, getBean(priorityCandidate, requiredType, args));
1019+
}
1020+
throw new NoUniqueBeanDefinitionException(requiredType, candidates.keySet());
1021+
}
1022+
return null;
1023+
}
1024+
1025+
@Override
1026+
public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName,
10031027
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
10041028

10051029
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
10061030
if (javaUtilOptionalClass == descriptor.getDependencyType()) {
1007-
return new OptionalDependencyFactory().createOptionalDependency(descriptor, beanName);
1031+
return new OptionalDependencyFactory().createOptionalDependency(descriptor, requestingBeanName);
10081032
}
10091033
else if (ObjectFactory.class == descriptor.getDependencyType() ||
10101034
ObjectProvider.class == descriptor.getDependencyType()) {
1011-
return new DependencyObjectProvider(descriptor, beanName);
1035+
return new DependencyObjectProvider(descriptor, requestingBeanName);
10121036
}
10131037
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
1014-
return new Jsr330ProviderFactory().createDependencyProvider(descriptor, beanName);
1038+
return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);
10151039
}
10161040
else {
1017-
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, beanName);
1041+
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
1042+
descriptor, requestingBeanName);
10181043
if (result == null) {
1019-
result = doResolveDependency(descriptor, beanName, autowiredBeanNames, typeConverter);
1044+
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
10201045
}
10211046
return result;
10221047
}
@@ -1347,9 +1372,9 @@ protected boolean isPrimary(String beanName, Object beanInstance) {
13471372
if (containsBeanDefinition(beanName)) {
13481373
return getMergedLocalBeanDefinition(beanName).isPrimary();
13491374
}
1350-
BeanFactory parentFactory = getParentBeanFactory();
1351-
return (parentFactory instanceof DefaultListableBeanFactory &&
1352-
((DefaultListableBeanFactory) parentFactory).isPrimary(beanName, beanInstance));
1375+
BeanFactory parent = getParentBeanFactory();
1376+
return (parent instanceof DefaultListableBeanFactory &&
1377+
((DefaultListableBeanFactory) parent).isPrimary(beanName, beanInstance));
13531378
}
13541379

13551380
/**
@@ -1425,8 +1450,9 @@ private void checkBeanNotOfRequiredType(Class<?> type, DependencyDescriptor desc
14251450
}
14261451
}
14271452

1428-
if (getParentBeanFactory() instanceof DefaultListableBeanFactory) {
1429-
((DefaultListableBeanFactory) getParentBeanFactory()).checkBeanNotOfRequiredType(type, descriptor);
1453+
BeanFactory parent = getParentBeanFactory();
1454+
if (parent instanceof DefaultListableBeanFactory) {
1455+
((DefaultListableBeanFactory) parent).checkBeanNotOfRequiredType(type, descriptor);
14301456
}
14311457
}
14321458

0 commit comments

Comments
 (0)