Source Code Cross Referenced for AbstractAutowireCapableBeanFactory.java in  » J2EE » spring-framework-2.5 » org » springframework » beans » factory » support » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » spring framework 2.5 » org.springframework.beans.factory.support 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2002-2007 the original author or authors.
0003:         *
0004:         * Licensed under the Apache License, Version 2.0 (the "License");
0005:         * you may not use this file except in compliance with the License.
0006:         * You may obtain a copy of the License at
0007:         *
0008:         *      http://www.apache.org/licenses/LICENSE-2.0
0009:         *
0010:         * Unless required by applicable law or agreed to in writing, software
0011:         * distributed under the License is distributed on an "AS IS" BASIS,
0012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013:         * See the License for the specific language governing permissions and
0014:         * limitations under the License.
0015:         */
0016:
0017:        package org.springframework.beans.factory.support;
0018:
0019:        import java.beans.PropertyDescriptor;
0020:        import java.lang.reflect.Constructor;
0021:        import java.lang.reflect.InvocationTargetException;
0022:        import java.lang.reflect.Method;
0023:        import java.lang.reflect.Modifier;
0024:        import java.security.AccessController;
0025:        import java.security.PrivilegedAction;
0026:        import java.util.ArrayList;
0027:        import java.util.Arrays;
0028:        import java.util.Collection;
0029:        import java.util.HashMap;
0030:        import java.util.HashSet;
0031:        import java.util.Iterator;
0032:        import java.util.LinkedHashSet;
0033:        import java.util.LinkedList;
0034:        import java.util.List;
0035:        import java.util.Map;
0036:        import java.util.Set;
0037:        import java.util.TreeSet;
0038:
0039:        import org.springframework.beans.BeanUtils;
0040:        import org.springframework.beans.BeanWrapper;
0041:        import org.springframework.beans.BeanWrapperImpl;
0042:        import org.springframework.beans.BeansException;
0043:        import org.springframework.beans.FatalBeanException;
0044:        import org.springframework.beans.MutablePropertyValues;
0045:        import org.springframework.beans.PropertyAccessorUtils;
0046:        import org.springframework.beans.PropertyValue;
0047:        import org.springframework.beans.PropertyValues;
0048:        import org.springframework.beans.TypeConverter;
0049:        import org.springframework.beans.factory.BeanClassLoaderAware;
0050:        import org.springframework.beans.factory.BeanCreationException;
0051:        import org.springframework.beans.factory.BeanCurrentlyInCreationException;
0052:        import org.springframework.beans.factory.BeanDefinitionStoreException;
0053:        import org.springframework.beans.factory.BeanFactory;
0054:        import org.springframework.beans.factory.BeanFactoryAware;
0055:        import org.springframework.beans.factory.BeanNameAware;
0056:        import org.springframework.beans.factory.FactoryBean;
0057:        import org.springframework.beans.factory.InitializingBean;
0058:        import org.springframework.beans.factory.NoSuchBeanDefinitionException;
0059:        import org.springframework.beans.factory.UnsatisfiedDependencyException;
0060:        import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
0061:        import org.springframework.beans.factory.config.BeanDefinition;
0062:        import org.springframework.beans.factory.config.BeanPostProcessor;
0063:        import org.springframework.beans.factory.config.ConfigurableBeanFactory;
0064:        import org.springframework.beans.factory.config.DependencyDescriptor;
0065:        import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
0066:        import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
0067:        import org.springframework.beans.factory.config.TypedStringValue;
0068:        import org.springframework.core.MethodParameter;
0069:        import org.springframework.util.ClassUtils;
0070:        import org.springframework.util.ObjectUtils;
0071:        import org.springframework.util.ReflectionUtils;
0072:        import org.springframework.util.StringUtils;
0073:
0074:        /**
0075:         * Abstract bean factory superclass that implements default bean creation,
0076:         * with the full capabilities specified by the {@link RootBeanDefinition} class.
0077:         * Implements the {@link org.springframework.beans.factory.config.AutowireCapableBeanFactory}
0078:         * interface in addition to AbstractBeanFactory's {@link #createBean} method.
0079:         *
0080:         * <p>Provides bean creation (with constructor resolution), property population,
0081:         * wiring (including autowiring), and initialization. Handles runtime bean
0082:         * references, resolves managed collections, calls initialization methods, etc.
0083:         * Supports autowiring constructors, properties by name, and properties by type.
0084:         *
0085:         * <p>The main template method to be implemented by subclasses is
0086:         * {@link #findAutowireCandidates}, used for autowiring by type. In case of
0087:         * a factory which is capable of searching its bean definitions, matching
0088:         * beans will typically be implemented through such a search. For other
0089:         * factory styles, simplified matching algorithms can be implemented.
0090:         *
0091:         * <p>Note that this class does <i>not</i> assume or implement bean definition
0092:         * registry capabilities. See {@link DefaultListableBeanFactory} for an implementation
0093:         * of the {@link org.springframework.beans.factory.ListableBeanFactory} and
0094:         * {@link BeanDefinitionRegistry} interfaces, which represent the API and SPI
0095:         * view of such a factory, respectively.
0096:         *
0097:         * @author Rod Johnson
0098:         * @author Juergen Hoeller
0099:         * @author Rob Harrop
0100:         * @author Mark Fisher
0101:         * @since 13.02.2004
0102:         * @see RootBeanDefinition
0103:         * @see DefaultListableBeanFactory
0104:         * @see BeanDefinitionRegistry
0105:         */
0106:        public abstract class AbstractAutowireCapableBeanFactory extends
0107:                AbstractBeanFactory implements  AutowireCapableBeanFactory {
0108:
0109:            private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
0110:
0111:            /** Whether to automatically try to resolve circular references between beans */
0112:            private boolean allowCircularReferences = true;
0113:
0114:            /**
0115:             * Whether to resort to injecting a raw bean instance in case of circular reference,
0116:             * even if the injected bean eventually got wrapped.
0117:             */
0118:            private boolean allowRawInjectionDespiteWrapping = false;
0119:
0120:            /**
0121:             * Dependency types to ignore on dependency check and autowire, as Set of
0122:             * Class objects: for example, String. Default is none.
0123:             */
0124:            private final Set ignoredDependencyTypes = new HashSet();
0125:
0126:            /**
0127:             * Dependency interfaces to ignore on dependency check and autowire, as Set of
0128:             * Class objects. By default, only the BeanFactory interface is ignored.
0129:             */
0130:            private final Set ignoredDependencyInterfaces = new HashSet();
0131:
0132:            /** Cache of unfinished FactoryBean instances: FactoryBean name --> BeanWrapper */
0133:            private final Map factoryBeanInstanceCache = new HashMap();
0134:
0135:            /** Cache of filtered PropertyDescriptors: bean Class -> PropertyDescriptor array */
0136:            private final Map filteredPropertyDescriptorsCache = new HashMap();
0137:
0138:            /**
0139:             * Create a new AbstractAutowireCapableBeanFactory.
0140:             */
0141:            public AbstractAutowireCapableBeanFactory() {
0142:                super ();
0143:                ignoreDependencyInterface(BeanNameAware.class);
0144:                ignoreDependencyInterface(BeanFactoryAware.class);
0145:                ignoreDependencyInterface(BeanClassLoaderAware.class);
0146:            }
0147:
0148:            /**
0149:             * Create a new AbstractAutowireCapableBeanFactory with the given parent.
0150:             * @param parentBeanFactory parent bean factory, or <code>null</code> if none
0151:             */
0152:            public AbstractAutowireCapableBeanFactory(
0153:                    BeanFactory parentBeanFactory) {
0154:                this ();
0155:                setParentBeanFactory(parentBeanFactory);
0156:            }
0157:
0158:            /**
0159:             * Set the instantiation strategy to use for creating bean instances.
0160:             * Default is CglibSubclassingInstantiationStrategy.
0161:             * @see CglibSubclassingInstantiationStrategy
0162:             */
0163:            public void setInstantiationStrategy(
0164:                    InstantiationStrategy instantiationStrategy) {
0165:                this .instantiationStrategy = instantiationStrategy;
0166:            }
0167:
0168:            /**
0169:             * Return the instantiation strategy to use for creating bean instances.
0170:             */
0171:            protected InstantiationStrategy getInstantiationStrategy() {
0172:                return this .instantiationStrategy;
0173:            }
0174:
0175:            /**
0176:             * Set whether to allow circular references between beans - and automatically
0177:             * try to resolve them.
0178:             * <p>Note that circular reference resolution means that one of the involved beans
0179:             * will receive a reference to another bean that is not fully initialized yet.
0180:             * This can lead to subtle and not-so-subtle side effects on initialization;
0181:             * it does work fine for many scenarios, though.
0182:             * <p>Default is "true". Turn this off to throw an exception when encountering
0183:             * a circular reference, disallowing them completely.
0184:             * <p><b>NOTE:</b> It is generally recommended to not rely on circular references
0185:             * between your beans. Refactor your application logic to have the two beans
0186:             * involved delegate to a third bean that encapsulates their common logic.
0187:             */
0188:            public void setAllowCircularReferences(
0189:                    boolean allowCircularReferences) {
0190:                this .allowCircularReferences = allowCircularReferences;
0191:            }
0192:
0193:            /**
0194:             * Set whether to allow the raw injection of a bean instance into some other
0195:             * bean's property, despite the injected bean eventually getting wrapped
0196:             * (for example, through AOP auto-proxying).
0197:             * <p>This will only be used as a last resort in case of a circular reference
0198:             * that cannot be resolved otherwise: essentially, preferring a raw instance
0199:             * getting injected over a failure of the entire bean wiring process.
0200:             * <p>Default is "false", as of Spring 2.0. Turn this on to allow for non-wrapped
0201:             * raw beans injected into some of your references, which was Spring 1.2's
0202:             * (arguably unclean) default behavior.
0203:             * <p><b>NOTE:</b> It is generally recommended to not rely on circular references
0204:             * between your beans, in particular with auto-proxying involved.
0205:             * @see #setAllowCircularReferences
0206:             */
0207:            public void setAllowRawInjectionDespiteWrapping(
0208:                    boolean allowRawInjectionDespiteWrapping) {
0209:                this .allowRawInjectionDespiteWrapping = allowRawInjectionDespiteWrapping;
0210:            }
0211:
0212:            /**
0213:             * Ignore the given dependency type for autowiring:
0214:             * for example, String. Default is none.
0215:             */
0216:            public void ignoreDependencyType(Class type) {
0217:                this .ignoredDependencyTypes.add(type);
0218:            }
0219:
0220:            /**
0221:             * Ignore the given dependency interface for autowiring.
0222:             * <p>This will typically be used by application contexts to register
0223:             * dependencies that are resolved in other ways, like BeanFactory through
0224:             * BeanFactoryAware or ApplicationContext through ApplicationContextAware.
0225:             * <p>By default, only the BeanFactoryAware interface is ignored.
0226:             * For further types to ignore, invoke this method for each type.
0227:             * @see org.springframework.beans.factory.BeanFactoryAware
0228:             * @see org.springframework.context.ApplicationContextAware
0229:             */
0230:            public void ignoreDependencyInterface(Class ifc) {
0231:                this .ignoredDependencyInterfaces.add(ifc);
0232:            }
0233:
0234:            public void copyConfigurationFrom(
0235:                    ConfigurableBeanFactory otherFactory) {
0236:                super .copyConfigurationFrom(otherFactory);
0237:                if (otherFactory instanceof  AbstractAutowireCapableBeanFactory) {
0238:                    AbstractAutowireCapableBeanFactory otherAutowireFactory = (AbstractAutowireCapableBeanFactory) otherFactory;
0239:                    this .instantiationStrategy = otherAutowireFactory.instantiationStrategy;
0240:                    this .allowCircularReferences = otherAutowireFactory.allowCircularReferences;
0241:                    this .ignoredDependencyTypes
0242:                            .addAll(otherAutowireFactory.ignoredDependencyTypes);
0243:                    this .ignoredDependencyInterfaces
0244:                            .addAll(otherAutowireFactory.ignoredDependencyInterfaces);
0245:                }
0246:            }
0247:
0248:            //---------------------------------------------------------------------
0249:            // Implementation of AutowireCapableBeanFactory interface
0250:            //---------------------------------------------------------------------
0251:
0252:            public Object createBean(Class beanClass) throws BeansException {
0253:                // Use non-singleton bean definition, to avoid registering bean as dependent bean.
0254:                RootBeanDefinition bd = new RootBeanDefinition(beanClass, false);
0255:                return createBean(beanClass.getName(), bd, null);
0256:            }
0257:
0258:            public Object createBean(Class beanClass, int autowireMode,
0259:                    boolean dependencyCheck) throws BeansException {
0260:
0261:                // Use non-singleton bean definition, to avoid registering bean as dependent bean.
0262:                RootBeanDefinition bd = new RootBeanDefinition(beanClass,
0263:                        autowireMode, dependencyCheck);
0264:                bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
0265:                return createBean(beanClass.getName(), bd, null);
0266:            }
0267:
0268:            public Object autowire(Class beanClass, int autowireMode,
0269:                    boolean dependencyCheck) throws BeansException {
0270:
0271:                // Use non-singleton bean definition, to avoid registering bean as dependent bean.
0272:                RootBeanDefinition bd = new RootBeanDefinition(beanClass,
0273:                        autowireMode, dependencyCheck);
0274:                bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
0275:                if (bd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR) {
0276:                    return autowireConstructor(beanClass.getName(), bd, null,
0277:                            null).getWrappedInstance();
0278:                } else {
0279:                    Object bean = getInstantiationStrategy().instantiate(bd,
0280:                            null, this );
0281:                    populateBean(beanClass.getName(), bd, new BeanWrapperImpl(
0282:                            bean));
0283:                    return bean;
0284:                }
0285:            }
0286:
0287:            public void autowireBeanProperties(Object existingBean,
0288:                    int autowireMode, boolean dependencyCheck)
0289:                    throws BeansException {
0290:
0291:                if (autowireMode == AUTOWIRE_CONSTRUCTOR) {
0292:                    throw new IllegalArgumentException(
0293:                            "AUTOWIRE_CONSTRUCTOR not supported for existing bean instance");
0294:                }
0295:                // Use non-singleton bean definition, to avoid registering bean as dependent bean.
0296:                RootBeanDefinition bd = new RootBeanDefinition(ClassUtils
0297:                        .getUserClass(existingBean), autowireMode,
0298:                        dependencyCheck);
0299:                bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
0300:                populateBean(bd.getBeanClass().getName(), bd,
0301:                        new BeanWrapperImpl(existingBean));
0302:            }
0303:
0304:            public void applyBeanPropertyValues(Object existingBean,
0305:                    String beanName) throws BeansException {
0306:                BeanDefinition bd = getMergedBeanDefinition(beanName);
0307:                BeanWrapper bw = new BeanWrapperImpl(existingBean);
0308:                initBeanWrapper(bw);
0309:                applyPropertyValues(beanName, bd, bw, bd.getPropertyValues());
0310:            }
0311:
0312:            public Object configureBean(Object existingBean, String beanName)
0313:                    throws BeansException {
0314:                BeanDefinition bd = getMergedBeanDefinition(beanName);
0315:                if (!(bd instanceof  RootBeanDefinition)) {
0316:                    throw new BeanDefinitionStoreException(
0317:                            "configureBean only supported for a merged RootBeanDefinition");
0318:                }
0319:                RootBeanDefinition rbd = (RootBeanDefinition) bd;
0320:                BeanWrapper bw = new BeanWrapperImpl(existingBean);
0321:                initBeanWrapper(bw);
0322:                populateBean(beanName, rbd, bw);
0323:                return initializeBean(beanName, existingBean, rbd);
0324:            }
0325:
0326:            public Object initializeBean(Object existingBean, String beanName) {
0327:                return initializeBean(beanName, existingBean, null);
0328:            }
0329:
0330:            public Object applyBeanPostProcessorsBeforeInitialization(
0331:                    Object existingBean, String beanName) throws BeansException {
0332:
0333:                Object result = existingBean;
0334:                for (Iterator it = getBeanPostProcessors().iterator(); it
0335:                        .hasNext();) {
0336:                    BeanPostProcessor beanProcessor = (BeanPostProcessor) it
0337:                            .next();
0338:                    result = beanProcessor.postProcessBeforeInitialization(
0339:                            result, beanName);
0340:                }
0341:                return result;
0342:            }
0343:
0344:            public Object applyBeanPostProcessorsAfterInitialization(
0345:                    Object existingBean, String beanName) throws BeansException {
0346:
0347:                Object result = existingBean;
0348:                for (Iterator it = getBeanPostProcessors().iterator(); it
0349:                        .hasNext();) {
0350:                    BeanPostProcessor beanProcessor = (BeanPostProcessor) it
0351:                            .next();
0352:                    result = beanProcessor.postProcessAfterInitialization(
0353:                            result, beanName);
0354:                }
0355:                return result;
0356:            }
0357:
0358:            public Object resolveDependency(DependencyDescriptor descriptor,
0359:                    String beanName) throws BeansException {
0360:                return resolveDependency(descriptor, beanName, null, null);
0361:            }
0362:
0363:            public Object resolveDependency(DependencyDescriptor descriptor,
0364:                    String beanName, Set autowiredBeanNames,
0365:                    TypeConverter typeConverter) throws BeansException {
0366:
0367:                Class type = descriptor.getDependencyType();
0368:                if (type.isArray()) {
0369:                    Class componentType = type.getComponentType();
0370:                    Map matchingBeans = findAutowireCandidates(beanName,
0371:                            componentType, descriptor);
0372:                    if (matchingBeans.isEmpty()) {
0373:                        if (descriptor.isRequired()) {
0374:                            throw new NoSuchBeanDefinitionException(
0375:                                    componentType,
0376:                                    "Unsatisfied dependency of type ["
0377:                                            + componentType
0378:                                            + "]: expected at least 1 matching bean");
0379:                        }
0380:                        return null;
0381:                    }
0382:                    if (autowiredBeanNames != null) {
0383:                        autowiredBeanNames.addAll(matchingBeans.keySet());
0384:                    }
0385:                    TypeConverter converter = (typeConverter != null ? typeConverter
0386:                            : getTypeConverter());
0387:                    return converter.convertIfNecessary(matchingBeans.values(),
0388:                            type);
0389:                } else if (Collection.class.isAssignableFrom(type)
0390:                        && type.isInterface()) {
0391:                    Class elementType = descriptor.getCollectionType();
0392:                    if (elementType == null) {
0393:                        if (descriptor.isRequired()) {
0394:                            throw new FatalBeanException(
0395:                                    "No element type declared for collection");
0396:                        }
0397:                        return null;
0398:                    }
0399:                    Map matchingBeans = findAutowireCandidates(beanName,
0400:                            elementType, descriptor);
0401:                    if (matchingBeans.isEmpty()) {
0402:                        if (descriptor.isRequired()) {
0403:                            throw new NoSuchBeanDefinitionException(
0404:                                    elementType,
0405:                                    "Unsatisfied dependency of type ["
0406:                                            + elementType.getName()
0407:                                            + "]: expected at least 1 matching bean");
0408:                        }
0409:                        return null;
0410:                    }
0411:                    if (autowiredBeanNames != null) {
0412:                        autowiredBeanNames.addAll(matchingBeans.keySet());
0413:                    }
0414:                    TypeConverter converter = (typeConverter != null ? typeConverter
0415:                            : getTypeConverter());
0416:                    return converter.convertIfNecessary(matchingBeans.values(),
0417:                            type);
0418:                } else if (Map.class.isAssignableFrom(type)
0419:                        && type.isInterface()) {
0420:                    Class keyType = descriptor.getMapKeyType();
0421:                    if (keyType == null
0422:                            || !String.class.isAssignableFrom(keyType)) {
0423:                        if (descriptor.isRequired()) {
0424:                            throw new FatalBeanException(
0425:                                    "Map key type must be assignable to ["
0426:                                            + String.class.getName() + "]");
0427:                        }
0428:                        return null;
0429:                    }
0430:                    Class valueType = descriptor.getMapValueType();
0431:                    if (valueType == null) {
0432:                        if (descriptor.isRequired()) {
0433:                            throw new FatalBeanException(
0434:                                    "No value type declared for map");
0435:                        }
0436:                        return null;
0437:                    }
0438:                    Map matchingBeans = findAutowireCandidates(beanName,
0439:                            valueType, descriptor);
0440:                    if (matchingBeans.isEmpty()) {
0441:                        if (descriptor.isRequired()) {
0442:                            throw new NoSuchBeanDefinitionException(
0443:                                    valueType,
0444:                                    "Unsatisfied dependency of type ["
0445:                                            + valueType.getName()
0446:                                            + "]: expected at least 1 matching bean");
0447:                        }
0448:                        return null;
0449:                    }
0450:                    if (autowiredBeanNames != null) {
0451:                        autowiredBeanNames.addAll(matchingBeans.keySet());
0452:                    }
0453:                    return matchingBeans;
0454:                } else {
0455:                    Map matchingBeans = findAutowireCandidates(beanName, type,
0456:                            descriptor);
0457:                    if (matchingBeans.isEmpty()) {
0458:                        if (descriptor.isRequired()) {
0459:                            throw new NoSuchBeanDefinitionException(
0460:                                    type,
0461:                                    "Unsatisfied dependency of type ["
0462:                                            + type
0463:                                            + "]: expected at least 1 matching bean");
0464:                        }
0465:                        return null;
0466:                    }
0467:                    if (matchingBeans.size() > 1) {
0468:                        String primaryBeanName = determinePrimaryCandidate(
0469:                                matchingBeans, type);
0470:                        if (primaryBeanName == null) {
0471:                            throw new NoSuchBeanDefinitionException(type,
0472:                                    "expected single matching bean but found "
0473:                                            + matchingBeans.size() + ": "
0474:                                            + matchingBeans.keySet());
0475:                        }
0476:                        if (autowiredBeanNames != null) {
0477:                            autowiredBeanNames.add(primaryBeanName);
0478:                        }
0479:                        return matchingBeans.get(primaryBeanName);
0480:                    }
0481:                    // We have exactly one match.
0482:                    Map.Entry entry = (Map.Entry) matchingBeans.entrySet()
0483:                            .iterator().next();
0484:                    if (autowiredBeanNames != null) {
0485:                        autowiredBeanNames.add(entry.getKey());
0486:                    }
0487:                    return entry.getValue();
0488:                }
0489:            }
0490:
0491:            //---------------------------------------------------------------------
0492:            // Implementation of relevant AbstractBeanFactory template methods
0493:            //---------------------------------------------------------------------
0494:
0495:            /**
0496:             * Central method of this class: creates a bean instance,
0497:             * populates the bean instance, applies post-processors, etc.
0498:             * @see #doCreateBean
0499:             */
0500:            protected Object createBean(final String beanName,
0501:                    final RootBeanDefinition mbd, final Object[] args)
0502:                    throws BeanCreationException {
0503:
0504:                return AccessController.doPrivileged(new PrivilegedAction() {
0505:                    public Object run() {
0506:                        if (logger.isDebugEnabled()) {
0507:                            logger.debug("Creating instance of bean '"
0508:                                    + beanName + "' with merged definition ["
0509:                                    + mbd + "]");
0510:                        }
0511:
0512:                        // Make sure bean class is actually resolved at this point.
0513:                        resolveBeanClass(mbd, beanName);
0514:
0515:                        // Prepare method overrides.
0516:                        try {
0517:                            mbd.prepareMethodOverrides();
0518:                        } catch (BeanDefinitionValidationException ex) {
0519:                            throw new BeanDefinitionStoreException(mbd
0520:                                    .getResourceDescription(), beanName,
0521:                                    "Validation of method overrides failed", ex);
0522:                        }
0523:
0524:                        try {
0525:                            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
0526:                            Object bean = resolveBeforeInstantiation(beanName,
0527:                                    mbd);
0528:                            if (bean != null) {
0529:                                return bean;
0530:                            }
0531:                        } catch (Throwable ex) {
0532:                            throw new BeanCreationException(
0533:                                    mbd.getResourceDescription(),
0534:                                    beanName,
0535:                                    "BeanPostProcessor before instantiation of bean failed",
0536:                                    ex);
0537:                        }
0538:
0539:                        return doCreateBean(beanName, mbd, args);
0540:                    }
0541:                });
0542:            }
0543:
0544:            /**
0545:             * Actually create the specified bean. Pre-creation processing has already happened
0546:             * at this point, e.g. checking <code>postProcessBeforeInstantiation</code> callbacks.
0547:             * <p>Differentiates between default bean instantiation, use of a
0548:             * factory method, and autowiring a constructor.
0549:             * @param beanName the name of the bean
0550:             * @param mbd the merged bean definition for the bean
0551:             * @param args arguments to use if creating a prototype using explicit arguments to a
0552:             * static factory method. This parameter must be <code>null</code> except in this case.
0553:             * @return a new instance of the bean
0554:             * @throws BeanCreationException if the bean could not be created
0555:             * @see #instantiateBean
0556:             * @see #instantiateUsingFactoryMethod
0557:             * @see #autowireConstructor
0558:             */
0559:            protected Object doCreateBean(String beanName,
0560:                    RootBeanDefinition mbd, Object[] args) {
0561:                // Instantiate the bean.
0562:                BeanWrapper instanceWrapper = null;
0563:                if (mbd.isSingleton()) {
0564:                    synchronized (getSingletonMutex()) {
0565:                        instanceWrapper = (BeanWrapper) this .factoryBeanInstanceCache
0566:                                .remove(beanName);
0567:                    }
0568:                }
0569:                if (instanceWrapper == null) {
0570:                    instanceWrapper = createBeanInstance(beanName, mbd, args);
0571:                }
0572:                Object bean = (instanceWrapper != null ? instanceWrapper
0573:                        .getWrappedInstance() : null);
0574:                Class beanType = (instanceWrapper != null ? instanceWrapper
0575:                        .getWrappedClass() : null);
0576:
0577:                // Allow post-processors to modify the merged bean definition.
0578:                if (!mbd.postProcessed) {
0579:                    applyMergedBeanDefinitionPostProcessors(mbd, beanType,
0580:                            beanName);
0581:                    mbd.postProcessed = true;
0582:                }
0583:
0584:                // Eagerly cache singletons to be able to resolve circular references
0585:                // even when triggered by lifecycle interfaces like BeanFactoryAware.
0586:                if (mbd.isSingleton() && this .allowCircularReferences
0587:                        && isSingletonCurrentlyInCreation(beanName)) {
0588:                    if (logger.isDebugEnabled()) {
0589:                        logger
0590:                                .debug("Eagerly caching bean '"
0591:                                        + beanName
0592:                                        + "' to allow for resolving potential circular references");
0593:                    }
0594:                    addSingleton(beanName, bean);
0595:                }
0596:
0597:                // Initialize the bean instance.
0598:                Object originalBean = bean;
0599:                try {
0600:                    populateBean(beanName, mbd, instanceWrapper);
0601:                    bean = initializeBean(beanName, bean, mbd);
0602:                } catch (Throwable ex) {
0603:                    if (ex instanceof  BeanCreationException
0604:                            && beanName.equals(((BeanCreationException) ex)
0605:                                    .getBeanName())) {
0606:                        throw (BeanCreationException) ex;
0607:                    } else {
0608:                        throw new BeanCreationException(mbd
0609:                                .getResourceDescription(), beanName,
0610:                                "Initialization of bean failed", ex);
0611:                    }
0612:                }
0613:
0614:                if (!this .allowRawInjectionDespiteWrapping
0615:                        && originalBean != bean && mbd.isSingleton()
0616:                        && hasDependentBean(beanName)) {
0617:                    throw new BeanCurrentlyInCreationException(
0618:                            beanName,
0619:                            "Bean with name '"
0620:                                    + beanName
0621:                                    + "' has been injected into other beans ["
0622:                                    + StringUtils
0623:                                            .arrayToCommaDelimitedString(getDependentBeans(beanName))
0624:                                    + "] in its raw version as part of a circular reference, but has eventually "
0625:                                    + "been wrapped (for example as part of auto-proxy creation). "
0626:                                    + "This means that said other beans do not use the final version of the bean. "
0627:                                    + "This is often the result of over-eager type matching - consider using "
0628:                                    + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
0629:                }
0630:
0631:                // Register bean as disposable.
0632:                registerDisposableBeanIfNecessary(beanName, originalBean, mbd);
0633:
0634:                return bean;
0635:            }
0636:
0637:            /**
0638:             * Predict the eventual bean type for the given bean.
0639:             * @param beanName the name of the bean
0640:             * @param mbd the merged bean definition to determine the type for
0641:             * @return the type of the bean, or <code>null</code> if not predictable
0642:             */
0643:            protected Class predictBeanType(String beanName,
0644:                    RootBeanDefinition mbd, boolean typeMatchOnly) {
0645:                Class beanClass = null;
0646:                if (mbd.getFactoryMethodName() != null) {
0647:                    beanClass = getTypeForFactoryMethod(beanName, mbd,
0648:                            typeMatchOnly);
0649:                } else {
0650:                    beanClass = resolveBeanClass(mbd, beanName, typeMatchOnly);
0651:                }
0652:                // Apply SmartInstantiationAwareBeanPostProcessors to predict the
0653:                // eventual type after a before-instantiation shortcut.
0654:                if (!mbd.isSynthetic()
0655:                        && hasInstantiationAwareBeanPostProcessors()) {
0656:                    for (Iterator it = getBeanPostProcessors().iterator(); it
0657:                            .hasNext();) {
0658:                        BeanPostProcessor bp = (BeanPostProcessor) it.next();
0659:                        if (bp instanceof  SmartInstantiationAwareBeanPostProcessor) {
0660:                            SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
0661:                            Class processedType = ibp.predictBeanType(
0662:                                    beanClass, beanName);
0663:                            if (processedType != null) {
0664:                                return processedType;
0665:                            }
0666:                        }
0667:                    }
0668:                }
0669:                return beanClass;
0670:            }
0671:
0672:            /**
0673:             * Determine the bean type for the given bean definition which is based on
0674:             * a factory method. Only called if there is no singleton instance registered
0675:             * for the target bean already.
0676:             * <p>This implementation determines the type matching {@link #createBean}'s
0677:             * different creation strategies. As far as possible, we'll perform static
0678:             * type checking to avoid creation of the target bean.
0679:             * @param beanName the name of the bean (for error handling purposes)
0680:             * @param mbd the merged bean definition for the bean
0681:             * @param typeMatchOnly whether the returned {@link Class} is only used
0682:             * for internal type matching purposes (that is, never exposed to application code)
0683:             * @return the type for the bean if determinable, or <code>null</code> else
0684:             * @see #createBean
0685:             */
0686:            protected Class getTypeForFactoryMethod(String beanName,
0687:                    RootBeanDefinition mbd, boolean typeMatchOnly) {
0688:                Class factoryClass = null;
0689:                boolean isStatic = true;
0690:
0691:                if (mbd.getFactoryBeanName() != null) {
0692:                    // Check declared factory method return type on factory class.
0693:                    factoryClass = getType(mbd.getFactoryBeanName());
0694:                    isStatic = false;
0695:                } else {
0696:                    // Check declared factory method return type on bean class.
0697:                    factoryClass = resolveBeanClass(mbd, beanName,
0698:                            typeMatchOnly);
0699:                }
0700:
0701:                if (factoryClass == null) {
0702:                    return null;
0703:                }
0704:
0705:                // If all factory methods have the same return type, return that type.
0706:                // Can't clearly figure out exact method due to type converting / autowiring!
0707:                int minNrOfArgs = mbd.getConstructorArgumentValues()
0708:                        .getArgumentCount();
0709:                Method[] candidates = ReflectionUtils
0710:                        .getAllDeclaredMethods(factoryClass);
0711:                Set returnTypes = new HashSet(1);
0712:                for (int i = 0; i < candidates.length; i++) {
0713:                    Method factoryMethod = candidates[i];
0714:                    if (Modifier.isStatic(factoryMethod.getModifiers()) == isStatic
0715:                            && factoryMethod.getName().equals(
0716:                                    mbd.getFactoryMethodName())
0717:                            && factoryMethod.getParameterTypes().length >= minNrOfArgs) {
0718:                        returnTypes.add(factoryMethod.getReturnType());
0719:                    }
0720:                }
0721:
0722:                if (returnTypes.size() == 1) {
0723:                    // Clear return type found: all factory methods return same type.
0724:                    return (Class) returnTypes.iterator().next();
0725:                } else {
0726:                    // Ambiguous return types found: return null to indicate "not determinable".
0727:                    return null;
0728:                }
0729:            }
0730:
0731:            /**
0732:             * This implementation checks the FactoryBean's <code>getObjectType</code> method
0733:             * on a plain instance of the FactoryBean, without bean properties applied yet.
0734:             * If this doesn't return a type yet, a full creation of the FactoryBean is
0735:             * used as fallback (through delegation to the superclass's implementation).
0736:             * <p>The shortcut check for a FactoryBean is only applied in case of a singleton
0737:             * FactoryBean. If the FactoryBean instance itself is not kept as singleton,
0738:             * it will be fully created to check the type of its exposed object.
0739:             */
0740:            protected Class getTypeForFactoryBean(String beanName,
0741:                    RootBeanDefinition mbd) {
0742:                FactoryBean fb = (mbd.isSingleton() ? getSingletonFactoryBeanForTypeCheck(
0743:                        beanName, mbd)
0744:                        : getNonSingletonFactoryBeanForTypeCheck(beanName, mbd));
0745:
0746:                if (fb != null) {
0747:                    // Try to obtain the FactoryBean's object type from this early stage of the instance.
0748:                    Class objectType = getTypeForFactoryBean(fb);
0749:                    if (objectType != null) {
0750:                        return objectType;
0751:                    }
0752:                }
0753:
0754:                // No type found - fall back to full creation of the FactoryBean instance.
0755:                return super .getTypeForFactoryBean(beanName, mbd);
0756:            }
0757:
0758:            //---------------------------------------------------------------------
0759:            // Implementation methods
0760:            //---------------------------------------------------------------------
0761:
0762:            /**
0763:             * Obtain a "shortcut" singleton FactoryBean instance to use for a
0764:             * <code>getObjectType()</code> call, without full initialization
0765:             * of the FactoryBean.
0766:             * @param beanName the name of the bean
0767:             * @param mbd the bean definition for the bean
0768:             * @return the FactoryBean instance, or <code>null</code> to indicate
0769:             * that we couldn't obtain a shortcut FactoryBean instance
0770:             */
0771:            private FactoryBean getSingletonFactoryBeanForTypeCheck(
0772:                    String beanName, RootBeanDefinition mbd) {
0773:                synchronized (getSingletonMutex()) {
0774:                    BeanWrapper bw = (BeanWrapper) this .factoryBeanInstanceCache
0775:                            .get(beanName);
0776:                    if (bw != null) {
0777:                        return (FactoryBean) bw.getWrappedInstance();
0778:                    }
0779:                    if (isSingletonCurrentlyInCreation(beanName)) {
0780:                        return null;
0781:                    }
0782:                    Object instance = null;
0783:                    try {
0784:                        // Mark this bean as currently in creation, even if just partially.
0785:                        beforeSingletonCreation(beanName);
0786:                        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
0787:                        instance = resolveBeforeInstantiation(beanName, mbd);
0788:                        if (instance == null) {
0789:                            bw = createBeanInstance(beanName, mbd, null);
0790:                            instance = bw.getWrappedInstance();
0791:                        }
0792:                    } finally {
0793:                        // Finished partial creation of this bean.
0794:                        afterSingletonCreation(beanName);
0795:                    }
0796:                    if (!(instance instanceof  FactoryBean)) {
0797:                        throw new BeanCreationException(beanName,
0798:                                "Bean instance of type [" + instance.getClass()
0799:                                        + "] is not a FactoryBean");
0800:                    }
0801:                    if (bw != null) {
0802:                        this .factoryBeanInstanceCache.put(beanName, bw);
0803:                    }
0804:                    return (FactoryBean) instance;
0805:                }
0806:            }
0807:
0808:            /**
0809:             * Obtain a "shortcut" non-singleton FactoryBean instance to use for a
0810:             * <code>getObjectType()</code> call, without full initialization
0811:             * of the FactoryBean.
0812:             * @param beanName the name of the bean
0813:             * @param mbd the bean definition for the bean
0814:             * @return the FactoryBean instance, or <code>null</code> to indicate
0815:             * that we couldn't obtain a shortcut FactoryBean instance
0816:             */
0817:            private FactoryBean getNonSingletonFactoryBeanForTypeCheck(
0818:                    String beanName, RootBeanDefinition mbd) {
0819:                if (isPrototypeCurrentlyInCreation(beanName)) {
0820:                    return null;
0821:                }
0822:                Object instance = null;
0823:                try {
0824:                    // Mark this bean as currently in creation, even if just partially.
0825:                    beforePrototypeCreation(beanName);
0826:                    // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
0827:                    instance = resolveBeforeInstantiation(beanName, mbd);
0828:                    if (instance == null) {
0829:                        BeanWrapper bw = createBeanInstance(beanName, mbd, null);
0830:                        instance = bw.getWrappedInstance();
0831:                    }
0832:                } finally {
0833:                    // Finished partial creation of this bean.
0834:                    afterPrototypeCreation(beanName);
0835:                }
0836:                if (!(instance instanceof  FactoryBean)) {
0837:                    throw new BeanCreationException(beanName,
0838:                            "Bean instance of type [" + instance.getClass()
0839:                                    + "] is not a FactoryBean");
0840:                }
0841:                return (FactoryBean) instance;
0842:            }
0843:
0844:            /**
0845:             * Apply MergedBeanDefinitionPostProcessors to the specified bean definition,
0846:             * invoking their <code>postProcessMergedBeanDefinition</code> methods.
0847:             * @param mbd the merged bean definition for the bean
0848:             * @param beanType the actual type of the managed bean instance
0849:             * @param beanName the name of the bean
0850:             * @throws BeansException if any post-processing failed
0851:             * @see MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
0852:             */
0853:            protected void applyMergedBeanDefinitionPostProcessors(
0854:                    RootBeanDefinition mbd, Class beanType, String beanName)
0855:                    throws BeansException {
0856:
0857:                for (Iterator it = getBeanPostProcessors().iterator(); it
0858:                        .hasNext();) {
0859:                    BeanPostProcessor beanProcessor = (BeanPostProcessor) it
0860:                            .next();
0861:                    if (beanProcessor instanceof  MergedBeanDefinitionPostProcessor) {
0862:                        MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) beanProcessor;
0863:                        bdp.postProcessMergedBeanDefinition(mbd, beanType,
0864:                                beanName);
0865:                    }
0866:                }
0867:            }
0868:
0869:            /**
0870:             * Apply before-instantiation post-processors, resolving whether there is a
0871:             * before-instantiation shortcut for the specified bean.
0872:             * @param beanName the name of the bean
0873:             * @param mbd the bean definition for the bean
0874:             * @return the shortcut-determined bean instance, or <code>null</code> if none
0875:             */
0876:            protected Object resolveBeforeInstantiation(String beanName,
0877:                    RootBeanDefinition mbd) {
0878:                Object bean = null;
0879:                if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
0880:                    // Make sure bean class is actually resolved at this point.
0881:                    if (mbd.hasBeanClass() && !mbd.isSynthetic()
0882:                            && hasInstantiationAwareBeanPostProcessors()) {
0883:                        bean = applyBeanPostProcessorsBeforeInstantiation(mbd
0884:                                .getBeanClass(), beanName);
0885:                        if (bean != null) {
0886:                            bean = applyBeanPostProcessorsAfterInitialization(
0887:                                    bean, beanName);
0888:                        }
0889:                    }
0890:                    mbd.beforeInstantiationResolved = Boolean
0891:                            .valueOf(bean != null);
0892:                }
0893:                return bean;
0894:            }
0895:
0896:            /**
0897:             * Apply InstantiationAwareBeanPostProcessors to the specified bean definition
0898:             * (by class and name), invoking their <code>postProcessBeforeInstantiation</code> methods.
0899:             * <p>Any returned object will be used as the bean instead of actually instantiating
0900:             * the target bean. A <code>null</code> return value from the post-processor will
0901:             * result in the target bean being instantiated.
0902:             * @param beanClass the class of the bean to be instantiated
0903:             * @param beanName the name of the bean
0904:             * @return the bean object to use instead of a default instance of the target bean, or <code>null</code>
0905:             * @throws BeansException if any post-processing failed
0906:             * @see InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
0907:             */
0908:            protected Object applyBeanPostProcessorsBeforeInstantiation(
0909:                    Class beanClass, String beanName) throws BeansException {
0910:
0911:                for (Iterator it = getBeanPostProcessors().iterator(); it
0912:                        .hasNext();) {
0913:                    BeanPostProcessor beanProcessor = (BeanPostProcessor) it
0914:                            .next();
0915:                    if (beanProcessor instanceof  InstantiationAwareBeanPostProcessor) {
0916:                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) beanProcessor;
0917:                        Object result = ibp.postProcessBeforeInstantiation(
0918:                                beanClass, beanName);
0919:                        if (result != null) {
0920:                            return result;
0921:                        }
0922:                    }
0923:                }
0924:                return null;
0925:            }
0926:
0927:            /**
0928:             * Create a new instance for the specified bean, using an appropriate instantiation strategy:
0929:             * factory method, constructor autowiring, or simple instantiation.
0930:             * @param beanName the name of the bean
0931:             * @param mbd the bean definition for the bean
0932:             * @param args arguments to use if creating a prototype using explicit arguments to a
0933:             * static factory method. It is invalid to use a non-null args value in any other case.
0934:             * @return BeanWrapper for the new instance
0935:             * @see #instantiateUsingFactoryMethod
0936:             * @see #autowireConstructor
0937:             * @see #instantiateBean
0938:             */
0939:            protected BeanWrapper createBeanInstance(String beanName,
0940:                    RootBeanDefinition mbd, Object[] args) {
0941:                if (mbd.getFactoryMethodName() != null) {
0942:                    return instantiateUsingFactoryMethod(beanName, mbd, args);
0943:                }
0944:
0945:                // Shortcut when re-creating the same bean...
0946:                if (mbd.resolvedConstructorOrFactoryMethod != null) {
0947:                    if (mbd.constructorArgumentsResolved) {
0948:                        return autowireConstructor(beanName, mbd, null, args);
0949:                    } else {
0950:                        return instantiateBean(beanName, mbd);
0951:                    }
0952:                }
0953:
0954:                // Need to determine the constructor...
0955:                Constructor[] ctors = determineConstructorsFromBeanPostProcessors(
0956:                        mbd.getBeanClass(), beanName);
0957:                if (ctors != null
0958:                        || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR
0959:                        || mbd.hasConstructorArgumentValues()
0960:                        || !ObjectUtils.isEmpty(args)) {
0961:                    return autowireConstructor(beanName, mbd, ctors, args);
0962:                }
0963:
0964:                // No special handling: simply use no-arg constructor.
0965:                return instantiateBean(beanName, mbd);
0966:            }
0967:
0968:            /**
0969:             * Determine candidate constructors to use for the given bean, checking all registered
0970:             * {@link SmartInstantiationAwareBeanPostProcessor SmartInstantiationAwareBeanPostProcessors}.
0971:             * @param beanClass the raw class of the bean
0972:             * @param beanName the name of the bean
0973:             * @return the candidate constructors, or <code>null</code> if none specified
0974:             * @throws org.springframework.beans.BeansException in case of errors
0975:             * @see org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors
0976:             */
0977:            protected Constructor[] determineConstructorsFromBeanPostProcessors(
0978:                    Class beanClass, String beanName) throws BeansException {
0979:
0980:                if (hasInstantiationAwareBeanPostProcessors()) {
0981:                    for (Iterator it = getBeanPostProcessors().iterator(); it
0982:                            .hasNext();) {
0983:                        BeanPostProcessor beanProcessor = (BeanPostProcessor) it
0984:                                .next();
0985:                        if (beanProcessor instanceof  SmartInstantiationAwareBeanPostProcessor) {
0986:                            SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) beanProcessor;
0987:                            Constructor[] ctors = ibp
0988:                                    .determineCandidateConstructors(beanClass,
0989:                                            beanName);
0990:                            if (ctors != null) {
0991:                                return ctors;
0992:                            }
0993:                        }
0994:                    }
0995:                }
0996:                return null;
0997:            }
0998:
0999:            /**
1000:             * Instantiate the given bean using its default constructor.
1001:             * @param beanName the name of the bean
1002:             * @param mbd the bean definition for the bean
1003:             * @return BeanWrapper for the new instance
1004:             */
1005:            protected BeanWrapper instantiateBean(String beanName,
1006:                    RootBeanDefinition mbd) {
1007:                try {
1008:                    Object beanInstance = getInstantiationStrategy()
1009:                            .instantiate(mbd, beanName, this );
1010:                    BeanWrapper bw = new BeanWrapperImpl(beanInstance);
1011:                    initBeanWrapper(bw);
1012:                    return bw;
1013:                } catch (Throwable ex) {
1014:                    throw new BeanCreationException(mbd
1015:                            .getResourceDescription(), beanName,
1016:                            "Instantiation of bean failed", ex);
1017:                }
1018:            }
1019:
1020:            /**
1021:             * Instantiate the bean using a named factory method. The method may be static, if the
1022:             * mbd parameter specifies a class, rather than a factoryBean, or an instance variable
1023:             * on a factory object itself configured using Dependency Injection.
1024:             * @param beanName the name of the bean
1025:             * @param mbd the bean definition for the bean
1026:             * @param explicitArgs argument values passed in programmatically via the getBean method,
1027:             * or <code>null</code> if none (-> use constructor argument values from bean definition)
1028:             * @return BeanWrapper for the new instance
1029:             * @see #getBean(String, Object[])
1030:             */
1031:            protected BeanWrapper instantiateUsingFactoryMethod(
1032:                    String beanName, RootBeanDefinition mbd,
1033:                    Object[] explicitArgs) {
1034:
1035:                ConstructorResolver constructorResolver = new ConstructorResolverAdapter();
1036:                return constructorResolver.instantiateUsingFactoryMethod(
1037:                        beanName, mbd, explicitArgs);
1038:            }
1039:
1040:            /**
1041:             * "autowire constructor" (with constructor arguments by type) behavior.
1042:             * Also applied if explicit constructor argument values are specified,
1043:             * matching all remaining arguments with beans from the bean factory.
1044:             * <p>This corresponds to constructor injection: In this mode, a Spring
1045:             * bean factory is able to host components that expect constructor-based
1046:             * dependency resolution.
1047:             * @param beanName the name of the bean
1048:             * @param mbd the bean definition for the bean
1049:             * @param ctors the chosen candidate constructors
1050:             * @param explicitArgs argument values passed in programmatically via the getBean method,
1051:             * or <code>null</code> if none (-> use constructor argument values from bean definition)
1052:             * @return BeanWrapper for the new instance
1053:             */
1054:            protected BeanWrapper autowireConstructor(String beanName,
1055:                    RootBeanDefinition mbd, Constructor[] ctors,
1056:                    Object[] explicitArgs) {
1057:
1058:                ConstructorResolver constructorResolver = new ConstructorResolverAdapter();
1059:                return constructorResolver.autowireConstructor(beanName, mbd,
1060:                        ctors, explicitArgs);
1061:            }
1062:
1063:            /**
1064:             * Populate the bean instance in the given BeanWrapper with the property values
1065:             * from the bean definition.
1066:             * @param beanName the name of the bean
1067:             * @param mbd the bean definition for the bean
1068:             * @param bw BeanWrapper with bean instance
1069:             */
1070:            protected void populateBean(String beanName,
1071:                    AbstractBeanDefinition mbd, BeanWrapper bw) {
1072:                // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
1073:                // state of the bean before properties are set. This can be used, for example,
1074:                // to support styles of field injection.
1075:                boolean continueWithPropertyPopulation = true;
1076:
1077:                if (!mbd.isSynthetic()
1078:                        && hasInstantiationAwareBeanPostProcessors()) {
1079:                    for (Iterator it = getBeanPostProcessors().iterator(); it
1080:                            .hasNext();) {
1081:                        BeanPostProcessor beanProcessor = (BeanPostProcessor) it
1082:                                .next();
1083:                        if (beanProcessor instanceof  InstantiationAwareBeanPostProcessor) {
1084:                            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) beanProcessor;
1085:                            if (!ibp.postProcessAfterInstantiation(bw
1086:                                    .getWrappedInstance(), beanName)) {
1087:                                continueWithPropertyPopulation = false;
1088:                                break;
1089:                            }
1090:                        }
1091:                    }
1092:                }
1093:
1094:                if (!continueWithPropertyPopulation) {
1095:                    return;
1096:                }
1097:
1098:                PropertyValues pvs = mbd.getPropertyValues();
1099:
1100:                if (bw == null) {
1101:                    if (!pvs.isEmpty()) {
1102:                        throw new BeanCreationException(mbd
1103:                                .getResourceDescription(), beanName,
1104:                                "Cannot apply property values to null instance");
1105:                    } else {
1106:                        // Skip property population phase for null instance.
1107:                        return;
1108:                    }
1109:                }
1110:
1111:                if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME
1112:                        || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
1113:                    MutablePropertyValues newPvs = new MutablePropertyValues(
1114:                            pvs);
1115:
1116:                    // Add property values based on autowire by name if applicable.
1117:                    if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
1118:                        autowireByName(beanName, mbd, bw, newPvs);
1119:                    }
1120:
1121:                    // Add property values based on autowire by type if applicable.
1122:                    if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
1123:                        autowireByType(beanName, mbd, bw, newPvs);
1124:                    }
1125:
1126:                    pvs = newPvs;
1127:                }
1128:
1129:                boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
1130:                boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
1131:
1132:                if (hasInstAwareBpps || needsDepCheck) {
1133:                    PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw);
1134:                    if (hasInstAwareBpps) {
1135:                        for (Iterator it = getBeanPostProcessors().iterator(); it
1136:                                .hasNext();) {
1137:                            BeanPostProcessor beanProcessor = (BeanPostProcessor) it
1138:                                    .next();
1139:                            if (beanProcessor instanceof  InstantiationAwareBeanPostProcessor) {
1140:                                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) beanProcessor;
1141:                                pvs = ibp.postProcessPropertyValues(pvs,
1142:                                        filteredPds, bw.getWrappedInstance(),
1143:                                        beanName);
1144:                                if (pvs == null) {
1145:                                    return;
1146:                                }
1147:                            }
1148:                        }
1149:                    }
1150:                    if (needsDepCheck) {
1151:                        checkDependencies(beanName, mbd, filteredPds, pvs);
1152:                    }
1153:                }
1154:
1155:                applyPropertyValues(beanName, mbd, bw, pvs);
1156:            }
1157:
1158:            /**
1159:             * Fill in any missing property values with references to
1160:             * other beans in this factory if autowire is set to "byName".
1161:             * @param beanName the name of the bean we're wiring up.
1162:             * Useful for debugging messages; not used functionally.
1163:             * @param mbd bean definition to update through autowiring
1164:             * @param bw BeanWrapper from which we can obtain information about the bean
1165:             * @param pvs the PropertyValues to register wired objects with
1166:             */
1167:            protected void autowireByName(String beanName,
1168:                    AbstractBeanDefinition mbd, BeanWrapper bw,
1169:                    MutablePropertyValues pvs) {
1170:
1171:                String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
1172:                for (int i = 0; i < propertyNames.length; i++) {
1173:                    String propertyName = propertyNames[i];
1174:                    if (containsBean(propertyName)) {
1175:                        Object bean = getBean(propertyName);
1176:                        pvs.addPropertyValue(propertyName, bean);
1177:                        registerDependentBean(propertyName, beanName);
1178:                        if (logger.isDebugEnabled()) {
1179:                            logger
1180:                                    .debug("Added autowiring by name from bean name '"
1181:                                            + beanName
1182:                                            + "' via property '"
1183:                                            + propertyName
1184:                                            + "' to bean named '"
1185:                                            + propertyName + "'");
1186:                        }
1187:                    } else {
1188:                        if (logger.isTraceEnabled()) {
1189:                            logger.trace("Not autowiring property '"
1190:                                    + propertyName + "' of bean '" + beanName
1191:                                    + "' by name: no matching bean found");
1192:                        }
1193:                    }
1194:                }
1195:            }
1196:
1197:            /**
1198:             * Abstract method defining "autowire by type" (bean properties by type) behavior.
1199:             * <p>This is like PicoContainer default, in which there must be exactly one bean
1200:             * of the property type in the bean factory. This makes bean factories simple to
1201:             * configure for small namespaces, but doesn't work as well as standard Spring
1202:             * behavior for bigger applications.
1203:             * @param beanName the name of the bean to autowire by type
1204:             * @param mbd the merged bean definition to update through autowiring
1205:             * @param bw BeanWrapper from which we can obtain information about the bean
1206:             * @param pvs the PropertyValues to register wired objects with
1207:             */
1208:            protected void autowireByType(String beanName,
1209:                    AbstractBeanDefinition mbd, BeanWrapper bw,
1210:                    MutablePropertyValues pvs) {
1211:
1212:                TypeConverter converter = getCustomTypeConverter();
1213:                if (converter == null) {
1214:                    converter = bw;
1215:                }
1216:                Set autowiredBeanNames = new LinkedHashSet(4);
1217:                String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
1218:                for (int i = 0; i < propertyNames.length; i++) {
1219:                    String propertyName = propertyNames[i];
1220:                    try {
1221:                        PropertyDescriptor pd = bw
1222:                                .getPropertyDescriptor(propertyName);
1223:                        Object autowiredArgument = resolveDependency(
1224:                                new DependencyDescriptor(new MethodParameter(pd
1225:                                        .getWriteMethod(), 0), false),
1226:                                beanName, autowiredBeanNames, converter);
1227:                        if (autowiredArgument != null) {
1228:                            pvs.addPropertyValue(propertyName,
1229:                                    autowiredArgument);
1230:                        }
1231:                        for (Iterator it = autowiredBeanNames.iterator(); it
1232:                                .hasNext();) {
1233:                            String autowiredBeanName = (String) it.next();
1234:                            registerDependentBean(autowiredBeanName, beanName);
1235:                            if (logger.isDebugEnabled()) {
1236:                                logger
1237:                                        .debug("Autowiring by type from bean name '"
1238:                                                + beanName
1239:                                                + "' via property '"
1240:                                                + propertyName
1241:                                                + "' to bean named '"
1242:                                                + autowiredBeanName + "'");
1243:                            }
1244:                        }
1245:                        autowiredBeanNames.clear();
1246:                    } catch (BeansException ex) {
1247:                        throw new UnsatisfiedDependencyException(mbd
1248:                                .getResourceDescription(), beanName,
1249:                                propertyName, ex.getMessage());
1250:                    }
1251:                }
1252:            }
1253:
1254:            /**
1255:             * Return an array of non-simple bean properties that are unsatisfied.
1256:             * These are probably unsatisfied references to other beans in the
1257:             * factory. Does not include simple properties like primitives or Strings.
1258:             * @param mbd the merged bean definition the bean was created with
1259:             * @param bw the BeanWrapper the bean was created with
1260:             * @return an array of bean property names
1261:             * @see org.springframework.beans.BeanUtils#isSimpleProperty
1262:             */
1263:            protected String[] unsatisfiedNonSimpleProperties(
1264:                    AbstractBeanDefinition mbd, BeanWrapper bw) {
1265:                Set result = new TreeSet();
1266:                PropertyValues pvs = mbd.getPropertyValues();
1267:                PropertyDescriptor[] pds = bw.getPropertyDescriptors();
1268:                for (int i = 0; i < pds.length; i++) {
1269:                    if (pds[i].getWriteMethod() != null
1270:                            && !isExcludedFromDependencyCheck(pds[i])
1271:                            && !pvs.contains(pds[i].getName())
1272:                            && !BeanUtils.isSimpleProperty(pds[i]
1273:                                    .getPropertyType())) {
1274:                        result.add(pds[i].getName());
1275:                    }
1276:                }
1277:                return StringUtils.toStringArray(result);
1278:            }
1279:
1280:            /**
1281:             * Extract a filtered set of PropertyDescriptors from the given BeanWrapper,
1282:             * excluding ignored dependency types or properties defined on ignored
1283:             * dependency interfaces.
1284:             * @param bw the BeanWrapper the bean was created with
1285:             * @return the filtered PropertyDescriptors
1286:             * @see #isExcludedFromDependencyCheck
1287:             */
1288:            protected PropertyDescriptor[] filterPropertyDescriptorsForDependencyCheck(
1289:                    BeanWrapper bw) {
1290:                synchronized (this .filteredPropertyDescriptorsCache) {
1291:                    PropertyDescriptor[] filtered = (PropertyDescriptor[]) this .filteredPropertyDescriptorsCache
1292:                            .get(bw.getWrappedClass());
1293:                    if (filtered == null) {
1294:                        List pds = new LinkedList(Arrays.asList(bw
1295:                                .getPropertyDescriptors()));
1296:                        for (Iterator it = pds.iterator(); it.hasNext();) {
1297:                            PropertyDescriptor pd = (PropertyDescriptor) it
1298:                                    .next();
1299:                            if (isExcludedFromDependencyCheck(pd)) {
1300:                                it.remove();
1301:                            }
1302:                        }
1303:                        filtered = (PropertyDescriptor[]) pds
1304:                                .toArray(new PropertyDescriptor[pds.size()]);
1305:                        this .filteredPropertyDescriptorsCache.put(bw
1306:                                .getWrappedClass(), filtered);
1307:                    }
1308:                    return filtered;
1309:                }
1310:            }
1311:
1312:            /**
1313:             * Determine whether the given bean property is excluded from dependency checks.
1314:             * <p>This implementation excludes properties defined by CGLIB and
1315:             * properties whose type matches an ignored dependency type or which
1316:             * are defined by an ignored dependency interface.
1317:             * @param pd the PropertyDescriptor of the bean property
1318:             * @return whether the bean property is excluded
1319:             * @see #ignoreDependencyType(Class)
1320:             * @see #ignoreDependencyInterface(Class)
1321:             */
1322:            protected boolean isExcludedFromDependencyCheck(
1323:                    PropertyDescriptor pd) {
1324:                return (AutowireUtils.isExcludedFromDependencyCheck(pd)
1325:                        || this .ignoredDependencyTypes.contains(pd
1326:                                .getPropertyType()) || AutowireUtils
1327:                        .isSetterDefinedInInterface(pd,
1328:                                this .ignoredDependencyInterfaces));
1329:            }
1330:
1331:            /**
1332:             * Perform a dependency check that all properties exposed have been set,
1333:             * if desired. Dependency checks can be objects (collaborating beans),
1334:             * simple (primitives and String), or all (both).
1335:             * @param beanName the name of the bean
1336:             * @param mbd the merged bean definition the bean was created with
1337:             * @param pds the relevant property descriptors for the target bean
1338:             * @param pvs the property values to be applied to the bean
1339:             * @see #isExcludedFromDependencyCheck(java.beans.PropertyDescriptor)
1340:             */
1341:            protected void checkDependencies(String beanName,
1342:                    AbstractBeanDefinition mbd, PropertyDescriptor[] pds,
1343:                    PropertyValues pvs) throws UnsatisfiedDependencyException {
1344:
1345:                int dependencyCheck = mbd.getDependencyCheck();
1346:                for (int i = 0; i < pds.length; i++) {
1347:                    if (pds[i].getWriteMethod() != null
1348:                            && !pvs.contains(pds[i].getName())) {
1349:                        boolean isSimple = BeanUtils.isSimpleProperty(pds[i]
1350:                                .getPropertyType());
1351:                        boolean unsatisfied = (dependencyCheck == RootBeanDefinition.DEPENDENCY_CHECK_ALL)
1352:                                || (isSimple && dependencyCheck == RootBeanDefinition.DEPENDENCY_CHECK_SIMPLE)
1353:                                || (!isSimple && dependencyCheck == RootBeanDefinition.DEPENDENCY_CHECK_OBJECTS);
1354:                        if (unsatisfied) {
1355:                            throw new UnsatisfiedDependencyException(mbd
1356:                                    .getResourceDescription(), beanName, pds[i]
1357:                                    .getName(),
1358:                                    "Set this property value or disable dependency checking for this bean.");
1359:                        }
1360:                    }
1361:                }
1362:            }
1363:
1364:            /**
1365:             * Apply the given property values, resolving any runtime references
1366:             * to other beans in this bean factory. Must use deep copy, so we
1367:             * don't permanently modify this property.
1368:             * @param beanName the bean name passed for better exception information
1369:             * @param mbd the merged bean definition
1370:             * @param bw the BeanWrapper wrapping the target object
1371:             * @param pvs the new property values
1372:             */
1373:            protected void applyPropertyValues(String beanName,
1374:                    BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
1375:                if (pvs == null || pvs.isEmpty()) {
1376:                    return;
1377:                }
1378:
1379:                MutablePropertyValues mpvs = null;
1380:                List original = null;
1381:
1382:                if (pvs instanceof  MutablePropertyValues) {
1383:                    mpvs = (MutablePropertyValues) pvs;
1384:                    if (mpvs.isConverted()) {
1385:                        // Shortcut: use the pre-converted values as-is.
1386:                        try {
1387:                            bw.setPropertyValues(mpvs);
1388:                            return;
1389:                        } catch (BeansException ex) {
1390:                            throw new BeanCreationException(mbd
1391:                                    .getResourceDescription(), beanName,
1392:                                    "Error setting property values", ex);
1393:                        }
1394:                    }
1395:                    original = mpvs.getPropertyValueList();
1396:                } else {
1397:                    original = Arrays.asList(pvs.getPropertyValues());
1398:                }
1399:
1400:                TypeConverter converter = getCustomTypeConverter();
1401:                if (converter == null) {
1402:                    converter = bw;
1403:                }
1404:                BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(
1405:                        this , beanName, mbd, converter);
1406:
1407:                // Create a deep copy, resolving any references for values.
1408:                List deepCopy = new ArrayList(original.size());
1409:                boolean resolveNecessary = false;
1410:                for (Iterator it = original.iterator(); it.hasNext();) {
1411:                    PropertyValue pv = (PropertyValue) it.next();
1412:                    if (pv.isConverted()) {
1413:                        deepCopy.add(pv);
1414:                    } else {
1415:                        String propertyName = pv.getName();
1416:                        Object originalValue = pv.getValue();
1417:                        Object resolvedValue = valueResolver
1418:                                .resolveValueIfNecessary(pv, originalValue);
1419:                        // Possibly store converted value in merged bean definition,
1420:                        // in order to avoid re-conversion for every created bean instance.
1421:                        if (resolvedValue == originalValue) {
1422:                            if (!PropertyAccessorUtils
1423:                                    .isNestedOrIndexedProperty(propertyName)) {
1424:                                pv.setConvertedValue(convertForProperty(
1425:                                        resolvedValue, propertyName, bw,
1426:                                        converter));
1427:                            }
1428:                            deepCopy.add(pv);
1429:                        } else if (originalValue instanceof  TypedStringValue
1430:                                && !PropertyAccessorUtils
1431:                                        .isNestedOrIndexedProperty(propertyName)) {
1432:                            pv
1433:                                    .setConvertedValue(convertForProperty(
1434:                                            resolvedValue, propertyName, bw,
1435:                                            converter));
1436:                            deepCopy.add(pv);
1437:                        } else {
1438:                            resolveNecessary = true;
1439:                            deepCopy.add(new PropertyValue(pv, resolvedValue));
1440:                        }
1441:                    }
1442:                }
1443:                if (mpvs != null && !resolveNecessary) {
1444:                    mpvs.setConverted();
1445:                }
1446:
1447:                // Set our (possibly massaged) deep copy.
1448:                try {
1449:                    bw.setPropertyValues(new MutablePropertyValues(deepCopy));
1450:                } catch (BeansException ex) {
1451:                    throw new BeanCreationException(mbd
1452:                            .getResourceDescription(), beanName,
1453:                            "Error setting property values", ex);
1454:                }
1455:            }
1456:
1457:            /**
1458:             * Convert the given value for the specified target property.
1459:             */
1460:            private Object convertForProperty(Object value,
1461:                    String propertyName, BeanWrapper bw, TypeConverter converter) {
1462:                if (converter instanceof  BeanWrapperImpl) {
1463:                    return ((BeanWrapperImpl) converter).convertForProperty(
1464:                            value, propertyName);
1465:                } else {
1466:                    PropertyDescriptor descriptor = bw
1467:                            .getPropertyDescriptor(propertyName);
1468:                    return converter.convertIfNecessary(value, descriptor
1469:                            .getPropertyType(), new MethodParameter(descriptor
1470:                            .getWriteMethod(), 0));
1471:                }
1472:            }
1473:
1474:            /**
1475:             * Initialize the given bean instance, applying factory callbacks
1476:             * as well as init methods and bean post processors.
1477:             * <p>Called from {@link #createBean} for traditionally defined beans,
1478:             * and from {@link #initializeBean} for existing bean instances.
1479:             * @param beanName the bean name in the factory (for debugging purposes)
1480:             * @param bean the new bean instance we may need to initialize
1481:             * @param mbd the bean definition that the bean was created with
1482:             * (can also be <code>null</code>, if given an existing bean instance)
1483:             * @return the initialized bean instance (potentially wrapped)
1484:             * @see BeanNameAware
1485:             * @see BeanClassLoaderAware
1486:             * @see BeanFactoryAware
1487:             * @see #applyBeanPostProcessorsBeforeInitialization
1488:             * @see #invokeInitMethods
1489:             * @see #applyBeanPostProcessorsAfterInitialization
1490:             */
1491:            protected Object initializeBean(String beanName, Object bean,
1492:                    RootBeanDefinition mbd) {
1493:                if (bean instanceof  BeanNameAware) {
1494:                    ((BeanNameAware) bean).setBeanName(beanName);
1495:                }
1496:
1497:                if (bean instanceof  BeanClassLoaderAware) {
1498:                    ((BeanClassLoaderAware) bean)
1499:                            .setBeanClassLoader(getBeanClassLoader());
1500:                }
1501:
1502:                if (bean instanceof  BeanFactoryAware) {
1503:                    ((BeanFactoryAware) bean).setBeanFactory(this );
1504:                }
1505:
1506:                Object wrappedBean = bean;
1507:                if (mbd == null || !mbd.isSynthetic()) {
1508:                    wrappedBean = applyBeanPostProcessorsBeforeInitialization(
1509:                            wrappedBean, beanName);
1510:                }
1511:
1512:                try {
1513:                    invokeInitMethods(beanName, wrappedBean, mbd);
1514:                } catch (Throwable ex) {
1515:                    throw new BeanCreationException((mbd != null ? mbd
1516:                            .getResourceDescription() : null), beanName,
1517:                            "Invocation of init method failed", ex);
1518:                }
1519:
1520:                if (mbd == null || !mbd.isSynthetic()) {
1521:                    wrappedBean = applyBeanPostProcessorsAfterInitialization(
1522:                            wrappedBean, beanName);
1523:                }
1524:                return wrappedBean;
1525:            }
1526:
1527:            /**
1528:             * Give a bean a chance to react now all its properties are set,
1529:             * and a chance to know about its owning bean factory (this object).
1530:             * This means checking whether the bean implements InitializingBean or defines
1531:             * a custom init method, and invoking the necessary callback(s) if it does.
1532:             * @param beanName the bean name in the factory (for debugging purposes)
1533:             * @param bean the new bean instance we may need to initialize
1534:             * @param mbd the merged bean definition that the bean was created with
1535:             * (can also be <code>null</code>, if given an existing bean instance)
1536:             * @throws Throwable if thrown by init methods or by the invocation process
1537:             * @see #invokeCustomInitMethod
1538:             */
1539:            protected void invokeInitMethods(String beanName, Object bean,
1540:                    RootBeanDefinition mbd) throws Throwable {
1541:
1542:                boolean isInitializingBean = (bean instanceof  InitializingBean);
1543:                if (isInitializingBean
1544:                        && (mbd == null || !mbd
1545:                                .isExternallyManagedInitMethod("afterPropertiesSet"))) {
1546:                    ((InitializingBean) bean).afterPropertiesSet();
1547:                }
1548:
1549:                String initMethodName = (mbd != null ? mbd.getInitMethodName()
1550:                        : null);
1551:                if (initMethodName != null
1552:                        && !(isInitializingBean && "afterPropertiesSet"
1553:                                .equals(initMethodName))
1554:                        && !mbd.isExternallyManagedInitMethod(initMethodName)) {
1555:                    invokeCustomInitMethod(beanName, bean, initMethodName, mbd
1556:                            .isEnforceInitMethod());
1557:                }
1558:            }
1559:
1560:            /**
1561:             * Invoke the specified custom init method on the given bean.
1562:             * Called by invokeInitMethods.
1563:             * <p>Can be overridden in subclasses for custom resolution of init
1564:             * methods with arguments.
1565:             * @param beanName the bean name in the factory (for debugging purposes)
1566:             * @param bean the new bean instance we may need to initialize
1567:             * @param initMethodName the name of the custom init method
1568:             * @param enforceInitMethod indicates whether the defined init method needs to exist
1569:             * @see #invokeInitMethods
1570:             */
1571:            protected void invokeCustomInitMethod(String beanName, Object bean,
1572:                    String initMethodName, boolean enforceInitMethod)
1573:                    throws Throwable {
1574:
1575:                Method initMethod = BeanUtils.findMethod(bean.getClass(),
1576:                        initMethodName, null);
1577:                if (initMethod == null) {
1578:                    if (enforceInitMethod) {
1579:                        throw new NoSuchMethodException(
1580:                                "Couldn't find an init method named '"
1581:                                        + initMethodName
1582:                                        + "' on bean with name '" + beanName
1583:                                        + "'");
1584:                    } else {
1585:                        // Ignore non-existent default lifecycle methods.
1586:                        return;
1587:                    }
1588:                }
1589:                ReflectionUtils.makeAccessible(initMethod);
1590:                try {
1591:                    initMethod.invoke(bean, (Object[]) null);
1592:                } catch (InvocationTargetException ex) {
1593:                    throw ex.getTargetException();
1594:                }
1595:            }
1596:
1597:            /**
1598:             * Applies the <code>postProcessAfterInitialization</code> callback of all
1599:             * registered BeanPostProcessors, giving them a chance to post-process the
1600:             * object obtained from FactoryBeans (for example, to auto-proxy them).
1601:             * @see #applyBeanPostProcessorsAfterInitialization
1602:             */
1603:            protected Object postProcessObjectFromFactoryBean(Object object,
1604:                    String beanName) {
1605:                return applyBeanPostProcessorsAfterInitialization(object,
1606:                        beanName);
1607:            }
1608:
1609:            /**
1610:             * Overridden to clear FactoryBean instance cache as well.
1611:             */
1612:            protected void removeSingleton(String beanName) {
1613:                super .removeSingleton(beanName);
1614:                this .factoryBeanInstanceCache.remove(beanName);
1615:            }
1616:
1617:            //---------------------------------------------------------------------
1618:            // Template methods to be implemented by subclasses
1619:            //---------------------------------------------------------------------
1620:
1621:            /**
1622:             * Find bean instances that match the required type.
1623:             * Called during autowiring for the specified bean.
1624:             * <p>If a subclass cannot obtain information about bean names by type,
1625:             * a corresponding exception should be thrown.
1626:             * @param beanName the name of the bean that is about to be wired
1627:             * @param requiredType the actual type of bean to look for
1628:             * (may be an array component type or collection element type)
1629:             * @param descriptor the descriptor of the dependency to resolve
1630:             * @return a Map of candidate names and candidate instances that match
1631:             * the required type (never <code>null</code>)
1632:             * @throws BeansException in case of errors
1633:             * @see #autowireByType
1634:             * @see #autowireConstructor
1635:             */
1636:            protected abstract Map findAutowireCandidates(String beanName,
1637:                    Class requiredType, DependencyDescriptor descriptor)
1638:                    throws BeansException;
1639:
1640:            protected abstract String determinePrimaryCandidate(
1641:                    Map matchingBeans, Class type);
1642:
1643:            //---------------------------------------------------------------------
1644:            // Inner classes that serve as internal helpers
1645:            //---------------------------------------------------------------------
1646:
1647:            /**
1648:             * Subclass of ConstructorResolver that delegates to surrounding
1649:             * AbstractAutowireCapableBeanFactory facilities.
1650:             */
1651:            private class ConstructorResolverAdapter extends
1652:                    ConstructorResolver {
1653:
1654:                public ConstructorResolverAdapter() {
1655:                    super (AbstractAutowireCapableBeanFactory.this ,
1656:                            getInstantiationStrategy(),
1657:                            getCustomTypeConverter());
1658:                }
1659:
1660:                protected Object resolveAutowiredArgument(
1661:                        MethodParameter param, String beanName,
1662:                        Set autowiredBeanNames, TypeConverter typeConverter) {
1663:                    return resolveDependency(new DependencyDescriptor(param,
1664:                            true), beanName, autowiredBeanNames, typeConverter);
1665:                }
1666:            }
1667:
1668:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.