Source Code Cross Referenced for AbstractBeanFactory.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.PropertyEditor;
0020:        import java.security.AccessController;
0021:        import java.security.PrivilegedAction;
0022:        import java.util.ArrayList;
0023:        import java.util.Arrays;
0024:        import java.util.Collections;
0025:        import java.util.HashMap;
0026:        import java.util.HashSet;
0027:        import java.util.Iterator;
0028:        import java.util.LinkedHashSet;
0029:        import java.util.List;
0030:        import java.util.Map;
0031:        import java.util.Set;
0032:
0033:        import org.springframework.beans.BeanWrapper;
0034:        import org.springframework.beans.BeansException;
0035:        import org.springframework.beans.PropertyEditorRegistrar;
0036:        import org.springframework.beans.PropertyEditorRegistry;
0037:        import org.springframework.beans.PropertyEditorRegistrySupport;
0038:        import org.springframework.beans.SimpleTypeConverter;
0039:        import org.springframework.beans.TypeConverter;
0040:        import org.springframework.beans.factory.BeanCreationException;
0041:        import org.springframework.beans.factory.BeanCurrentlyInCreationException;
0042:        import org.springframework.beans.factory.BeanDefinitionStoreException;
0043:        import org.springframework.beans.factory.BeanFactory;
0044:        import org.springframework.beans.factory.BeanFactoryUtils;
0045:        import org.springframework.beans.factory.BeanIsAbstractException;
0046:        import org.springframework.beans.factory.BeanIsNotAFactoryException;
0047:        import org.springframework.beans.factory.BeanNotOfRequiredTypeException;
0048:        import org.springframework.beans.factory.CannotLoadBeanClassException;
0049:        import org.springframework.beans.factory.DisposableBean;
0050:        import org.springframework.beans.factory.FactoryBean;
0051:        import org.springframework.beans.factory.FactoryBeanNotInitializedException;
0052:        import org.springframework.beans.factory.NoSuchBeanDefinitionException;
0053:        import org.springframework.beans.factory.ObjectFactory;
0054:        import org.springframework.beans.factory.SmartFactoryBean;
0055:        import org.springframework.beans.factory.config.BeanDefinition;
0056:        import org.springframework.beans.factory.config.BeanPostProcessor;
0057:        import org.springframework.beans.factory.config.ConfigurableBeanFactory;
0058:        import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
0059:        import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
0060:        import org.springframework.beans.factory.config.Scope;
0061:        import org.springframework.core.CollectionFactory;
0062:        import org.springframework.util.Assert;
0063:        import org.springframework.util.ClassUtils;
0064:        import org.springframework.util.StringUtils;
0065:        import org.springframework.util.StringValueResolver;
0066:
0067:        /**
0068:         * Abstract base class for {@link org.springframework.beans.factory.BeanFactory}
0069:         * implementations, providing the full capabilities of the
0070:         * {@link org.springframework.beans.factory.config.ConfigurableBeanFactory} SPI.
0071:         * Does <i>not</i> assume a listable bean factory: can therefore also be used
0072:         * as base class for bean factory implementations which obtain bean definitions
0073:         * from some backend resource (where bean definition access is an expensive operation).
0074:         *
0075:         * <p>This class provides a singleton cache (through its base class
0076:         * {@link org.springframework.beans.factory.support.DefaultSingletonBeanRegistry},
0077:         * singleton/prototype determination, {@link org.springframework.beans.factory.FactoryBean}
0078:         * handling, aliases, bean definition merging for child bean definitions,
0079:         * and bean destruction ({@link org.springframework.beans.factory.DisposableBean}
0080:         * interface, custom destroy methods). Furthermore, it can manage a bean factory
0081:         * hierarchy (delegating to the parent in case of an unknown bean), through implementing
0082:         * the {@link org.springframework.beans.factory.HierarchicalBeanFactory} interface.
0083:         *
0084:         * <p>The main template methods to be implemented by subclasses are
0085:         * {@link #getBeanDefinition} and {@link #createBean}, retrieving a bean definition
0086:         * for a given bean name and creating a bean instance for a given bean definition,
0087:         * respectively. Default implementations of those operations can be found in
0088:         * {@link DefaultListableBeanFactory} and {@link AbstractAutowireCapableBeanFactory}.
0089:         *
0090:         * @author Rod Johnson
0091:         * @author Juergen Hoeller
0092:         * @since 15 April 2001
0093:         * @see #getBeanDefinition
0094:         * @see #createBean
0095:         * @see AbstractAutowireCapableBeanFactory#createBean
0096:         * @see DefaultListableBeanFactory#getBeanDefinition
0097:         */
0098:        public abstract class AbstractBeanFactory extends
0099:                DefaultSingletonBeanRegistry implements  ConfigurableBeanFactory {
0100:
0101:            /** Parent bean factory, for bean inheritance support */
0102:            private BeanFactory parentBeanFactory;
0103:
0104:            /** ClassLoader to resolve bean class names with, if necessary */
0105:            private ClassLoader beanClassLoader = ClassUtils
0106:                    .getDefaultClassLoader();
0107:
0108:            /** ClassLoader to temporarily resolve bean class names with, if necessary */
0109:            private ClassLoader tempClassLoader;
0110:
0111:            /** Whether to cache bean metadata or rather reobtain it for every access */
0112:            private boolean cacheBeanMetadata = true;
0113:
0114:            /** Custom PropertyEditors to apply to the beans of this factory */
0115:            private final Map customEditors = new HashMap();
0116:
0117:            /** Custom PropertyEditorRegistrars to apply to the beans of this factory */
0118:            private final Set propertyEditorRegistrars = new LinkedHashSet(16);
0119:
0120:            /** A custom TypeConverter to use, overriding the default PropertyEditor mechanism */
0121:            private TypeConverter typeConverter;
0122:
0123:            /** BeanPostProcessors to apply in createBean */
0124:            private final List beanPostProcessors = new ArrayList();
0125:
0126:            /** Indicates whether any InstantiationAwareBeanPostProcessors have been registered */
0127:            private boolean hasInstantiationAwareBeanPostProcessors;
0128:
0129:            /** Indicates whether any DestructionAwareBeanPostProcessors have been registered */
0130:            private boolean hasDestructionAwareBeanPostProcessors;
0131:
0132:            /** Map from scope identifier String to corresponding Scope */
0133:            private final Map scopes = new HashMap();
0134:
0135:            /** Map from alias to canonical bean name */
0136:            private final Map aliasMap = CollectionFactory
0137:                    .createConcurrentMapIfPossible(16);
0138:
0139:            /** Map from bean name to merged RootBeanDefinition */
0140:            private final Map mergedBeanDefinitions = CollectionFactory
0141:                    .createConcurrentMapIfPossible(16);
0142:
0143:            /** Names of beans that have already been created at least once */
0144:            private final Set alreadyCreated = Collections
0145:                    .synchronizedSet(new HashSet());
0146:
0147:            /** Names of beans that are currently in creation */
0148:            private final ThreadLocal prototypesCurrentlyInCreation = new ThreadLocal();
0149:
0150:            /** Cache of singleton objects created by FactoryBeans: FactoryBean name --> object */
0151:            private final Map factoryBeanObjectCache = new HashMap();
0152:
0153:            /**
0154:             * Create a new AbstractBeanFactory.
0155:             */
0156:            public AbstractBeanFactory() {
0157:            }
0158:
0159:            /**
0160:             * Create a new AbstractBeanFactory with the given parent.
0161:             * @param parentBeanFactory parent bean factory, or <code>null</code> if none
0162:             * @see #getBean
0163:             */
0164:            public AbstractBeanFactory(BeanFactory parentBeanFactory) {
0165:                this .parentBeanFactory = parentBeanFactory;
0166:            }
0167:
0168:            //---------------------------------------------------------------------
0169:            // Implementation of BeanFactory interface
0170:            //---------------------------------------------------------------------
0171:
0172:            public Object getBean(String name) throws BeansException {
0173:                return getBean(name, null, null);
0174:            }
0175:
0176:            public Object getBean(String name, Class requiredType)
0177:                    throws BeansException {
0178:                return getBean(name, requiredType, null);
0179:            }
0180:
0181:            public Object getBean(String name, Object[] args)
0182:                    throws BeansException {
0183:                return getBean(name, null, args);
0184:            }
0185:
0186:            /**
0187:             * Return an instance, which may be shared or independent, of the specified bean.
0188:             * @param name the name of the bean to retrieve
0189:             * @param requiredType the required type of the bean to retrieve
0190:             * @param args arguments to use if creating a prototype using explicit arguments to a
0191:             * static factory method. It is invalid to use a non-null args value in any other case.
0192:             * @return an instance of the bean
0193:             * @throws BeansException if the bean could not be created
0194:             */
0195:            public Object getBean(final String name, final Class requiredType,
0196:                    final Object[] args) throws BeansException {
0197:                final String beanName = transformedBeanName(name);
0198:                Object bean = null;
0199:
0200:                // Eagerly check singleton cache for manually registered singletons.
0201:                Object sharedInstance = getSingleton(beanName);
0202:                if (sharedInstance != null) {
0203:                    if (logger.isDebugEnabled()) {
0204:                        if (isSingletonCurrentlyInCreation(beanName)) {
0205:                            logger
0206:                                    .debug("Returning eagerly cached instance of singleton bean '"
0207:                                            + beanName
0208:                                            + "' that is not fully initialized yet - a consequence of a circular reference");
0209:                        } else {
0210:                            logger
0211:                                    .debug("Returning cached instance of singleton bean '"
0212:                                            + beanName + "'");
0213:                        }
0214:                    }
0215:                    bean = getObjectForBeanInstance(sharedInstance, name,
0216:                            beanName);
0217:                }
0218:
0219:                else {
0220:                    // Fail if we're already creating this bean instance:
0221:                    // We're assumably within a circular reference.
0222:                    if (isPrototypeCurrentlyInCreation(beanName)) {
0223:                        throw new BeanCurrentlyInCreationException(beanName);
0224:                    }
0225:
0226:                    // Check if bean definition exists in this factory.
0227:                    BeanFactory parentBeanFactory = getParentBeanFactory();
0228:                    if (parentBeanFactory != null
0229:                            && !containsBeanDefinition(beanName)) {
0230:                        // Not found -> check parent.
0231:                        String nameToLookup = originalBeanName(name);
0232:                        if (args != null) {
0233:                            // Delegation to parent with explicit args.
0234:                            return parentBeanFactory
0235:                                    .getBean(nameToLookup, args);
0236:                        } else {
0237:                            // No args -> delegate to standard getBean method.
0238:                            return parentBeanFactory.getBean(nameToLookup,
0239:                                    requiredType);
0240:                        }
0241:                    }
0242:
0243:                    this .alreadyCreated.add(beanName);
0244:
0245:                    final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
0246:                    checkMergedBeanDefinition(mbd, beanName, args);
0247:
0248:                    // Guarantee initialization of beans that the current one depends on.
0249:                    String[] dependsOn = mbd.getDependsOn();
0250:                    if (dependsOn != null) {
0251:                        for (int i = 0; i < dependsOn.length; i++) {
0252:                            String dependsOnBean = dependsOn[i];
0253:                            getBean(dependsOnBean);
0254:                            registerDependentBean(dependsOnBean, beanName);
0255:                        }
0256:                    }
0257:
0258:                    // Create bean instance.
0259:                    if (mbd.isSingleton()) {
0260:                        sharedInstance = getSingleton(beanName,
0261:                                new ObjectFactory() {
0262:                                    public Object getObject()
0263:                                            throws BeansException {
0264:                                        try {
0265:                                            return createBean(beanName, mbd,
0266:                                                    args);
0267:                                        } catch (BeansException ex) {
0268:                                            // Explicitly remove instance from singleton cache: It might have been put there
0269:                                            // eagerly by the creation process, to allow for circular reference resolution.
0270:                                            // Also remove any beans that received a temporary reference to the bean.
0271:                                            destroySingleton(beanName);
0272:                                            throw ex;
0273:                                        }
0274:                                    }
0275:                                });
0276:                        bean = getObjectForBeanInstance(sharedInstance, name,
0277:                                beanName);
0278:                    }
0279:
0280:                    else if (mbd.isPrototype()) {
0281:                        // It's a prototype -> create a new instance.
0282:                        Object prototypeInstance = null;
0283:                        try {
0284:                            beforePrototypeCreation(beanName);
0285:                            prototypeInstance = createBean(beanName, mbd, args);
0286:                        } finally {
0287:                            afterPrototypeCreation(beanName);
0288:                        }
0289:                        bean = getObjectForBeanInstance(prototypeInstance,
0290:                                name, beanName);
0291:                    }
0292:
0293:                    else {
0294:                        String scopeName = mbd.getScope();
0295:                        final Scope scope = (Scope) this .scopes.get(scopeName);
0296:                        if (scope == null) {
0297:                            throw new IllegalStateException(
0298:                                    "No Scope registered for scope '"
0299:                                            + scopeName + "'");
0300:                        }
0301:                        try {
0302:                            Object scopedInstance = scope.get(beanName,
0303:                                    new ObjectFactory() {
0304:                                        public Object getObject()
0305:                                                throws BeansException {
0306:                                            beforePrototypeCreation(beanName);
0307:                                            try {
0308:                                                return createBean(beanName,
0309:                                                        mbd, args);
0310:                                            } finally {
0311:                                                afterPrototypeCreation(beanName);
0312:                                            }
0313:                                        }
0314:                                    });
0315:                            bean = getObjectForBeanInstance(scopedInstance,
0316:                                    name, beanName);
0317:                        } catch (IllegalStateException ex) {
0318:                            throw new BeanCreationException(
0319:                                    beanName,
0320:                                    "Scope '"
0321:                                            + scopeName
0322:                                            + "' is not active for the current thread; "
0323:                                            + "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",
0324:                                    ex);
0325:                        }
0326:                    }
0327:                }
0328:
0329:                // Check if required type matches the type of the actual bean instance.
0330:                if (requiredType != null && bean != null
0331:                        && !requiredType.isAssignableFrom(bean.getClass())) {
0332:                    throw new BeanNotOfRequiredTypeException(name,
0333:                            requiredType, bean.getClass());
0334:                }
0335:                return bean;
0336:            }
0337:
0338:            public boolean containsBean(String name) {
0339:                String beanName = transformedBeanName(name);
0340:                if (containsSingleton(beanName)
0341:                        || containsBeanDefinition(beanName)) {
0342:                    return (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(name));
0343:                }
0344:                // Not found -> check parent.
0345:                BeanFactory parentBeanFactory = getParentBeanFactory();
0346:                return (parentBeanFactory != null && parentBeanFactory
0347:                        .containsBean(originalBeanName(name)));
0348:            }
0349:
0350:            public boolean isSingleton(String name)
0351:                    throws NoSuchBeanDefinitionException {
0352:                String beanName = transformedBeanName(name);
0353:
0354:                Object beanInstance = getSingleton(beanName);
0355:                if (beanInstance != null) {
0356:                    if (beanInstance instanceof  FactoryBean) {
0357:                        return (BeanFactoryUtils.isFactoryDereference(name) || ((FactoryBean) beanInstance)
0358:                                .isSingleton());
0359:                    } else {
0360:                        return !BeanFactoryUtils.isFactoryDereference(name);
0361:                    }
0362:                }
0363:
0364:                else {
0365:                    // No singleton instance found -> check bean definition.
0366:                    BeanFactory parentBeanFactory = getParentBeanFactory();
0367:                    if (parentBeanFactory != null
0368:                            && !containsBeanDefinition(beanName)) {
0369:                        // No bean definition found in this factory -> delegate to parent.
0370:                        return parentBeanFactory
0371:                                .isSingleton(originalBeanName(name));
0372:                    }
0373:
0374:                    RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
0375:
0376:                    // In case of FactoryBean, return singleton status of created object if not a dereference.
0377:                    if (mbd.isSingleton()) {
0378:                        Class beanClass = predictBeanType(beanName, mbd, true);
0379:                        if (beanClass != null
0380:                                && FactoryBean.class
0381:                                        .isAssignableFrom(beanClass)) {
0382:                            if (BeanFactoryUtils.isFactoryDereference(name)) {
0383:                                return true;
0384:                            }
0385:                            FactoryBean factoryBean = (FactoryBean) getBean(FACTORY_BEAN_PREFIX
0386:                                    + beanName);
0387:                            return factoryBean.isSingleton();
0388:                        } else {
0389:                            return !BeanFactoryUtils.isFactoryDereference(name);
0390:                        }
0391:                    } else {
0392:                        return false;
0393:                    }
0394:                }
0395:            }
0396:
0397:            public boolean isPrototype(String name)
0398:                    throws NoSuchBeanDefinitionException {
0399:                String beanName = transformedBeanName(name);
0400:
0401:                BeanFactory parentBeanFactory = getParentBeanFactory();
0402:                if (parentBeanFactory != null
0403:                        && !containsBeanDefinition(beanName)) {
0404:                    // No bean definition found in this factory -> delegate to parent.
0405:                    return parentBeanFactory
0406:                            .isPrototype(originalBeanName(name));
0407:                }
0408:
0409:                RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
0410:                if (mbd.isPrototype()) {
0411:                    // In case of FactoryBean, return singleton status of created object if not a dereference.
0412:                    if (!BeanFactoryUtils.isFactoryDereference(name)) {
0413:                        return true;
0414:                    }
0415:                    Class beanClass = predictBeanType(beanName, mbd, true);
0416:                    return (beanClass != null && FactoryBean.class
0417:                            .isAssignableFrom(beanClass));
0418:                } else {
0419:                    // Singleton or scoped - not a prototype.
0420:                    // However, FactoryBean may still produce a prototype object...
0421:                    if (BeanFactoryUtils.isFactoryDereference(name)) {
0422:                        return false;
0423:                    }
0424:                    Class beanClass = predictBeanType(beanName, mbd, true);
0425:                    if (beanClass != null
0426:                            && FactoryBean.class.isAssignableFrom(beanClass)) {
0427:                        FactoryBean factoryBean = (FactoryBean) getBean(FACTORY_BEAN_PREFIX
0428:                                + beanName);
0429:                        return ((factoryBean instanceof  SmartFactoryBean && ((SmartFactoryBean) factoryBean)
0430:                                .isPrototype()) || !factoryBean.isSingleton());
0431:                    } else {
0432:                        return false;
0433:                    }
0434:                }
0435:            }
0436:
0437:            public boolean isTypeMatch(String name, Class targetType)
0438:                    throws NoSuchBeanDefinitionException {
0439:                String beanName = transformedBeanName(name);
0440:                Class typeToMatch = (targetType != null ? targetType
0441:                        : Object.class);
0442:
0443:                // Check manually registered singletons.
0444:                Object beanInstance = getSingleton(beanName);
0445:                if (beanInstance != null) {
0446:                    if (beanInstance instanceof  FactoryBean) {
0447:                        if (!BeanFactoryUtils.isFactoryDereference(name)) {
0448:                            Class type = getTypeForFactoryBean((FactoryBean) beanInstance);
0449:                            return (type != null && typeToMatch
0450:                                    .isAssignableFrom(type));
0451:                        } else {
0452:                            return typeToMatch.isAssignableFrom(beanInstance
0453:                                    .getClass());
0454:                        }
0455:                    } else {
0456:                        return !BeanFactoryUtils.isFactoryDereference(name)
0457:                                && typeToMatch.isAssignableFrom(beanInstance
0458:                                        .getClass());
0459:                    }
0460:                }
0461:
0462:                else {
0463:                    // No singleton instance found -> check bean definition.
0464:                    BeanFactory parentBeanFactory = getParentBeanFactory();
0465:                    if (parentBeanFactory != null
0466:                            && !containsBeanDefinition(beanName)) {
0467:                        // No bean definition found in this factory -> delegate to parent.
0468:                        return parentBeanFactory.isTypeMatch(
0469:                                originalBeanName(name), targetType);
0470:                    }
0471:
0472:                    RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
0473:                    Class beanClass = predictBeanType(beanName, mbd, true);
0474:
0475:                    if (beanClass == null) {
0476:                        return false;
0477:                    }
0478:
0479:                    // Check bean class whether we're dealing with a FactoryBean.
0480:                    if (FactoryBean.class.isAssignableFrom(beanClass)) {
0481:                        if (!BeanFactoryUtils.isFactoryDereference(name)) {
0482:                            // If it's a FactoryBean, we want to look at what it creates, not the factory class.
0483:                            Class type = getTypeForFactoryBean(beanName, mbd);
0484:                            return (type != null && typeToMatch
0485:                                    .isAssignableFrom(type));
0486:                        } else {
0487:                            return typeToMatch.isAssignableFrom(beanClass);
0488:                        }
0489:                    } else {
0490:                        return !BeanFactoryUtils.isFactoryDereference(name)
0491:                                && typeToMatch.isAssignableFrom(beanClass);
0492:                    }
0493:                }
0494:            }
0495:
0496:            public Class getType(String name)
0497:                    throws NoSuchBeanDefinitionException {
0498:                String beanName = transformedBeanName(name);
0499:
0500:                // Check manually registered singletons.
0501:                Object beanInstance = getSingleton(beanName);
0502:                if (beanInstance != null) {
0503:                    if (beanInstance instanceof  FactoryBean
0504:                            && !BeanFactoryUtils.isFactoryDereference(name)) {
0505:                        return getTypeForFactoryBean((FactoryBean) beanInstance);
0506:                    } else {
0507:                        return beanInstance.getClass();
0508:                    }
0509:                }
0510:
0511:                else {
0512:                    // No singleton instance found -> check bean definition.
0513:                    BeanFactory parentBeanFactory = getParentBeanFactory();
0514:                    if (parentBeanFactory != null
0515:                            && !containsBeanDefinition(beanName)) {
0516:                        // No bean definition found in this factory -> delegate to parent.
0517:                        return parentBeanFactory
0518:                                .getType(originalBeanName(name));
0519:                    }
0520:
0521:                    RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
0522:                    Class beanClass = predictBeanType(beanName, mbd, false);
0523:
0524:                    // Check bean class whether we're dealing with a FactoryBean.
0525:                    if (beanClass != null
0526:                            && FactoryBean.class.isAssignableFrom(beanClass)) {
0527:                        if (!BeanFactoryUtils.isFactoryDereference(name)) {
0528:                            // If it's a FactoryBean, we want to look at what it creates, not the factory class.
0529:                            return getTypeForFactoryBean(beanName, mbd);
0530:                        } else {
0531:                            return beanClass;
0532:                        }
0533:                    } else {
0534:                        return (!BeanFactoryUtils.isFactoryDereference(name) ? beanClass
0535:                                : null);
0536:                    }
0537:                }
0538:            }
0539:
0540:            public String[] getAliases(String name) {
0541:                String beanName = transformedBeanName(name);
0542:                List aliases = new ArrayList();
0543:                boolean factoryPrefix = name.startsWith(FACTORY_BEAN_PREFIX);
0544:                String fullBeanName = beanName;
0545:                if (factoryPrefix) {
0546:                    fullBeanName = FACTORY_BEAN_PREFIX + beanName;
0547:                }
0548:                if (!fullBeanName.equals(name)) {
0549:                    aliases.add(fullBeanName);
0550:                }
0551:                synchronized (this .aliasMap) {
0552:                    for (Iterator it = this .aliasMap.entrySet().iterator(); it
0553:                            .hasNext();) {
0554:                        Map.Entry entry = (Map.Entry) it.next();
0555:                        String registeredName = (String) entry.getValue();
0556:                        if (registeredName.equals(beanName)) {
0557:                            String key = (factoryPrefix ? FACTORY_BEAN_PREFIX
0558:                                    : "")
0559:                                    + entry.getKey();
0560:                            if (!key.equals(name)) {
0561:                                aliases.add(key);
0562:                            }
0563:                        }
0564:                    }
0565:                }
0566:                if (!containsSingleton(beanName)
0567:                        && !containsBeanDefinition(beanName)) {
0568:                    BeanFactory parentBeanFactory = getParentBeanFactory();
0569:                    if (parentBeanFactory != null) {
0570:                        aliases.addAll(Arrays.asList(parentBeanFactory
0571:                                .getAliases(fullBeanName)));
0572:                    }
0573:                }
0574:                return StringUtils.toStringArray(aliases);
0575:            }
0576:
0577:            //---------------------------------------------------------------------
0578:            // Implementation of HierarchicalBeanFactory interface
0579:            //---------------------------------------------------------------------
0580:
0581:            public BeanFactory getParentBeanFactory() {
0582:                return this .parentBeanFactory;
0583:            }
0584:
0585:            public boolean containsLocalBean(String name) {
0586:                String beanName = transformedBeanName(name);
0587:                return ((containsSingleton(beanName) || containsBeanDefinition(beanName)) && (!BeanFactoryUtils
0588:                        .isFactoryDereference(name) || isFactoryBean(beanName)));
0589:            }
0590:
0591:            //---------------------------------------------------------------------
0592:            // Implementation of ConfigurableBeanFactory interface
0593:            //---------------------------------------------------------------------
0594:
0595:            public void setParentBeanFactory(BeanFactory parentBeanFactory) {
0596:                if (this .parentBeanFactory != null
0597:                        && this .parentBeanFactory != parentBeanFactory) {
0598:                    throw new IllegalStateException(
0599:                            "Already associated with parent BeanFactory: "
0600:                                    + this .parentBeanFactory);
0601:                }
0602:                this .parentBeanFactory = parentBeanFactory;
0603:            }
0604:
0605:            public void setBeanClassLoader(ClassLoader beanClassLoader) {
0606:                this .beanClassLoader = (beanClassLoader != null ? beanClassLoader
0607:                        : ClassUtils.getDefaultClassLoader());
0608:            }
0609:
0610:            public ClassLoader getBeanClassLoader() {
0611:                return this .beanClassLoader;
0612:            }
0613:
0614:            public void setTempClassLoader(ClassLoader tempClassLoader) {
0615:                this .tempClassLoader = tempClassLoader;
0616:            }
0617:
0618:            public ClassLoader getTempClassLoader() {
0619:                return this .tempClassLoader;
0620:            }
0621:
0622:            public void setCacheBeanMetadata(boolean cacheBeanMetadata) {
0623:                this .cacheBeanMetadata = cacheBeanMetadata;
0624:            }
0625:
0626:            public boolean isCacheBeanMetadata() {
0627:                return this .cacheBeanMetadata;
0628:            }
0629:
0630:            public void addPropertyEditorRegistrar(
0631:                    PropertyEditorRegistrar registrar) {
0632:                Assert.notNull(registrar,
0633:                        "PropertyEditorRegistrar must not be null");
0634:                this .propertyEditorRegistrars.add(registrar);
0635:            }
0636:
0637:            /**
0638:             * Return the set of PropertyEditorRegistrars.
0639:             */
0640:            public Set getPropertyEditorRegistrars() {
0641:                return this .propertyEditorRegistrars;
0642:            }
0643:
0644:            public void registerCustomEditor(Class requiredType,
0645:                    PropertyEditor propertyEditor) {
0646:                Assert.notNull(requiredType, "Required type must not be null");
0647:                Assert.notNull(propertyEditor,
0648:                        "PropertyEditor must not be null");
0649:                this .customEditors.put(requiredType, propertyEditor);
0650:            }
0651:
0652:            /**
0653:             * Return the map of custom editors, with Classes as keys
0654:             * and PropertyEditors as values.
0655:             */
0656:            public Map getCustomEditors() {
0657:                return this .customEditors;
0658:            }
0659:
0660:            public void setTypeConverter(TypeConverter typeConverter) {
0661:                this .typeConverter = typeConverter;
0662:            }
0663:
0664:            /**
0665:             * Return the custom TypeConverter to use, if any.
0666:             * @return the custom TypeConverter, or <code>null</code> if none specified
0667:             */
0668:            protected TypeConverter getCustomTypeConverter() {
0669:                return this .typeConverter;
0670:            }
0671:
0672:            public TypeConverter getTypeConverter() {
0673:                TypeConverter customConverter = getCustomTypeConverter();
0674:                if (customConverter != null) {
0675:                    return customConverter;
0676:                } else {
0677:                    // Build default TypeConverter, registering custom editors.
0678:                    SimpleTypeConverter typeConverter = new SimpleTypeConverter();
0679:                    registerCustomEditors(typeConverter);
0680:                    return typeConverter;
0681:                }
0682:            }
0683:
0684:            public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
0685:                Assert.notNull(beanPostProcessor,
0686:                        "BeanPostProcessor must not be null");
0687:                this .beanPostProcessors.add(beanPostProcessor);
0688:                if (beanPostProcessor instanceof  InstantiationAwareBeanPostProcessor) {
0689:                    this .hasInstantiationAwareBeanPostProcessors = true;
0690:                }
0691:                if (beanPostProcessor instanceof  DestructionAwareBeanPostProcessor) {
0692:                    this .hasDestructionAwareBeanPostProcessors = true;
0693:                }
0694:            }
0695:
0696:            public int getBeanPostProcessorCount() {
0697:                return this .beanPostProcessors.size();
0698:            }
0699:
0700:            /**
0701:             * Return the list of BeanPostProcessors that will get applied
0702:             * to beans created with this factory.
0703:             */
0704:            public List getBeanPostProcessors() {
0705:                return this .beanPostProcessors;
0706:            }
0707:
0708:            /**
0709:             * Return whether this factory holds a InstantiationAwareBeanPostProcessor
0710:             * that will get applied to singleton beans on shutdown.
0711:             * @see #addBeanPostProcessor
0712:             * @see org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor
0713:             */
0714:            protected boolean hasInstantiationAwareBeanPostProcessors() {
0715:                return this .hasInstantiationAwareBeanPostProcessors;
0716:            }
0717:
0718:            /**
0719:             * Return whether this factory holds a DestructionAwareBeanPostProcessor
0720:             * that will get applied to singleton beans on shutdown.
0721:             * @see #addBeanPostProcessor
0722:             * @see org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor
0723:             */
0724:            protected boolean hasDestructionAwareBeanPostProcessors() {
0725:                return this .hasDestructionAwareBeanPostProcessors;
0726:            }
0727:
0728:            public void registerScope(String scopeName, Scope scope) {
0729:                Assert.notNull(scopeName, "Scope identifier must not be null");
0730:                Assert.notNull(scope, "Scope must not be null");
0731:                if (SCOPE_SINGLETON.equals(scopeName)
0732:                        || SCOPE_PROTOTYPE.equals(scopeName)) {
0733:                    throw new IllegalArgumentException(
0734:                            "Cannot replace existing scopes 'singleton' and 'prototype'");
0735:                }
0736:                this .scopes.put(scopeName, scope);
0737:            }
0738:
0739:            public String[] getRegisteredScopeNames() {
0740:                return StringUtils.toStringArray(this .scopes.keySet());
0741:            }
0742:
0743:            public Scope getRegisteredScope(String scopeName) {
0744:                Assert.notNull(scopeName, "Scope identifier must not be null");
0745:                return (Scope) this .scopes.get(scopeName);
0746:            }
0747:
0748:            public void copyConfigurationFrom(
0749:                    ConfigurableBeanFactory otherFactory) {
0750:                Assert.notNull(otherFactory, "BeanFactory must not be null");
0751:                setBeanClassLoader(otherFactory.getBeanClassLoader());
0752:                setCacheBeanMetadata(otherFactory.isCacheBeanMetadata());
0753:                if (otherFactory instanceof  AbstractBeanFactory) {
0754:                    AbstractBeanFactory otherAbstractFactory = (AbstractBeanFactory) otherFactory;
0755:                    this .customEditors
0756:                            .putAll(otherAbstractFactory.customEditors);
0757:                    this .propertyEditorRegistrars
0758:                            .addAll(otherAbstractFactory.propertyEditorRegistrars);
0759:                    this .beanPostProcessors
0760:                            .addAll(otherAbstractFactory.beanPostProcessors);
0761:                    this .hasInstantiationAwareBeanPostProcessors = this .hasInstantiationAwareBeanPostProcessors
0762:                            || otherAbstractFactory.hasInstantiationAwareBeanPostProcessors;
0763:                    this .hasDestructionAwareBeanPostProcessors = this .hasDestructionAwareBeanPostProcessors
0764:                            || otherAbstractFactory.hasDestructionAwareBeanPostProcessors;
0765:                    this .scopes.putAll(otherAbstractFactory.scopes);
0766:                }
0767:            }
0768:
0769:            public void registerAlias(String beanName, String alias)
0770:                    throws BeanDefinitionStoreException {
0771:                Assert.hasText(beanName, "'beanName' must not be empty");
0772:                Assert.hasText(alias, "'alias' must not be empty");
0773:                if (!alias.equals(beanName)) {
0774:                    // Only actually register the alias if it is not equal to the bean name itself.
0775:                    if (logger.isDebugEnabled()) {
0776:                        logger.debug("Registering alias '" + alias
0777:                                + "' for bean with name '" + beanName + "'");
0778:                    }
0779:                    synchronized (this .aliasMap) {
0780:                        String registeredName = (String) this .aliasMap
0781:                                .get(alias);
0782:                        if (registeredName != null
0783:                                && !registeredName.equals(beanName)) {
0784:                            throw new BeanDefinitionStoreException(
0785:                                    "Cannot register alias '"
0786:                                            + alias
0787:                                            + "' for bean name '"
0788:                                            + beanName
0789:                                            + "': It is already registered for bean name '"
0790:                                            + registeredName + "'.");
0791:                        }
0792:                        this .aliasMap.put(alias, beanName);
0793:                    }
0794:                }
0795:            }
0796:
0797:            public void resolveAliases(StringValueResolver valueResolver) {
0798:                Assert.notNull(valueResolver,
0799:                        "StringValueResolver must not be null");
0800:                synchronized (this .aliasMap) {
0801:                    Map aliasCopy = new HashMap(this .aliasMap);
0802:                    for (Iterator it = aliasCopy.keySet().iterator(); it
0803:                            .hasNext();) {
0804:                        String alias = (String) it.next();
0805:                        String registeredName = (String) aliasCopy.get(alias);
0806:                        String resolvedAlias = valueResolver
0807:                                .resolveStringValue(alias);
0808:                        String resolvedName = valueResolver
0809:                                .resolveStringValue(registeredName);
0810:                        if (!resolvedAlias.equals(alias)) {
0811:                            String existingName = (String) this .aliasMap
0812:                                    .get(resolvedAlias);
0813:                            if (existingName != null
0814:                                    && !existingName.equals(resolvedName)) {
0815:                                throw new BeanDefinitionStoreException(
0816:                                        "Cannot register resolved alias '"
0817:                                                + resolvedAlias
0818:                                                + "' (original: '"
0819:                                                + alias
0820:                                                + "') for bean name '"
0821:                                                + resolvedName
0822:                                                + "': It is already registered for bean name '"
0823:                                                + registeredName + "'.");
0824:                            }
0825:                            this .aliasMap.put(resolvedAlias, resolvedName);
0826:                            this .aliasMap.remove(alias);
0827:                        } else if (!registeredName.equals(resolvedName)) {
0828:                            this .aliasMap.put(alias, resolvedName);
0829:                        }
0830:                    }
0831:                }
0832:            }
0833:
0834:            /**
0835:             * Return a 'merged' BeanDefinition for the given bean name,
0836:             * merging a child bean definition with its parent if necessary.
0837:             * <p>This <code>getMergedBeanDefinition</code> considers bean definition
0838:             * in ancestors as well.
0839:             * @param name the name of the bean to retrieve the merged definition for
0840:             * (may be an alias)
0841:             * @return a (potentially merged) RootBeanDefinition for the given bean
0842:             * @throws NoSuchBeanDefinitionException if there is no bean with the given name
0843:             * @throws BeanDefinitionStoreException in case of an invalid bean definition
0844:             */
0845:            public BeanDefinition getMergedBeanDefinition(String name)
0846:                    throws BeansException {
0847:                String beanName = transformedBeanName(name);
0848:
0849:                // Efficiently check whether bean definition exists in this factory.
0850:                if (!containsBeanDefinition(beanName)
0851:                        && getParentBeanFactory() instanceof  ConfigurableBeanFactory) {
0852:                    return ((ConfigurableBeanFactory) getParentBeanFactory())
0853:                            .getMergedBeanDefinition(beanName);
0854:                }
0855:                // Resolve merged bean definition locally.
0856:                return getMergedLocalBeanDefinition(beanName);
0857:            }
0858:
0859:            /**
0860:             * Callback before prototype creation.
0861:             * <p>The default implementation register the prototype as currently in creation.
0862:             * @param beanName the name of the prototype about to be created
0863:             * @see #isPrototypeCurrentlyInCreation
0864:             */
0865:            protected void beforePrototypeCreation(String beanName) {
0866:                Object curVal = this .prototypesCurrentlyInCreation.get();
0867:                if (curVal == null) {
0868:                    this .prototypesCurrentlyInCreation.set(beanName);
0869:                } else if (curVal instanceof  String) {
0870:                    Set beanNameSet = new HashSet(2);
0871:                    beanNameSet.add(curVal);
0872:                    beanNameSet.add(beanName);
0873:                    this .prototypesCurrentlyInCreation.set(beanNameSet);
0874:                } else {
0875:                    Set beanNameSet = (Set) curVal;
0876:                    beanNameSet.add(beanName);
0877:                }
0878:            }
0879:
0880:            /**
0881:             * Callback after prototype creation.
0882:             * <p>The default implementation marks the prototype as not in creation anymore.
0883:             * @param beanName the name of the prototype that has been created
0884:             * @see #isPrototypeCurrentlyInCreation
0885:             */
0886:            protected void afterPrototypeCreation(String beanName) {
0887:                Object curVal = this .prototypesCurrentlyInCreation.get();
0888:                if (curVal instanceof  String) {
0889:                    this .prototypesCurrentlyInCreation.set(null);
0890:                } else if (curVal instanceof  Set) {
0891:                    Set beanNameSet = (Set) curVal;
0892:                    beanNameSet.remove(beanName);
0893:                    if (beanNameSet.isEmpty()) {
0894:                        this .prototypesCurrentlyInCreation.set(null);
0895:                    }
0896:                }
0897:            }
0898:
0899:            /**
0900:             * Return whether the specified prototype bean is currently in creation
0901:             * (within the current thread).
0902:             * @param beanName the name of the bean
0903:             */
0904:            protected final boolean isPrototypeCurrentlyInCreation(
0905:                    String beanName) {
0906:                Object curVal = this .prototypesCurrentlyInCreation.get();
0907:                return (curVal != null && (curVal.equals(beanName) || (curVal instanceof  Set && ((Set) curVal)
0908:                        .contains(beanName))));
0909:            }
0910:
0911:            public boolean isCurrentlyInCreation(String beanName) {
0912:                return isSingletonCurrentlyInCreation(beanName)
0913:                        || isPrototypeCurrentlyInCreation(beanName);
0914:            }
0915:
0916:            public void destroyBean(String beanName, Object beanInstance) {
0917:                destroyBean(beanName, beanInstance,
0918:                        getMergedLocalBeanDefinition(beanName));
0919:            }
0920:
0921:            /**
0922:             * Destroy the given bean instance (usually a prototype instance
0923:             * obtained from this factory) according to the given bean definition.
0924:             * @param beanName the name of the bean definition
0925:             * @param beanInstance the bean instance to destroy
0926:             * @param mbd the merged bean definition
0927:             */
0928:            protected void destroyBean(String beanName, Object beanInstance,
0929:                    RootBeanDefinition mbd) {
0930:                new DisposableBeanAdapter(beanInstance, beanName, mbd,
0931:                        getBeanPostProcessors()).destroy();
0932:            }
0933:
0934:            public void destroyScopedBean(String beanName) {
0935:                RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
0936:                if (mbd.isSingleton() || mbd.isPrototype()) {
0937:                    throw new IllegalArgumentException("Bean name '" + beanName
0938:                            + "' does not correspond to an object in a Scope");
0939:                }
0940:                String scopeName = mbd.getScope();
0941:                Scope scope = (Scope) this .scopes.get(scopeName);
0942:                if (scope == null) {
0943:                    throw new IllegalStateException(
0944:                            "No Scope registered for scope '" + scopeName + "'");
0945:                }
0946:                Object bean = scope.remove(beanName);
0947:                if (bean != null) {
0948:                    destroyBean(beanName, bean, mbd);
0949:                }
0950:            }
0951:
0952:            //---------------------------------------------------------------------
0953:            // Implementation methods
0954:            //---------------------------------------------------------------------
0955:
0956:            /**
0957:             * Return the bean name, stripping out the factory dereference prefix if necessary,
0958:             * and resolving aliases to canonical names.
0959:             * @param name the user-specified name
0960:             * @return the transformed bean name
0961:             */
0962:            protected String transformedBeanName(String name) {
0963:                String canonicalName = BeanFactoryUtils
0964:                        .transformedBeanName(name);
0965:                // Handle aliasing.
0966:                String resolvedName = null;
0967:                do {
0968:                    resolvedName = (String) this .aliasMap.get(canonicalName);
0969:                    if (resolvedName != null) {
0970:                        canonicalName = resolvedName;
0971:                    }
0972:                } while (resolvedName != null);
0973:                return canonicalName;
0974:            }
0975:
0976:            /**
0977:             * Determine the original bean name, resolving locally defined aliases to canonical names.
0978:             * @param name the user-specified name
0979:             * @return the original bean name
0980:             */
0981:            protected String originalBeanName(String name) {
0982:                String beanName = transformedBeanName(name);
0983:                if (name.startsWith(FACTORY_BEAN_PREFIX)) {
0984:                    beanName = FACTORY_BEAN_PREFIX + beanName;
0985:                }
0986:                return beanName;
0987:            }
0988:
0989:            /**
0990:             * Determine whether this given bean name is defines as an alias
0991:             * (as opposed to the name of an actual bean definition).
0992:             * @param beanName the bean name to check
0993:             * @return whether the given name is an alias
0994:             */
0995:            protected boolean isAlias(String beanName) {
0996:                return this .aliasMap.containsKey(beanName);
0997:            }
0998:
0999:            /**
1000:             * Initialize the given BeanWrapper with the custom editors registered
1001:             * with this factory. To be called for BeanWrappers that will create
1002:             * and populate bean instances.
1003:             * <p>The default implementation delegates to <code>registerCustomEditors</code>.
1004:             * Can be overridden in subclasses.
1005:             * @param bw the BeanWrapper to initialize
1006:             * @see #registerCustomEditors
1007:             */
1008:            protected void initBeanWrapper(BeanWrapper bw) {
1009:                registerCustomEditors(bw);
1010:            }
1011:
1012:            /**
1013:             * Initialize the given PropertyEditorRegistry with the custom editors
1014:             * registered with this BeanFactory.
1015:             * <p>To be called for BeanWrappers that will create and populate bean
1016:             * instances, and for SimpleTypeConverter used for constructor argument
1017:             * and factory method type conversion.
1018:             * @param registry the PropertyEditorRegistry to initialize
1019:             */
1020:            protected void registerCustomEditors(PropertyEditorRegistry registry) {
1021:                PropertyEditorRegistrySupport registrySupport = (registry instanceof  PropertyEditorRegistrySupport ? (PropertyEditorRegistrySupport) registry
1022:                        : null);
1023:                if (registrySupport != null) {
1024:                    registrySupport.useConfigValueEditors();
1025:                }
1026:                if (!this .propertyEditorRegistrars.isEmpty()) {
1027:                    for (Iterator it = this .propertyEditorRegistrars.iterator(); it
1028:                            .hasNext();) {
1029:                        PropertyEditorRegistrar registrar = (PropertyEditorRegistrar) it
1030:                                .next();
1031:                        try {
1032:                            registrar.registerCustomEditors(registry);
1033:                        } catch (BeanCreationException ex) {
1034:                            Throwable rootCause = ex.getMostSpecificCause();
1035:                            if (rootCause instanceof  BeanCurrentlyInCreationException) {
1036:                                BeanCreationException bce = (BeanCreationException) rootCause;
1037:                                if (isCurrentlyInCreation(bce.getBeanName())) {
1038:                                    if (logger.isDebugEnabled()) {
1039:                                        logger
1040:                                                .debug("PropertyEditorRegistrar ["
1041:                                                        + registrar.getClass()
1042:                                                                .getName()
1043:                                                        + "] failed because it tried to obtain currently created bean '"
1044:                                                        + ex.getBeanName()
1045:                                                        + "': "
1046:                                                        + ex.getMessage());
1047:                                    }
1048:                                    onSuppressedException(ex);
1049:                                    continue;
1050:                                }
1051:                            }
1052:                            throw ex;
1053:                        }
1054:                    }
1055:                }
1056:                if (!this .customEditors.isEmpty()) {
1057:                    for (Iterator it = this .customEditors.entrySet().iterator(); it
1058:                            .hasNext();) {
1059:                        Map.Entry entry = (Map.Entry) it.next();
1060:                        Class clazz = (Class) entry.getKey();
1061:                        PropertyEditor editor = (PropertyEditor) entry
1062:                                .getValue();
1063:                        // Register the editor as shared instance, if possible,
1064:                        // to make it clear that it might be used concurrently.
1065:                        if (registrySupport != null) {
1066:                            registrySupport.registerSharedEditor(clazz, editor);
1067:                        } else {
1068:                            registry.registerCustomEditor(clazz, editor);
1069:                        }
1070:                    }
1071:                }
1072:            }
1073:
1074:            /**
1075:             * Return a merged RootBeanDefinition, traversing the parent bean definition
1076:             * if the specified bean corresponds to a child bean definition.
1077:             * @param beanName the name of the bean to retrieve the merged definition for
1078:             * @return a (potentially merged) RootBeanDefinition for the given bean
1079:             * @throws NoSuchBeanDefinitionException if there is no bean with the given name
1080:             * @throws BeanDefinitionStoreException in case of an invalid bean definition
1081:             */
1082:            protected RootBeanDefinition getMergedLocalBeanDefinition(
1083:                    String beanName) throws BeansException {
1084:                // Quick check on the concurrent map first, with minimal locking.
1085:                RootBeanDefinition mbd = (RootBeanDefinition) this .mergedBeanDefinitions
1086:                        .get(beanName);
1087:                if (mbd != null) {
1088:                    return mbd;
1089:                }
1090:                return getMergedBeanDefinition(beanName,
1091:                        getBeanDefinition(beanName));
1092:            }
1093:
1094:            /**
1095:             * Return a RootBeanDefinition for the given top-level bean, by merging with
1096:             * the parent if the given bean's definition is a child bean definition.
1097:             * @param beanName the name of the bean definition
1098:             * @param bd the original bean definition (Root/ChildBeanDefinition)
1099:             * @return a (potentially merged) RootBeanDefinition for the given bean
1100:             * @throws BeanDefinitionStoreException in case of an invalid bean definition
1101:             */
1102:            protected RootBeanDefinition getMergedBeanDefinition(
1103:                    String beanName, BeanDefinition bd)
1104:                    throws BeanDefinitionStoreException {
1105:
1106:                return getMergedBeanDefinition(beanName, bd, null);
1107:            }
1108:
1109:            /**
1110:             * Return a RootBeanDefinition for the given bean, by merging with the
1111:             * parent if the given bean's definition is a child bean definition.
1112:             * @param beanName the name of the bean definition
1113:             * @param bd the original bean definition (Root/ChildBeanDefinition)
1114:             * @param containingBd the containing bean definition in case of inner bean,
1115:             * or <code>null</code> in case of a top-level bean
1116:             * @return a (potentially merged) RootBeanDefinition for the given bean
1117:             * @throws BeanDefinitionStoreException in case of an invalid bean definition
1118:             */
1119:            protected RootBeanDefinition getMergedBeanDefinition(
1120:                    String beanName, BeanDefinition bd,
1121:                    BeanDefinition containingBd)
1122:                    throws BeanDefinitionStoreException {
1123:
1124:                synchronized (this .mergedBeanDefinitions) {
1125:                    RootBeanDefinition mbd = null;
1126:
1127:                    // Check with full lock now in order to enforce the same merged instance.
1128:                    if (containingBd == null) {
1129:                        mbd = (RootBeanDefinition) this .mergedBeanDefinitions
1130:                                .get(beanName);
1131:                    }
1132:
1133:                    if (mbd == null) {
1134:                        if (bd.getParentName() == null) {
1135:                            // Use copy of given root bean definition.
1136:                            mbd = new RootBeanDefinition(bd);
1137:                        } else {
1138:                            // Child bean definition: needs to be merged with parent.
1139:                            BeanDefinition pbd = null;
1140:                            try {
1141:                                String parentBeanName = transformedBeanName(bd
1142:                                        .getParentName());
1143:                                if (!beanName.equals(parentBeanName)) {
1144:                                    pbd = getMergedBeanDefinition(parentBeanName);
1145:                                } else {
1146:                                    if (getParentBeanFactory() instanceof  ConfigurableBeanFactory) {
1147:                                        pbd = ((ConfigurableBeanFactory) getParentBeanFactory())
1148:                                                .getMergedBeanDefinition(parentBeanName);
1149:                                    } else {
1150:                                        throw new NoSuchBeanDefinitionException(
1151:                                                bd.getParentName(),
1152:                                                "Parent name '"
1153:                                                        + bd.getParentName()
1154:                                                        + "' is equal to bean name '"
1155:                                                        + beanName
1156:                                                        + "': cannot be resolved without an AbstractBeanFactory parent");
1157:                                    }
1158:                                }
1159:                            } catch (NoSuchBeanDefinitionException ex) {
1160:                                throw new BeanDefinitionStoreException(bd
1161:                                        .getResourceDescription(), beanName,
1162:                                        "Could not resolve parent bean definition '"
1163:                                                + bd.getParentName() + "'", ex);
1164:                            }
1165:                            // Deep copy with overridden values.
1166:                            mbd = new RootBeanDefinition(pbd);
1167:                            mbd.overrideFrom(bd);
1168:                        }
1169:
1170:                        // A bean contained in a non-singleton bean cannot be a singleton itself.
1171:                        // Let's correct this on the fly here, since this might be the result of
1172:                        // parent-child merging for the outer bean, in which case the original inner bean
1173:                        // definition will not have inherited the merged outer bean's singleton status.
1174:                        if (containingBd != null && !containingBd.isSingleton()
1175:                                && mbd.isSingleton()) {
1176:                            mbd.setScope(containingBd.getScope());
1177:                        }
1178:
1179:                        // Only cache the merged bean definition if we're already about to create an
1180:                        // instance of the bean, or at least have already created an instance before.
1181:                        if (containingBd == null && isCacheBeanMetadata()
1182:                                && this .alreadyCreated.contains(beanName)) {
1183:                            this .mergedBeanDefinitions.put(beanName, mbd);
1184:                        }
1185:                    }
1186:
1187:                    return mbd;
1188:                }
1189:            }
1190:
1191:            /**
1192:             * Check the given merged bean definition,
1193:             * potentially throwing validation exceptions.
1194:             * @param mbd the merged bean definition to check
1195:             * @param beanName the name of the bean
1196:             * @param args the arguments for bean creation, if any
1197:             * @throws BeanDefinitionStoreException in case of validation failure
1198:             */
1199:            protected void checkMergedBeanDefinition(RootBeanDefinition mbd,
1200:                    String beanName, Object[] args)
1201:                    throws BeanDefinitionStoreException {
1202:
1203:                // check if bean definition is not abstract
1204:                if (mbd.isAbstract()) {
1205:                    throw new BeanIsAbstractException(beanName);
1206:                }
1207:
1208:                // Check validity of the usage of the args parameter. This can
1209:                // only be used for prototypes constructed via a factory method.
1210:                if (args != null && !mbd.isPrototype()) {
1211:                    throw new BeanDefinitionStoreException(
1212:                            "Can only specify arguments for the getBean method when referring to a prototype bean definition");
1213:                }
1214:            }
1215:
1216:            /**
1217:             * Remove the merged bean definition for the specified bean,
1218:             * recreating it on next access.
1219:             * @param beanName the bean name to clear the merged definition for
1220:             */
1221:            protected void clearMergedBeanDefinition(String beanName) {
1222:                this .mergedBeanDefinitions.remove(beanName);
1223:            }
1224:
1225:            /**
1226:             * Resolve the bean class for the specified bean definition,
1227:             * resolving a bean class name into a Class reference (if necessary)
1228:             * and storing the resolved Class in the bean definition for further use.
1229:             * @param mbd the merged bean definition to determine the class for
1230:             * @param beanName the name of the bean (for error handling purposes)
1231:             * @return the resolved bean class (or <code>null</code> if none)
1232:             * @throws CannotLoadBeanClassException if we failed to load the class
1233:             */
1234:            protected Class resolveBeanClass(RootBeanDefinition mbd,
1235:                    String beanName) {
1236:                return resolveBeanClass(mbd, beanName, false);
1237:            }
1238:
1239:            /**
1240:             * Resolve the bean class for the specified bean definition,
1241:             * resolving a bean class name into a Class reference (if necessary)
1242:             * and storing the resolved Class in the bean definition for further use.
1243:             * @param mbd the merged bean definition to determine the class for
1244:             * @param beanName the name of the bean (for error handling purposes)
1245:             * @param typeMatchOnly whether the returned {@link Class} is only used
1246:             * for internal type matching purposes (that is, never exposed to application code)
1247:             * @return the resolved bean class (or <code>null</code> if none)
1248:             * @throws CannotLoadBeanClassException if we failed to load the class
1249:             */
1250:            protected Class resolveBeanClass(RootBeanDefinition mbd,
1251:                    String beanName, boolean typeMatchOnly)
1252:                    throws CannotLoadBeanClassException {
1253:                try {
1254:                    if (mbd.hasBeanClass()) {
1255:                        return mbd.getBeanClass();
1256:                    }
1257:                    if (typeMatchOnly && getTempClassLoader() != null) {
1258:                        String className = mbd.getBeanClassName();
1259:                        return (className != null ? ClassUtils.forName(
1260:                                className, getTempClassLoader()) : null);
1261:                    }
1262:                    return mbd.resolveBeanClass(getBeanClassLoader());
1263:                } catch (ClassNotFoundException ex) {
1264:                    throw new CannotLoadBeanClassException(mbd
1265:                            .getResourceDescription(), beanName, mbd
1266:                            .getBeanClassName(), ex);
1267:                } catch (LinkageError err) {
1268:                    throw new CannotLoadBeanClassException(mbd
1269:                            .getResourceDescription(), beanName, mbd
1270:                            .getBeanClassName(), err);
1271:                }
1272:            }
1273:
1274:            /**
1275:             * Predict the eventual bean type (of the processed bean instance) for the
1276:             * specified bean. Called by {@link #getType} and {@link #isTypeMatch}.
1277:             * Does not need to handle FactoryBeans specifically, since it is only
1278:             * supposed to operate on the raw bean type.
1279:             * <p>This implementation is simplistic in that it is not able to
1280:             * handle factory methods and InstantiationAwareBeanPostProcessors.
1281:             * It only predicts the bean type correctly for a standard bean.
1282:             * To be overridden in subclasses, applying more sophisticated type detection.
1283:             * @param beanName the name of the bean
1284:             * @param mbd the merged bean definition to determine the type for
1285:             * @param typeMatchOnly whether the predicated is only used for internal
1286:             * type matching purposes (i.e. never exposed to application code)
1287:             * @return the type of the bean, or <code>null</code> if not predictable
1288:             */
1289:            protected Class predictBeanType(String beanName,
1290:                    RootBeanDefinition mbd, boolean typeMatchOnly) {
1291:                if (mbd.getFactoryMethodName() != null) {
1292:                    return null;
1293:                }
1294:                return resolveBeanClass(mbd, beanName, typeMatchOnly);
1295:            }
1296:
1297:            /**
1298:             * Determine the bean type for the given FactoryBean definition, as far as possible.
1299:             * Only called if there is no singleton instance registered for the target bean already.
1300:             * <p>The default implementation creates the FactoryBean via <code>getBean</code>
1301:             * to call its <code>getObjectType</code> method. Subclasses are encouraged to optimize
1302:             * this, typically by just instantiating the FactoryBean but not populating it yet,
1303:             * trying whether its <code>getObjectType</code> method already returns a type.
1304:             * If no type found, a full FactoryBean creation as performed by this implementation
1305:             * should be used as fallback.
1306:             * @param beanName the name of the bean
1307:             * @param mbd the merged bean definition for the bean
1308:             * @return the type for the bean if determinable, or <code>null</code> else
1309:             * @see org.springframework.beans.factory.FactoryBean#getObjectType()
1310:             * @see #getBean(String)
1311:             */
1312:            protected Class getTypeForFactoryBean(String beanName,
1313:                    RootBeanDefinition mbd) {
1314:                if (!mbd.isSingleton()) {
1315:                    return null;
1316:                }
1317:                try {
1318:                    FactoryBean factoryBean = (FactoryBean) getBean(FACTORY_BEAN_PREFIX
1319:                            + beanName);
1320:                    return getTypeForFactoryBean(factoryBean);
1321:                } catch (BeanCreationException ex) {
1322:                    // Can only happen when getting a FactoryBean.
1323:                    logger
1324:                            .debug(
1325:                                    "Ignoring bean creation exception on FactoryBean type check",
1326:                                    ex);
1327:                    onSuppressedException(ex);
1328:                    return null;
1329:                }
1330:            }
1331:
1332:            /**
1333:             * Determine the type for the given FactoryBean.
1334:             * @param factoryBean the FactoryBean instance to check
1335:             * @return the FactoryBean's object type,
1336:             * or <code>null</code> if the type cannot be determined yet
1337:             */
1338:            protected Class getTypeForFactoryBean(FactoryBean factoryBean) {
1339:                try {
1340:                    return factoryBean.getObjectType();
1341:                } catch (Throwable ex) {
1342:                    // Thrown from the FactoryBean's getObjectType implementation.
1343:                    logger
1344:                            .warn(
1345:                                    "FactoryBean threw exception from getObjectType, despite the contract saying "
1346:                                            + "that it should return null if the type of its object cannot be determined yet",
1347:                                    ex);
1348:                    return null;
1349:                }
1350:            }
1351:
1352:            /**
1353:             * Get the object for the given bean instance, either the bean
1354:             * instance itself or its created object in case of a FactoryBean.
1355:             * @param beanInstance the shared bean instance
1356:             * @param name name that may include factory dereference prefix
1357:             * @param beanName the canonical bean name
1358:             * @return the object to expose for the bean
1359:             */
1360:            protected Object getObjectForBeanInstance(Object beanInstance,
1361:                    String name, String beanName) {
1362:                // Don't let calling code try to dereference the
1363:                // bean factory if the bean isn't a factory.
1364:                if (BeanFactoryUtils.isFactoryDereference(name)
1365:                        && !(beanInstance instanceof  FactoryBean)) {
1366:                    throw new BeanIsNotAFactoryException(
1367:                            transformedBeanName(name), beanInstance.getClass());
1368:                }
1369:
1370:                Object object = beanInstance;
1371:
1372:                // Now we have the bean instance, which may be a normal bean or a FactoryBean.
1373:                // If it's a FactoryBean, we use it to create a bean instance, unless the
1374:                // caller actually wants a reference to the factory.
1375:                if (beanInstance instanceof  FactoryBean) {
1376:                    if (!BeanFactoryUtils.isFactoryDereference(name)) {
1377:                        // Return bean instance from factory.
1378:                        FactoryBean factory = (FactoryBean) beanInstance;
1379:                        // Cache object obtained from FactoryBean if it is a singleton.
1380:                        RootBeanDefinition mbd = (containsBeanDefinition(beanName) ? getMergedLocalBeanDefinition(beanName)
1381:                                : null);
1382:                        boolean shared = (mbd == null || mbd.isSingleton());
1383:                        if (shared && factory.isSingleton()) {
1384:                            synchronized (getSingletonMutex()) {
1385:                                object = this .factoryBeanObjectCache
1386:                                        .get(beanName);
1387:                                if (object == null) {
1388:                                    object = getObjectFromFactoryBean(factory,
1389:                                            beanName, mbd);
1390:                                    this .factoryBeanObjectCache.put(beanName,
1391:                                            object);
1392:                                }
1393:                            }
1394:                        } else {
1395:                            object = getObjectFromFactoryBean(factory,
1396:                                    beanName, mbd);
1397:                        }
1398:                    }
1399:                }
1400:
1401:                return object;
1402:            }
1403:
1404:            /**
1405:             * Obtain an object to expose from the given FactoryBean.
1406:             * @param factory the FactoryBean instance
1407:             * @param beanName the name of the bean
1408:             * @param mbd the merged bean definition
1409:             * @return the object obtained from the FactoryBean
1410:             * @throws BeanCreationException if FactoryBean object creation failed
1411:             * @see org.springframework.beans.factory.FactoryBean#getObject()
1412:             */
1413:            protected Object getObjectFromFactoryBean(
1414:                    final FactoryBean factory, final String beanName,
1415:                    final RootBeanDefinition mbd) throws BeanCreationException {
1416:
1417:                return AccessController.doPrivileged(new PrivilegedAction() {
1418:                    public Object run() {
1419:                        Object object;
1420:
1421:                        try {
1422:                            object = factory.getObject();
1423:                        } catch (FactoryBeanNotInitializedException ex) {
1424:                            throw new BeanCurrentlyInCreationException(
1425:                                    beanName, ex.toString());
1426:                        } catch (Throwable ex) {
1427:                            throw new BeanCreationException(
1428:                                    beanName,
1429:                                    "FactoryBean threw exception on object creation",
1430:                                    ex);
1431:                        }
1432:
1433:                        // Do not accept a null value for a FactoryBean that's not fully
1434:                        // initialized yet: Many FactoryBeans just return null then.
1435:                        if (object == null
1436:                                && isSingletonCurrentlyInCreation(beanName)) {
1437:                            throw new BeanCurrentlyInCreationException(
1438:                                    beanName,
1439:                                    "FactoryBean which is currently in creation returned null from getObject");
1440:                        }
1441:
1442:                        if (object != null
1443:                                && (mbd == null || !mbd.isSynthetic())) {
1444:                            try {
1445:                                object = postProcessObjectFromFactoryBean(
1446:                                        object, beanName);
1447:                            } catch (Throwable ex) {
1448:                                throw new BeanCreationException(
1449:                                        mbd.getResourceDescription(),
1450:                                        beanName,
1451:                                        "Post-processing of the FactoryBean's object failed",
1452:                                        ex);
1453:                            }
1454:                        }
1455:
1456:                        return object;
1457:                    }
1458:                });
1459:            }
1460:
1461:            /**
1462:             * Post-process the given object that has been obtained from the FactoryBean.
1463:             * The resulting object will get exposed for bean references.
1464:             * <p>The default implementation simply returns the given object as-is.
1465:             * Subclasses may override this, for example, to apply post-processors.
1466:             * @param object the object obtained from the FactoryBean.
1467:             * @param beanName the name of the bean
1468:             * @return the object to expose
1469:             * @throws BeansException if any post-processing failed
1470:             */
1471:            protected Object postProcessObjectFromFactoryBean(Object object,
1472:                    String beanName) throws BeansException {
1473:                return object;
1474:            }
1475:
1476:            public boolean isFactoryBean(String name)
1477:                    throws NoSuchBeanDefinitionException {
1478:                String beanName = transformedBeanName(name);
1479:
1480:                Object beanInstance = getSingleton(beanName);
1481:                if (beanInstance != null) {
1482:                    return (beanInstance instanceof  FactoryBean);
1483:                }
1484:
1485:                // No singleton instance found -> check bean definition.
1486:                if (!containsBeanDefinition(beanName)
1487:                        && getParentBeanFactory() instanceof  ConfigurableBeanFactory) {
1488:                    // No bean definition found in this factory -> delegate to parent.
1489:                    return ((ConfigurableBeanFactory) getParentBeanFactory())
1490:                            .isFactoryBean(name);
1491:                }
1492:
1493:                RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
1494:                Class beanClass = predictBeanType(beanName, mbd, true);
1495:                return (beanClass != null && FactoryBean.class
1496:                        .isAssignableFrom(beanClass));
1497:            }
1498:
1499:            /**
1500:             * Return whether the bean definition for the given bean name has been
1501:             * marked as a primary bean. 
1502:             */
1503:            protected boolean isPrimary(String beanName, Object beanInstance) {
1504:                return (containsBeanDefinition(beanName) && getMergedLocalBeanDefinition(
1505:                        beanName).isPrimary());
1506:            }
1507:
1508:            /**
1509:             * Determine whether the given bean name is already in use within this factory,
1510:             * i.e. whether there is a local bean registered under this name or an inner
1511:             * bean created with this name.
1512:             * @param beanName the name to check
1513:             */
1514:            public boolean isBeanNameInUse(String beanName) {
1515:                return containsLocalBean(beanName)
1516:                        || hasDependentBean(beanName);
1517:            }
1518:
1519:            /**
1520:             * Determine whether the given bean requires destruction on shutdown.
1521:             * <p>The default implementation checks the DisposableBean interface as well as
1522:             * a specified destroy method and registered DestructionAwareBeanPostProcessors.
1523:             * @param bean the bean instance to check
1524:             * @param mbd the corresponding bean definition
1525:             * @see org.springframework.beans.factory.DisposableBean
1526:             * @see AbstractBeanDefinition#getDestroyMethodName()
1527:             * @see org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor
1528:             */
1529:            protected boolean requiresDestruction(Object bean,
1530:                    RootBeanDefinition mbd) {
1531:                return (bean instanceof  DisposableBean
1532:                        || mbd.getDestroyMethodName() != null || hasDestructionAwareBeanPostProcessors());
1533:            }
1534:
1535:            /**
1536:             * Add the given bean to the list of disposable beans in this factory,
1537:             * registering its DisposableBean interface and/or the given destroy method
1538:             * to be called on factory shutdown (if applicable). Only applies to singletons.
1539:             * @param beanName the name of the bean
1540:             * @param bean the bean instance
1541:             * @param mbd the bean definition for the bean
1542:             * @see RootBeanDefinition#isSingleton
1543:             * @see RootBeanDefinition#getDependsOn
1544:             * @see #registerDisposableBean
1545:             * @see #registerDependentBean
1546:             */
1547:            protected void registerDisposableBeanIfNecessary(String beanName,
1548:                    Object bean, RootBeanDefinition mbd) {
1549:                if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
1550:                    if (mbd.isSingleton()) {
1551:                        // Register a DisposableBean implementation that performs all destruction
1552:                        // work for the given bean: DestructionAwareBeanPostProcessors,
1553:                        // DisposableBean interface, custom destroy method.
1554:                        registerDisposableBean(beanName,
1555:                                new DisposableBeanAdapter(bean, beanName, mbd,
1556:                                        getBeanPostProcessors()));
1557:                    } else {
1558:                        // A bean with a custom scope...
1559:                        Scope scope = (Scope) this .scopes.get(mbd.getScope());
1560:                        if (scope == null) {
1561:                            throw new IllegalStateException(
1562:                                    "No Scope registered for scope '"
1563:                                            + mbd.getScope() + "'");
1564:                        }
1565:                        scope.registerDestructionCallback(beanName,
1566:                                new DisposableBeanAdapter(bean, beanName, mbd,
1567:                                        getBeanPostProcessors()));
1568:                    }
1569:                }
1570:            }
1571:
1572:            /**
1573:             * Overridden to clear the FactoryBean object cache as well.
1574:             */
1575:            protected void removeSingleton(String beanName) {
1576:                super .removeSingleton(beanName);
1577:                this .factoryBeanObjectCache.remove(beanName);
1578:            }
1579:
1580:            //---------------------------------------------------------------------
1581:            // Abstract methods to be implemented by subclasses
1582:            //---------------------------------------------------------------------
1583:
1584:            /**
1585:             * Check if this bean factory contains a bean definition with the given name.
1586:             * Does not consider any hierarchy this factory may participate in.
1587:             * Invoked by <code>containsBean</code> when no cached singleton instance is found.
1588:             * <p>Depending on the nature of the concrete bean factory implementation,
1589:             * this operation might be expensive (for example, because of directory lookups
1590:             * in external registries). However, for listable bean factories, this usually
1591:             * just amounts to a local hash lookup: The operation is therefore part of the
1592:             * public interface there. The same implementation can serve for both this
1593:             * template method and the public interface method in that case.
1594:             * @param beanName the name of the bean to look for
1595:             * @return if this bean factory contains a bean definition with the given name
1596:             * @see #containsBean
1597:             * @see org.springframework.beans.factory.ListableBeanFactory#containsBeanDefinition
1598:             */
1599:            protected abstract boolean containsBeanDefinition(String beanName);
1600:
1601:            /**
1602:             * Return the bean definition for the given bean name.
1603:             * Subclasses should normally implement caching, as this method is invoked
1604:             * by this class every time bean definition metadata is needed.
1605:             * <p>Depending on the nature of the concrete bean factory implementation,
1606:             * this operation might be expensive (for example, because of directory lookups
1607:             * in external registries). However, for listable bean factories, this usually
1608:             * just amounts to a local hash lookup: The operation is therefore part of the
1609:             * public interface there. The same implementation can serve for both this
1610:             * template method and the public interface method in that case.
1611:             * @param beanName the name of the bean to find a definition for
1612:             * @return the BeanDefinition for this prototype name (never <code>null</code>)
1613:             * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
1614:             * if the bean definition cannot be resolved
1615:             * @throws BeansException in case of errors
1616:             * @see RootBeanDefinition
1617:             * @see ChildBeanDefinition
1618:             * @see org.springframework.beans.factory.config.ConfigurableListableBeanFactory#getBeanDefinition
1619:             */
1620:            protected abstract BeanDefinition getBeanDefinition(String beanName)
1621:                    throws BeansException;
1622:
1623:            /**
1624:             * Create a bean instance for the given bean definition.
1625:             * The bean definition will already have been merged with the parent
1626:             * definition in case of a child definition.
1627:             * <p>All the other methods in this class invoke this method, although
1628:             * beans may be cached after being instantiated by this method. All bean
1629:             * instantiation within this class is performed by this method.
1630:             * @param beanName the name of the bean
1631:             * @param mbd the merged bean definition for the bean
1632:             * @param args arguments to use if creating a prototype using explicit arguments to a
1633:             * static factory method. This parameter must be <code>null</code> except in this case.
1634:             * @return a new instance of the bean
1635:             * @throws BeanCreationException if the bean could not be created
1636:             */
1637:            protected abstract Object createBean(String beanName,
1638:                    RootBeanDefinition mbd, Object[] args)
1639:                    throws BeanCreationException;
1640:
1641:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.