1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.beans.factory.support;
18
19 import java.beans.PropertyEditor;
20 import java.security.AccessControlContext;
21 import java.security.AccessController;
22 import java.security.PrivilegedAction;
23 import java.security.PrivilegedActionException;
24 import java.security.PrivilegedExceptionAction;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.Collections;
28 import java.util.HashMap;
29 import java.util.HashSet;
30 import java.util.LinkedHashMap;
31 import java.util.LinkedHashSet;
32 import java.util.LinkedList;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Set;
36 import java.util.concurrent.ConcurrentHashMap;
37
38 import org.springframework.beans.BeanUtils;
39 import org.springframework.beans.BeanWrapper;
40 import org.springframework.beans.BeansException;
41 import org.springframework.beans.PropertyEditorRegistrar;
42 import org.springframework.beans.PropertyEditorRegistry;
43 import org.springframework.beans.PropertyEditorRegistrySupport;
44 import org.springframework.beans.SimpleTypeConverter;
45 import org.springframework.beans.TypeConverter;
46 import org.springframework.beans.TypeMismatchException;
47 import org.springframework.beans.factory.BeanCreationException;
48 import org.springframework.beans.factory.BeanCurrentlyInCreationException;
49 import org.springframework.beans.factory.BeanDefinitionStoreException;
50 import org.springframework.beans.factory.BeanFactory;
51 import org.springframework.beans.factory.BeanFactoryUtils;
52 import org.springframework.beans.factory.BeanIsAbstractException;
53 import org.springframework.beans.factory.BeanIsNotAFactoryException;
54 import org.springframework.beans.factory.BeanNotOfRequiredTypeException;
55 import org.springframework.beans.factory.CannotLoadBeanClassException;
56 import org.springframework.beans.factory.FactoryBean;
57 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
58 import org.springframework.beans.factory.ObjectFactory;
59 import org.springframework.beans.factory.SmartFactoryBean;
60 import org.springframework.beans.factory.config.BeanDefinition;
61 import org.springframework.beans.factory.config.BeanDefinitionHolder;
62 import org.springframework.beans.factory.config.BeanExpressionContext;
63 import org.springframework.beans.factory.config.BeanExpressionResolver;
64 import org.springframework.beans.factory.config.BeanPostProcessor;
65 import org.springframework.beans.factory.config.ConfigurableBeanFactory;
66 import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
67 import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
68 import org.springframework.beans.factory.config.Scope;
69 import org.springframework.core.DecoratingClassLoader;
70 import org.springframework.core.NamedThreadLocal;
71 import org.springframework.core.convert.ConversionService;
72 import org.springframework.util.Assert;
73 import org.springframework.util.ClassUtils;
74 import org.springframework.util.ObjectUtils;
75 import org.springframework.util.StringUtils;
76 import org.springframework.util.StringValueResolver;
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111 public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
112
113
114 private BeanFactory parentBeanFactory;
115
116
117 private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
118
119
120 private ClassLoader tempClassLoader;
121
122
123 private boolean cacheBeanMetadata = true;
124
125
126 private BeanExpressionResolver beanExpressionResolver;
127
128
129 private ConversionService conversionService;
130
131
132 private final Set<PropertyEditorRegistrar> propertyEditorRegistrars =
133 new LinkedHashSet<PropertyEditorRegistrar>(4);
134
135
136 private TypeConverter typeConverter;
137
138
139 private final Map<Class<?>, Class<? extends PropertyEditor>> customEditors =
140 new HashMap<Class<?>, Class<? extends PropertyEditor>>(4);
141
142
143 private final List<StringValueResolver> embeddedValueResolvers = new LinkedList<StringValueResolver>();
144
145
146 private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>();
147
148
149 private boolean hasInstantiationAwareBeanPostProcessors;
150
151
152 private boolean hasDestructionAwareBeanPostProcessors;
153
154
155 private final Map<String, Scope> scopes = new LinkedHashMap<String, Scope>(8);
156
157
158 private SecurityContextProvider securityContextProvider;
159
160
161 private final Map<String, RootBeanDefinition> mergedBeanDefinitions =
162 new ConcurrentHashMap<String, RootBeanDefinition>(64);
163
164
165 private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(64));
166
167
168 private final ThreadLocal<Object> prototypesCurrentlyInCreation =
169 new NamedThreadLocal<Object>("Prototype beans currently in creation");
170
171
172
173
174
175 public AbstractBeanFactory() {
176 }
177
178
179
180
181
182
183 public AbstractBeanFactory(BeanFactory parentBeanFactory) {
184 this.parentBeanFactory = parentBeanFactory;
185 }
186
187
188
189
190
191
192 @Override
193 public Object getBean(String name) throws BeansException {
194 return doGetBean(name, null, null, false);
195 }
196
197 @Override
198 public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
199 return doGetBean(name, requiredType, null, false);
200 }
201
202 @Override
203 public Object getBean(String name, Object... args) throws BeansException {
204 return doGetBean(name, null, args, false);
205 }
206
207
208
209
210
211
212
213
214
215
216 public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {
217 return doGetBean(name, requiredType, args, false);
218 }
219
220
221
222
223
224
225
226
227
228
229
230
231 @SuppressWarnings("unchecked")
232 protected <T> T doGetBean(
233 final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
234 throws BeansException {
235
236 final String beanName = transformedBeanName(name);
237 Object bean;
238
239
240 Object sharedInstance = getSingleton(beanName);
241 if (sharedInstance != null && args == null) {
242 if (logger.isDebugEnabled()) {
243 if (isSingletonCurrentlyInCreation(beanName)) {
244 logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
245 "' that is not fully initialized yet - a consequence of a circular reference");
246 }
247 else {
248 logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
249 }
250 }
251 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
252 }
253
254 else {
255
256
257 if (isPrototypeCurrentlyInCreation(beanName)) {
258 throw new BeanCurrentlyInCreationException(beanName);
259 }
260
261
262 BeanFactory parentBeanFactory = getParentBeanFactory();
263 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
264
265 String nameToLookup = originalBeanName(name);
266 if (args != null) {
267
268 return (T) parentBeanFactory.getBean(nameToLookup, args);
269 }
270 else {
271
272 return parentBeanFactory.getBean(nameToLookup, requiredType);
273 }
274 }
275
276 if (!typeCheckOnly) {
277 markBeanAsCreated(beanName);
278 }
279
280 try {
281 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
282 checkMergedBeanDefinition(mbd, beanName, args);
283
284
285 String[] dependsOn = mbd.getDependsOn();
286 if (dependsOn != null) {
287 for (String dependsOnBean : dependsOn) {
288 if (isDependent(beanName, dependsOnBean)) {
289 throw new BeanCreationException(mbd.getResourceDescription(), beanName,
290 "Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
291 }
292 registerDependentBean(dependsOnBean, beanName);
293 getBean(dependsOnBean);
294 }
295 }
296
297
298 if (mbd.isSingleton()) {
299 sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
300 @Override
301 public Object getObject() throws BeansException {
302 try {
303 return createBean(beanName, mbd, args);
304 }
305 catch (BeansException ex) {
306
307
308
309 destroySingleton(beanName);
310 throw ex;
311 }
312 }
313 });
314 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
315 }
316
317 else if (mbd.isPrototype()) {
318
319 Object prototypeInstance = null;
320 try {
321 beforePrototypeCreation(beanName);
322 prototypeInstance = createBean(beanName, mbd, args);
323 }
324 finally {
325 afterPrototypeCreation(beanName);
326 }
327 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
328 }
329
330 else {
331 String scopeName = mbd.getScope();
332 final Scope scope = this.scopes.get(scopeName);
333 if (scope == null) {
334 throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
335 }
336 try {
337 Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
338 @Override
339 public Object getObject() throws BeansException {
340 beforePrototypeCreation(beanName);
341 try {
342 return createBean(beanName, mbd, args);
343 }
344 finally {
345 afterPrototypeCreation(beanName);
346 }
347 }
348 });
349 bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
350 }
351 catch (IllegalStateException ex) {
352 throw new BeanCreationException(beanName,
353 "Scope '" + scopeName + "' is not active for the current thread; " +
354 "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",
355 ex);
356 }
357 }
358 }
359 catch (BeansException ex) {
360 cleanupAfterBeanCreationFailure(beanName);
361 throw ex;
362 }
363 }
364
365
366 if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
367 try {
368 return getTypeConverter().convertIfNecessary(bean, requiredType);
369 }
370 catch (TypeMismatchException ex) {
371 if (logger.isDebugEnabled()) {
372 logger.debug("Failed to convert bean '" + name + "' to required type [" +
373 ClassUtils.getQualifiedName(requiredType) + "]", ex);
374 }
375 throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
376 }
377 }
378 return (T) bean;
379 }
380
381 @Override
382 public boolean containsBean(String name) {
383 String beanName = transformedBeanName(name);
384 if (containsSingleton(beanName) || containsBeanDefinition(beanName)) {
385 return (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(name));
386 }
387
388 BeanFactory parentBeanFactory = getParentBeanFactory();
389 return (parentBeanFactory != null && parentBeanFactory.containsBean(originalBeanName(name)));
390 }
391
392 @Override
393 public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
394 String beanName = transformedBeanName(name);
395
396 Object beanInstance = getSingleton(beanName, false);
397 if (beanInstance != null) {
398 if (beanInstance instanceof FactoryBean) {
399 return (BeanFactoryUtils.isFactoryDereference(name) || ((FactoryBean<?>) beanInstance).isSingleton());
400 }
401 else {
402 return !BeanFactoryUtils.isFactoryDereference(name);
403 }
404 }
405 else if (containsSingleton(beanName)) {
406 return true;
407 }
408
409 else {
410
411 BeanFactory parentBeanFactory = getParentBeanFactory();
412 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
413
414 return parentBeanFactory.isSingleton(originalBeanName(name));
415 }
416
417 RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
418
419
420 if (mbd.isSingleton()) {
421 if (isFactoryBean(beanName, mbd)) {
422 if (BeanFactoryUtils.isFactoryDereference(name)) {
423 return true;
424 }
425 FactoryBean<?> factoryBean = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
426 return factoryBean.isSingleton();
427 }
428 else {
429 return !BeanFactoryUtils.isFactoryDereference(name);
430 }
431 }
432 else {
433 return false;
434 }
435 }
436 }
437
438 @Override
439 public boolean isPrototype(String name) throws NoSuchBeanDefinitionException {
440 String beanName = transformedBeanName(name);
441
442 BeanFactory parentBeanFactory = getParentBeanFactory();
443 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
444
445 return parentBeanFactory.isPrototype(originalBeanName(name));
446 }
447
448 RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
449 if (mbd.isPrototype()) {
450
451 return (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(beanName, mbd));
452 }
453 else {
454
455
456 if (BeanFactoryUtils.isFactoryDereference(name)) {
457 return false;
458 }
459 if (isFactoryBean(beanName, mbd)) {
460 final FactoryBean<?> factoryBean = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
461 if (System.getSecurityManager() != null) {
462 return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
463 @Override
464 public Boolean run() {
465 return ((factoryBean instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factoryBean).isPrototype()) ||
466 !factoryBean.isSingleton());
467 }
468 }, getAccessControlContext());
469 }
470 else {
471 return ((factoryBean instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factoryBean).isPrototype()) ||
472 !factoryBean.isSingleton());
473 }
474 }
475 else {
476 return false;
477 }
478 }
479 }
480
481 @Override
482 public boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException {
483 String beanName = transformedBeanName(name);
484 Class<?> typeToMatch = (targetType != null ? targetType : Object.class);
485
486
487 Object beanInstance = getSingleton(beanName, false);
488 if (beanInstance != null) {
489 if (beanInstance instanceof FactoryBean) {
490 if (!BeanFactoryUtils.isFactoryDereference(name)) {
491 Class<?> type = getTypeForFactoryBean((FactoryBean<?>) beanInstance);
492 return (type != null && ClassUtils.isAssignable(typeToMatch, type));
493 }
494 else {
495 return ClassUtils.isAssignableValue(typeToMatch, beanInstance);
496 }
497 }
498 else {
499 return !BeanFactoryUtils.isFactoryDereference(name) &&
500 ClassUtils.isAssignableValue(typeToMatch, beanInstance);
501 }
502 }
503 else if (containsSingleton(beanName) && !containsBeanDefinition(beanName)) {
504
505 return false;
506 }
507
508 else {
509
510 BeanFactory parentBeanFactory = getParentBeanFactory();
511 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
512
513 return parentBeanFactory.isTypeMatch(originalBeanName(name), targetType);
514 }
515
516
517 RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
518
519 Class<?>[] typesToMatch = (FactoryBean.class.equals(typeToMatch) ?
520 new Class<?>[] {typeToMatch} : new Class<?>[] {FactoryBean.class, typeToMatch});
521
522
523
524 BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
525 if (dbd != null && !BeanFactoryUtils.isFactoryDereference(name)) {
526 RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd);
527 Class<?> targetClass = predictBeanType(dbd.getBeanName(), tbd, typesToMatch);
528 if (targetClass != null && !FactoryBean.class.isAssignableFrom(targetClass)) {
529 return typeToMatch.isAssignableFrom(targetClass);
530 }
531 }
532
533 Class<?> beanType = predictBeanType(beanName, mbd, typesToMatch);
534 if (beanType == null) {
535 return false;
536 }
537
538
539 if (FactoryBean.class.isAssignableFrom(beanType)) {
540 if (!BeanFactoryUtils.isFactoryDereference(name)) {
541
542 beanType = getTypeForFactoryBean(beanName, mbd);
543 if (beanType == null) {
544 return false;
545 }
546 }
547 }
548 else if (BeanFactoryUtils.isFactoryDereference(name)) {
549
550
551
552 beanType = predictBeanType(beanName, mbd, FactoryBean.class);
553 if (beanType == null || !FactoryBean.class.isAssignableFrom(beanType)) {
554 return false;
555 }
556 }
557
558 return typeToMatch.isAssignableFrom(beanType);
559 }
560 }
561
562 @Override
563 public Class<?> getType(String name) throws NoSuchBeanDefinitionException {
564 String beanName = transformedBeanName(name);
565
566
567 Object beanInstance = getSingleton(beanName, false);
568 if (beanInstance != null) {
569 if (beanInstance instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
570 return getTypeForFactoryBean((FactoryBean<?>) beanInstance);
571 }
572 else {
573 return beanInstance.getClass();
574 }
575 }
576 else if (containsSingleton(beanName) && !containsBeanDefinition(beanName)) {
577
578 return null;
579 }
580
581 else {
582
583 BeanFactory parentBeanFactory = getParentBeanFactory();
584 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
585
586 return parentBeanFactory.getType(originalBeanName(name));
587 }
588
589 RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
590
591
592
593 BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
594 if (dbd != null && !BeanFactoryUtils.isFactoryDereference(name)) {
595 RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd);
596 Class<?> targetClass = predictBeanType(dbd.getBeanName(), tbd);
597 if (targetClass != null && !FactoryBean.class.isAssignableFrom(targetClass)) {
598 return targetClass;
599 }
600 }
601
602 Class<?> beanClass = predictBeanType(beanName, mbd);
603
604
605 if (beanClass != null && FactoryBean.class.isAssignableFrom(beanClass)) {
606 if (!BeanFactoryUtils.isFactoryDereference(name)) {
607
608 return getTypeForFactoryBean(beanName, mbd);
609 }
610 else {
611 return beanClass;
612 }
613 }
614 else {
615 return (!BeanFactoryUtils.isFactoryDereference(name) ? beanClass : null);
616 }
617 }
618 }
619
620 @Override
621 public String[] getAliases(String name) {
622 String beanName = transformedBeanName(name);
623 List<String> aliases = new ArrayList<String>();
624 boolean factoryPrefix = name.startsWith(FACTORY_BEAN_PREFIX);
625 String fullBeanName = beanName;
626 if (factoryPrefix) {
627 fullBeanName = FACTORY_BEAN_PREFIX + beanName;
628 }
629 if (!fullBeanName.equals(name)) {
630 aliases.add(fullBeanName);
631 }
632 String[] retrievedAliases = super.getAliases(beanName);
633 for (String retrievedAlias : retrievedAliases) {
634 String alias = (factoryPrefix ? FACTORY_BEAN_PREFIX : "") + retrievedAlias;
635 if (!alias.equals(name)) {
636 aliases.add(alias);
637 }
638 }
639 if (!containsSingleton(beanName) && !containsBeanDefinition(beanName)) {
640 BeanFactory parentBeanFactory = getParentBeanFactory();
641 if (parentBeanFactory != null) {
642 aliases.addAll(Arrays.asList(parentBeanFactory.getAliases(fullBeanName)));
643 }
644 }
645 return StringUtils.toStringArray(aliases);
646 }
647
648
649
650
651
652
653 @Override
654 public BeanFactory getParentBeanFactory() {
655 return this.parentBeanFactory;
656 }
657
658 @Override
659 public boolean containsLocalBean(String name) {
660 String beanName = transformedBeanName(name);
661 return ((containsSingleton(beanName) || containsBeanDefinition(beanName)) &&
662 (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(beanName)));
663 }
664
665
666
667
668
669
670 @Override
671 public void setParentBeanFactory(BeanFactory parentBeanFactory) {
672 if (this.parentBeanFactory != null && this.parentBeanFactory != parentBeanFactory) {
673 throw new IllegalStateException("Already associated with parent BeanFactory: " + this.parentBeanFactory);
674 }
675 this.parentBeanFactory = parentBeanFactory;
676 }
677
678 @Override
679 public void setBeanClassLoader(ClassLoader beanClassLoader) {
680 this.beanClassLoader = (beanClassLoader != null ? beanClassLoader : ClassUtils.getDefaultClassLoader());
681 }
682
683 @Override
684 public ClassLoader getBeanClassLoader() {
685 return this.beanClassLoader;
686 }
687
688 @Override
689 public void setTempClassLoader(ClassLoader tempClassLoader) {
690 this.tempClassLoader = tempClassLoader;
691 }
692
693 @Override
694 public ClassLoader getTempClassLoader() {
695 return this.tempClassLoader;
696 }
697
698 @Override
699 public void setCacheBeanMetadata(boolean cacheBeanMetadata) {
700 this.cacheBeanMetadata = cacheBeanMetadata;
701 }
702
703 @Override
704 public boolean isCacheBeanMetadata() {
705 return this.cacheBeanMetadata;
706 }
707
708 @Override
709 public void setBeanExpressionResolver(BeanExpressionResolver resolver) {
710 this.beanExpressionResolver = resolver;
711 }
712
713 @Override
714 public BeanExpressionResolver getBeanExpressionResolver() {
715 return this.beanExpressionResolver;
716 }
717
718 @Override
719 public void setConversionService(ConversionService conversionService) {
720 this.conversionService = conversionService;
721 }
722
723 @Override
724 public ConversionService getConversionService() {
725 return this.conversionService;
726 }
727
728 @Override
729 public void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar) {
730 Assert.notNull(registrar, "PropertyEditorRegistrar must not be null");
731 this.propertyEditorRegistrars.add(registrar);
732 }
733
734
735
736
737 public Set<PropertyEditorRegistrar> getPropertyEditorRegistrars() {
738 return this.propertyEditorRegistrars;
739 }
740
741 @Override
742 public void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass) {
743 Assert.notNull(requiredType, "Required type must not be null");
744 Assert.isAssignable(PropertyEditor.class, propertyEditorClass);
745 this.customEditors.put(requiredType, propertyEditorClass);
746 }
747
748 @Override
749 public void copyRegisteredEditorsTo(PropertyEditorRegistry registry) {
750 registerCustomEditors(registry);
751 }
752
753
754
755
756 public Map<Class<?>, Class<? extends PropertyEditor>> getCustomEditors() {
757 return this.customEditors;
758 }
759
760 @Override
761 public void setTypeConverter(TypeConverter typeConverter) {
762 this.typeConverter = typeConverter;
763 }
764
765
766
767
768
769 protected TypeConverter getCustomTypeConverter() {
770 return this.typeConverter;
771 }
772
773 @Override
774 public TypeConverter getTypeConverter() {
775 TypeConverter customConverter = getCustomTypeConverter();
776 if (customConverter != null) {
777 return customConverter;
778 }
779 else {
780
781 SimpleTypeConverter typeConverter = new SimpleTypeConverter();
782 typeConverter.setConversionService(getConversionService());
783 registerCustomEditors(typeConverter);
784 return typeConverter;
785 }
786 }
787
788 @Override
789 public void addEmbeddedValueResolver(StringValueResolver valueResolver) {
790 Assert.notNull(valueResolver, "StringValueResolver must not be null");
791 this.embeddedValueResolvers.add(valueResolver);
792 }
793
794 @Override
795 public String resolveEmbeddedValue(String value) {
796 String result = value;
797 for (StringValueResolver resolver : this.embeddedValueResolvers) {
798 if (result == null) {
799 return null;
800 }
801 result = resolver.resolveStringValue(result);
802 }
803 return result;
804 }
805
806 @Override
807 public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
808 Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
809 this.beanPostProcessors.remove(beanPostProcessor);
810 this.beanPostProcessors.add(beanPostProcessor);
811 if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
812 this.hasInstantiationAwareBeanPostProcessors = true;
813 }
814 if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
815 this.hasDestructionAwareBeanPostProcessors = true;
816 }
817 }
818
819 @Override
820 public int getBeanPostProcessorCount() {
821 return this.beanPostProcessors.size();
822 }
823
824
825
826
827
828 public List<BeanPostProcessor> getBeanPostProcessors() {
829 return this.beanPostProcessors;
830 }
831
832
833
834
835
836
837
838 protected boolean hasInstantiationAwareBeanPostProcessors() {
839 return this.hasInstantiationAwareBeanPostProcessors;
840 }
841
842
843
844
845
846
847
848 protected boolean hasDestructionAwareBeanPostProcessors() {
849 return this.hasDestructionAwareBeanPostProcessors;
850 }
851
852 @Override
853 public void registerScope(String scopeName, Scope scope) {
854 Assert.notNull(scopeName, "Scope identifier must not be null");
855 Assert.notNull(scope, "Scope must not be null");
856 if (SCOPE_SINGLETON.equals(scopeName) || SCOPE_PROTOTYPE.equals(scopeName)) {
857 throw new IllegalArgumentException("Cannot replace existing scopes 'singleton' and 'prototype'");
858 }
859 Scope previous = this.scopes.put(scopeName, scope);
860 if (previous != null && previous != scope) {
861 if (logger.isInfoEnabled()) {
862 logger.info("Replacing scope '" + scopeName + "' from [" + previous + "] to [" + scope + "]");
863 }
864 }
865 else {
866 if (logger.isDebugEnabled()) {
867 logger.debug("Registering scope '" + scopeName + "' with implementation [" + scope + "]");
868 }
869 }
870 }
871
872 @Override
873 public String[] getRegisteredScopeNames() {
874 return StringUtils.toStringArray(this.scopes.keySet());
875 }
876
877 @Override
878 public Scope getRegisteredScope(String scopeName) {
879 Assert.notNull(scopeName, "Scope identifier must not be null");
880 return this.scopes.get(scopeName);
881 }
882
883
884
885
886
887
888 public void setSecurityContextProvider(SecurityContextProvider securityProvider) {
889 this.securityContextProvider = securityProvider;
890 }
891
892
893
894
895
896 @Override
897 public AccessControlContext getAccessControlContext() {
898 return (this.securityContextProvider != null ?
899 this.securityContextProvider.getAccessControlContext() :
900 AccessController.getContext());
901 }
902
903 @Override
904 public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) {
905 Assert.notNull(otherFactory, "BeanFactory must not be null");
906 setBeanClassLoader(otherFactory.getBeanClassLoader());
907 setCacheBeanMetadata(otherFactory.isCacheBeanMetadata());
908 setBeanExpressionResolver(otherFactory.getBeanExpressionResolver());
909 if (otherFactory instanceof AbstractBeanFactory) {
910 AbstractBeanFactory otherAbstractFactory = (AbstractBeanFactory) otherFactory;
911 this.customEditors.putAll(otherAbstractFactory.customEditors);
912 this.propertyEditorRegistrars.addAll(otherAbstractFactory.propertyEditorRegistrars);
913 this.beanPostProcessors.addAll(otherAbstractFactory.beanPostProcessors);
914 this.hasInstantiationAwareBeanPostProcessors = this.hasInstantiationAwareBeanPostProcessors ||
915 otherAbstractFactory.hasInstantiationAwareBeanPostProcessors;
916 this.hasDestructionAwareBeanPostProcessors = this.hasDestructionAwareBeanPostProcessors ||
917 otherAbstractFactory.hasDestructionAwareBeanPostProcessors;
918 this.scopes.putAll(otherAbstractFactory.scopes);
919 this.securityContextProvider = otherAbstractFactory.securityContextProvider;
920 }
921 else {
922 setTypeConverter(otherFactory.getTypeConverter());
923 }
924 }
925
926
927
928
929
930
931
932
933
934
935
936
937 @Override
938 public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
939 String beanName = transformedBeanName(name);
940
941
942 if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
943 return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);
944 }
945
946 return getMergedLocalBeanDefinition(beanName);
947 }
948
949 @Override
950 public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
951 String beanName = transformedBeanName(name);
952
953 Object beanInstance = getSingleton(beanName, false);
954 if (beanInstance != null) {
955 return (beanInstance instanceof FactoryBean);
956 }
957 else if (containsSingleton(beanName)) {
958
959 return false;
960 }
961
962
963 if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
964
965 return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
966 }
967
968 return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
969 }
970
971 @Override
972 public boolean isActuallyInCreation(String beanName) {
973 return (isSingletonCurrentlyInCreation(beanName) || isPrototypeCurrentlyInCreation(beanName));
974 }
975
976
977
978
979
980
981 protected boolean isPrototypeCurrentlyInCreation(String beanName) {
982 Object curVal = this.prototypesCurrentlyInCreation.get();
983 return (curVal != null &&
984 (curVal.equals(beanName) || (curVal instanceof Set && ((Set<?>) curVal).contains(beanName))));
985 }
986
987
988
989
990
991
992
993 @SuppressWarnings("unchecked")
994 protected void beforePrototypeCreation(String beanName) {
995 Object curVal = this.prototypesCurrentlyInCreation.get();
996 if (curVal == null) {
997 this.prototypesCurrentlyInCreation.set(beanName);
998 }
999 else if (curVal instanceof String) {
1000 Set<String> beanNameSet = new HashSet<String>(2);
1001 beanNameSet.add((String) curVal);
1002 beanNameSet.add(beanName);
1003 this.prototypesCurrentlyInCreation.set(beanNameSet);
1004 }
1005 else {
1006 Set<String> beanNameSet = (Set<String>) curVal;
1007 beanNameSet.add(beanName);
1008 }
1009 }
1010
1011
1012
1013
1014
1015
1016
1017 @SuppressWarnings("unchecked")
1018 protected void afterPrototypeCreation(String beanName) {
1019 Object curVal = this.prototypesCurrentlyInCreation.get();
1020 if (curVal instanceof String) {
1021 this.prototypesCurrentlyInCreation.remove();
1022 }
1023 else if (curVal instanceof Set) {
1024 Set<String> beanNameSet = (Set<String>) curVal;
1025 beanNameSet.remove(beanName);
1026 if (beanNameSet.isEmpty()) {
1027 this.prototypesCurrentlyInCreation.remove();
1028 }
1029 }
1030 }
1031
1032 @Override
1033 public void destroyBean(String beanName, Object beanInstance) {
1034 destroyBean(beanName, beanInstance, getMergedLocalBeanDefinition(beanName));
1035 }
1036
1037
1038
1039
1040
1041
1042
1043
1044 protected void destroyBean(String beanName, Object beanInstance, RootBeanDefinition mbd) {
1045 new DisposableBeanAdapter(beanInstance, beanName, mbd, getBeanPostProcessors(), getAccessControlContext()).destroy();
1046 }
1047
1048 @Override
1049 public void destroyScopedBean(String beanName) {
1050 RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
1051 if (mbd.isSingleton() || mbd.isPrototype()) {
1052 throw new IllegalArgumentException(
1053 "Bean name '" + beanName + "' does not correspond to an object in a mutable scope");
1054 }
1055 String scopeName = mbd.getScope();
1056 Scope scope = this.scopes.get(scopeName);
1057 if (scope == null) {
1058 throw new IllegalStateException("No Scope SPI registered for scope '" + scopeName + "'");
1059 }
1060 Object bean = scope.remove(beanName);
1061 if (bean != null) {
1062 destroyBean(beanName, bean, mbd);
1063 }
1064 }
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077 protected String transformedBeanName(String name) {
1078 return canonicalName(BeanFactoryUtils.transformedBeanName(name));
1079 }
1080
1081
1082
1083
1084
1085
1086 protected String originalBeanName(String name) {
1087 String beanName = transformedBeanName(name);
1088 if (name.startsWith(FACTORY_BEAN_PREFIX)) {
1089 beanName = FACTORY_BEAN_PREFIX + beanName;
1090 }
1091 return beanName;
1092 }
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102 protected void initBeanWrapper(BeanWrapper bw) {
1103 bw.setConversionService(getConversionService());
1104 registerCustomEditors(bw);
1105 }
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115 protected void registerCustomEditors(PropertyEditorRegistry registry) {
1116 PropertyEditorRegistrySupport registrySupport =
1117 (registry instanceof PropertyEditorRegistrySupport ? (PropertyEditorRegistrySupport) registry : null);
1118 if (registrySupport != null) {
1119 registrySupport.useConfigValueEditors();
1120 }
1121 if (!this.propertyEditorRegistrars.isEmpty()) {
1122 for (PropertyEditorRegistrar registrar : this.propertyEditorRegistrars) {
1123 try {
1124 registrar.registerCustomEditors(registry);
1125 }
1126 catch (BeanCreationException ex) {
1127 Throwable rootCause = ex.getMostSpecificCause();
1128 if (rootCause instanceof BeanCurrentlyInCreationException) {
1129 BeanCreationException bce = (BeanCreationException) rootCause;
1130 if (isCurrentlyInCreation(bce.getBeanName())) {
1131 if (logger.isDebugEnabled()) {
1132 logger.debug("PropertyEditorRegistrar [" + registrar.getClass().getName() +
1133 "] failed because it tried to obtain currently created bean '" +
1134 ex.getBeanName() + "': " + ex.getMessage());
1135 }
1136 onSuppressedException(ex);
1137 continue;
1138 }
1139 }
1140 throw ex;
1141 }
1142 }
1143 }
1144 if (!this.customEditors.isEmpty()) {
1145 for (Map.Entry<Class<?>, Class<? extends PropertyEditor>> entry : this.customEditors.entrySet()) {
1146 Class<?> requiredType = entry.getKey();
1147 Class<? extends PropertyEditor> editorClass = entry.getValue();
1148 registry.registerCustomEditor(requiredType, BeanUtils.instantiateClass(editorClass));
1149 }
1150 }
1151 }
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162 protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
1163
1164 RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
1165 if (mbd != null) {
1166 return mbd;
1167 }
1168 return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
1169 }
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179 protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
1180 throws BeanDefinitionStoreException {
1181
1182 return getMergedBeanDefinition(beanName, bd, null);
1183 }
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195 protected RootBeanDefinition getMergedBeanDefinition(
1196 String beanName, BeanDefinition bd, BeanDefinition containingBd)
1197 throws BeanDefinitionStoreException {
1198
1199 synchronized (this.mergedBeanDefinitions) {
1200 RootBeanDefinition mbd = null;
1201
1202
1203 if (containingBd == null) {
1204 mbd = this.mergedBeanDefinitions.get(beanName);
1205 }
1206
1207 if (mbd == null) {
1208 if (bd.getParentName() == null) {
1209
1210 if (bd instanceof RootBeanDefinition) {
1211 mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
1212 }
1213 else {
1214 mbd = new RootBeanDefinition(bd);
1215 }
1216 }
1217 else {
1218
1219 BeanDefinition pbd;
1220 try {
1221 String parentBeanName = transformedBeanName(bd.getParentName());
1222 if (!beanName.equals(parentBeanName)) {
1223 pbd = getMergedBeanDefinition(parentBeanName);
1224 }
1225 else {
1226 if (getParentBeanFactory() instanceof ConfigurableBeanFactory) {
1227 pbd = ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(parentBeanName);
1228 }
1229 else {
1230 throw new NoSuchBeanDefinitionException(bd.getParentName(),
1231 "Parent name '" + bd.getParentName() + "' is equal to bean name '" + beanName +
1232 "': cannot be resolved without an AbstractBeanFactory parent");
1233 }
1234 }
1235 }
1236 catch (NoSuchBeanDefinitionException ex) {
1237 throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
1238 "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
1239 }
1240
1241 mbd = new RootBeanDefinition(pbd);
1242 mbd.overrideFrom(bd);
1243 }
1244
1245
1246 if (!StringUtils.hasLength(mbd.getScope())) {
1247 mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
1248 }
1249
1250
1251
1252
1253
1254 if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
1255 mbd.setScope(containingBd.getScope());
1256 }
1257
1258
1259
1260 if (containingBd == null && isCacheBeanMetadata() && isBeanEligibleForMetadataCaching(beanName)) {
1261 this.mergedBeanDefinitions.put(beanName, mbd);
1262 }
1263 }
1264
1265 return mbd;
1266 }
1267 }
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277 protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, Object[] args)
1278 throws BeanDefinitionStoreException {
1279
1280 if (mbd.isAbstract()) {
1281 throw new BeanIsAbstractException(beanName);
1282 }
1283 }
1284
1285
1286
1287
1288
1289
1290 protected void clearMergedBeanDefinition(String beanName) {
1291 this.mergedBeanDefinitions.remove(beanName);
1292 }
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305 protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch)
1306 throws CannotLoadBeanClassException {
1307 try {
1308 if (mbd.hasBeanClass()) {
1309 return mbd.getBeanClass();
1310 }
1311 if (System.getSecurityManager() != null) {
1312 return AccessController.doPrivileged(new PrivilegedExceptionAction<Class<?>>() {
1313 @Override
1314 public Class<?> run() throws Exception {
1315 return doResolveBeanClass(mbd, typesToMatch);
1316 }
1317 }, getAccessControlContext());
1318 }
1319 else {
1320 return doResolveBeanClass(mbd, typesToMatch);
1321 }
1322 }
1323 catch (PrivilegedActionException pae) {
1324 ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
1325 throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
1326 }
1327 catch (ClassNotFoundException ex) {
1328 throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
1329 }
1330 catch (LinkageError err) {
1331 throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
1332 }
1333 }
1334
1335 private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch) throws ClassNotFoundException {
1336 if (!ObjectUtils.isEmpty(typesToMatch)) {
1337 ClassLoader tempClassLoader = getTempClassLoader();
1338 if (tempClassLoader != null) {
1339 if (tempClassLoader instanceof DecoratingClassLoader) {
1340 DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
1341 for (Class<?> typeToMatch : typesToMatch) {
1342 dcl.excludeClass(typeToMatch.getName());
1343 }
1344 }
1345 String className = mbd.getBeanClassName();
1346 return (className != null ? ClassUtils.forName(className, tempClassLoader) : null);
1347 }
1348 }
1349 return mbd.resolveBeanClass(getBeanClassLoader());
1350 }
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360 protected Object evaluateBeanDefinitionString(String value, BeanDefinition beanDefinition) {
1361 if (this.beanExpressionResolver == null) {
1362 return value;
1363 }
1364 Scope scope = (beanDefinition != null ? getRegisteredScope(beanDefinition.getScope()) : null);
1365 return this.beanExpressionResolver.evaluate(value, new BeanExpressionContext(this, scope));
1366 }
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384 protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
1385 if (mbd.getFactoryMethodName() != null) {
1386 return null;
1387 }
1388 return resolveBeanClass(mbd, beanName, typesToMatch);
1389 }
1390
1391
1392
1393
1394
1395
1396 protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
1397 Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);
1398 return (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
1399 }
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416 protected Class<?> getTypeForFactoryBean(String beanName, RootBeanDefinition mbd) {
1417 if (!mbd.isSingleton()) {
1418 return null;
1419 }
1420 try {
1421 FactoryBean<?> factoryBean = doGetBean(FACTORY_BEAN_PREFIX + beanName, FactoryBean.class, null, true);
1422 return getTypeForFactoryBean(factoryBean);
1423 }
1424 catch (BeanCreationException ex) {
1425
1426 if (logger.isWarnEnabled()) {
1427 logger.warn("Bean creation exception on FactoryBean type check: " + ex);
1428 }
1429 onSuppressedException(ex);
1430 return null;
1431 }
1432 }
1433
1434
1435
1436
1437
1438
1439
1440 protected void markBeanAsCreated(String beanName) {
1441 if (!this.alreadyCreated.contains(beanName)) {
1442 this.alreadyCreated.add(beanName);
1443 }
1444 }
1445
1446
1447
1448
1449
1450 protected void cleanupAfterBeanCreationFailure(String beanName) {
1451 this.alreadyCreated.remove(beanName);
1452 }
1453
1454
1455
1456
1457
1458
1459
1460
1461 protected boolean isBeanEligibleForMetadataCaching(String beanName) {
1462 return this.alreadyCreated.contains(beanName);
1463 }
1464
1465
1466
1467
1468
1469
1470
1471 protected boolean removeSingletonIfCreatedForTypeCheckOnly(String beanName) {
1472 if (!this.alreadyCreated.contains(beanName)) {
1473 removeSingleton(beanName);
1474 return true;
1475 }
1476 else {
1477 return false;
1478 }
1479 }
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490 protected Object getObjectForBeanInstance(
1491 Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
1492
1493
1494 if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
1495 throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
1496 }
1497
1498
1499
1500
1501 if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
1502 return beanInstance;
1503 }
1504
1505 Object object = null;
1506 if (mbd == null) {
1507 object = getCachedObjectForFactoryBean(beanName);
1508 }
1509 if (object == null) {
1510
1511 FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
1512
1513 if (mbd == null && containsBeanDefinition(beanName)) {
1514 mbd = getMergedLocalBeanDefinition(beanName);
1515 }
1516 boolean synthetic = (mbd != null && mbd.isSynthetic());
1517 object = getObjectFromFactoryBean(factory, beanName, !synthetic);
1518 }
1519 return object;
1520 }
1521
1522
1523
1524
1525
1526
1527
1528 public boolean isBeanNameInUse(String beanName) {
1529 return isAlias(beanName) || containsLocalBean(beanName) || hasDependentBean(beanName);
1530 }
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542 protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
1543 return (bean != null &&
1544 (DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || hasDestructionAwareBeanPostProcessors()));
1545 }
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559 protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
1560 AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
1561 if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
1562 if (mbd.isSingleton()) {
1563
1564
1565
1566 registerDisposableBean(beanName,
1567 new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
1568 }
1569 else {
1570
1571 Scope scope = this.scopes.get(mbd.getScope());
1572 if (scope == null) {
1573 throw new IllegalStateException("No Scope registered for scope '" + mbd.getScope() + "'");
1574 }
1575 scope.registerDestructionCallback(beanName,
1576 new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
1577 }
1578 }
1579 }
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601 protected abstract boolean containsBeanDefinition(String beanName);
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622 protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeansException;
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635 protected abstract Object createBean(String beanName, RootBeanDefinition mbd, Object[] args)
1636 throws BeanCreationException;
1637
1638 }