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