Source Code Cross Referenced for AbstractApplicationContext.java in  » J2EE » spring-framework-2.5 » org » springframework » context » 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.context.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.context.support;
0018:
0019:        import java.io.IOException;
0020:        import java.util.ArrayList;
0021:        import java.util.Collection;
0022:        import java.util.Collections;
0023:        import java.util.Date;
0024:        import java.util.HashMap;
0025:        import java.util.HashSet;
0026:        import java.util.Iterator;
0027:        import java.util.List;
0028:        import java.util.Locale;
0029:        import java.util.Map;
0030:
0031:        import org.apache.commons.logging.Log;
0032:        import org.apache.commons.logging.LogFactory;
0033:
0034:        import org.springframework.beans.BeanUtils;
0035:        import org.springframework.beans.BeansException;
0036:        import org.springframework.beans.factory.BeanFactory;
0037:        import org.springframework.beans.factory.BeanFactoryAware;
0038:        import org.springframework.beans.factory.DisposableBean;
0039:        import org.springframework.beans.factory.NoSuchBeanDefinitionException;
0040:        import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
0041:        import org.springframework.beans.factory.config.BeanDefinition;
0042:        import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
0043:        import org.springframework.beans.factory.config.BeanPostProcessor;
0044:        import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
0045:        import org.springframework.beans.factory.support.AbstractBeanDefinition;
0046:        import org.springframework.beans.support.ResourceEditorRegistrar;
0047:        import org.springframework.context.ApplicationContext;
0048:        import org.springframework.context.ApplicationContextAware;
0049:        import org.springframework.context.ApplicationEvent;
0050:        import org.springframework.context.ApplicationEventPublisher;
0051:        import org.springframework.context.ApplicationEventPublisherAware;
0052:        import org.springframework.context.ApplicationListener;
0053:        import org.springframework.context.ConfigurableApplicationContext;
0054:        import org.springframework.context.HierarchicalMessageSource;
0055:        import org.springframework.context.Lifecycle;
0056:        import org.springframework.context.MessageSource;
0057:        import org.springframework.context.MessageSourceAware;
0058:        import org.springframework.context.MessageSourceResolvable;
0059:        import org.springframework.context.NoSuchMessageException;
0060:        import org.springframework.context.ResourceLoaderAware;
0061:        import org.springframework.context.event.ApplicationEventMulticaster;
0062:        import org.springframework.context.event.ContextClosedEvent;
0063:        import org.springframework.context.event.ContextRefreshedEvent;
0064:        import org.springframework.context.event.ContextStartedEvent;
0065:        import org.springframework.context.event.ContextStoppedEvent;
0066:        import org.springframework.context.event.SimpleApplicationEventMulticaster;
0067:        import org.springframework.core.JdkVersion;
0068:        import org.springframework.core.OrderComparator;
0069:        import org.springframework.core.Ordered;
0070:        import org.springframework.core.PriorityOrdered;
0071:        import org.springframework.core.io.DefaultResourceLoader;
0072:        import org.springframework.core.io.Resource;
0073:        import org.springframework.core.io.ResourceLoader;
0074:        import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
0075:        import org.springframework.core.io.support.ResourcePatternResolver;
0076:        import org.springframework.util.Assert;
0077:        import org.springframework.util.ClassUtils;
0078:        import org.springframework.util.ObjectUtils;
0079:
0080:        /**
0081:         * Abstract implementation of the {@link org.springframework.context.ApplicationContext}
0082:         * interface. Doesn't mandate the type of storage used for configuration; simply
0083:         * implements common context functionality. Uses the Template Method design pattern,
0084:         * requiring concrete subclasses to implement abstract methods.
0085:         *
0086:         * <p>In contrast to a plain BeanFactory, an ApplicationContext is supposed
0087:         * to detect special beans defined in its internal bean factory:
0088:         * Therefore, this class automatically registers
0089:         * {@link org.springframework.beans.factory.config.BeanFactoryPostProcessor BeanFactoryPostProcessors},
0090:         * {@link org.springframework.beans.factory.config.BeanPostProcessor BeanPostProcessors}
0091:         * and {@link org.springframework.context.ApplicationListener ApplicationListeners}
0092:         * which are defined as beans in the context.
0093:         *
0094:         * <p>A {@link org.springframework.context.MessageSource} may also be supplied
0095:         * as a bean in the context, with the name "messageSource"; else, message
0096:         * resolution is delegated to the parent context. Furthermore, a multicaster
0097:         * for application events can be supplied as "applicationEventMulticaster" bean
0098:         * of type {@link org.springframework.context.event.ApplicationEventMulticaster}
0099:         * in the context; else, a default multicaster of type
0100:         * {@link org.springframework.context.event.SimpleApplicationEventMulticaster} will be used.
0101:         *
0102:         * <p>Implements resource loading through extending
0103:         * {@link org.springframework.core.io.DefaultResourceLoader}.
0104:         * Consequently treats non-URL resource paths as class path resources
0105:         * (supporting full class path resource names that include the package path,
0106:         * e.g. "mypackage/myresource.dat"), unless the {@link #getResourceByPath}
0107:         * method is overwritten in a subclass.
0108:         *
0109:         * @author Rod Johnson
0110:         * @author Juergen Hoeller
0111:         * @author Mark Fisher
0112:         * @since January 21, 2001
0113:         * @see #refreshBeanFactory
0114:         * @see #getBeanFactory
0115:         * @see org.springframework.beans.factory.config.BeanFactoryPostProcessor
0116:         * @see org.springframework.beans.factory.config.BeanPostProcessor
0117:         * @see org.springframework.context.event.ApplicationEventMulticaster
0118:         * @see org.springframework.context.ApplicationListener
0119:         * @see org.springframework.context.MessageSource
0120:         */
0121:        public abstract class AbstractApplicationContext extends
0122:                DefaultResourceLoader implements 
0123:                ConfigurableApplicationContext, DisposableBean {
0124:
0125:            /**
0126:             * Name of the MessageSource bean in the factory.
0127:             * If none is supplied, message resolution is delegated to the parent.
0128:             * @see MessageSource
0129:             */
0130:            public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";
0131:
0132:            /**
0133:             * Name of the ApplicationEventMulticaster bean in the factory.
0134:             * If none is supplied, a default SimpleApplicationEventMulticaster is used.
0135:             * @see org.springframework.context.event.ApplicationEventMulticaster
0136:             * @see org.springframework.context.event.SimpleApplicationEventMulticaster
0137:             */
0138:            public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";
0139:
0140:            static {
0141:                // Eagerly load the ContextClosedEvent class to avoid weird classloader issues
0142:                // on application shutdown in WebLogic 8.1. (Reported by Dustin Woods.)
0143:                ContextClosedEvent.class.getName();
0144:            }
0145:
0146:            /** Logger used by this class. Available to subclasses. */
0147:            protected final Log logger = LogFactory.getLog(getClass());
0148:
0149:            /** Parent context */
0150:            private ApplicationContext parent;
0151:
0152:            /** BeanFactoryPostProcessors to apply on refresh */
0153:            private final List beanFactoryPostProcessors = new ArrayList();
0154:
0155:            /** Display name */
0156:            private String displayName = ObjectUtils.identityToString(this );
0157:
0158:            /** System time in milliseconds when this context started */
0159:            private long startupDate;
0160:
0161:            /** Flag that indicates whether this context is currently active */
0162:            private boolean active = false;
0163:
0164:            /** Synchronization monitor for the "active" flag */
0165:            private final Object activeMonitor = new Object();
0166:
0167:            /** Synchronization monitor for the "refresh" and "destroy" */
0168:            private final Object startupShutdownMonitor = new Object();
0169:
0170:            /** Reference to the JVM shutdown hook, if registered */
0171:            private Thread shutdownHook;
0172:
0173:            /** ResourcePatternResolver used by this context */
0174:            private ResourcePatternResolver resourcePatternResolver;
0175:
0176:            /** MessageSource we delegate our implementation of this interface to */
0177:            private MessageSource messageSource;
0178:
0179:            /** Helper class used in event publishing */
0180:            private ApplicationEventMulticaster applicationEventMulticaster;
0181:
0182:            /** Statically specified listeners */
0183:            private List applicationListeners = new ArrayList();
0184:
0185:            /**
0186:             * Create a new AbstractApplicationContext with no parent.
0187:             */
0188:            public AbstractApplicationContext() {
0189:                this (null);
0190:            }
0191:
0192:            /**
0193:             * Create a new AbstractApplicationContext with the given parent context.
0194:             * @param parent the parent context
0195:             */
0196:            public AbstractApplicationContext(ApplicationContext parent) {
0197:                this .parent = parent;
0198:                this .resourcePatternResolver = getResourcePatternResolver();
0199:            }
0200:
0201:            //---------------------------------------------------------------------
0202:            // Implementation of ApplicationContext interface
0203:            //---------------------------------------------------------------------
0204:
0205:            /**
0206:             * Return the parent context, or <code>null</code> if there is no parent
0207:             * (that is, this context is the root of the context hierarchy).
0208:             */
0209:            public ApplicationContext getParent() {
0210:                return this .parent;
0211:            }
0212:
0213:            /**
0214:             * Return this context's internal bean factory as AutowireCapableBeanFactory,
0215:             * if already available.
0216:             * @see #getBeanFactory()
0217:             */
0218:            public AutowireCapableBeanFactory getAutowireCapableBeanFactory()
0219:                    throws IllegalStateException {
0220:                return getBeanFactory();
0221:            }
0222:
0223:            /**
0224:             * Set a friendly name for this context.
0225:             * Typically done during initialization of concrete context implementations.
0226:             */
0227:            public void setDisplayName(String displayName) {
0228:                this .displayName = displayName;
0229:            }
0230:
0231:            /**
0232:             * Return a friendly name for this context.
0233:             */
0234:            public String getDisplayName() {
0235:                return this .displayName;
0236:            }
0237:
0238:            /**
0239:             * Return the timestamp (ms) when this context was first loaded.
0240:             */
0241:            public long getStartupDate() {
0242:                return this .startupDate;
0243:            }
0244:
0245:            /**
0246:             * Publish the given event to all listeners.
0247:             * <p>Note: Listeners get initialized after the MessageSource, to be able
0248:             * to access it within listener implementations. Thus, MessageSource
0249:             * implementations cannot publish events.
0250:             * @param event the event to publish (may be application-specific or a
0251:             * standard framework event)
0252:             */
0253:            public void publishEvent(ApplicationEvent event) {
0254:                Assert.notNull(event, "Event must not be null");
0255:                if (logger.isDebugEnabled()) {
0256:                    logger.debug("Publishing event in context ["
0257:                            + ObjectUtils.identityToString(this ) + "]: "
0258:                            + event);
0259:                }
0260:                getApplicationEventMulticaster().multicastEvent(event);
0261:                if (this .parent != null) {
0262:                    this .parent.publishEvent(event);
0263:                }
0264:            }
0265:
0266:            /**
0267:             * Return the internal MessageSource used by the context.
0268:             * @return the internal MessageSource (never <code>null</code>)
0269:             * @throws IllegalStateException if the context has not been initialized yet
0270:             */
0271:            private ApplicationEventMulticaster getApplicationEventMulticaster()
0272:                    throws IllegalStateException {
0273:                if (this .applicationEventMulticaster == null) {
0274:                    throw new IllegalStateException(
0275:                            "ApplicationEventMulticaster not initialized - "
0276:                                    + "call 'refresh' before multicasting events via the context: "
0277:                                    + this );
0278:                }
0279:                return this .applicationEventMulticaster;
0280:            }
0281:
0282:            /**
0283:             * Return the ResourcePatternResolver to use for resolving location patterns
0284:             * into Resource instances. Default is a
0285:             * {@link org.springframework.core.io.support.PathMatchingResourcePatternResolver},
0286:             * supporting Ant-style location patterns.
0287:             * <p>Can be overridden in subclasses, for extended resolution strategies,
0288:             * for example in a web environment.
0289:             * <p><b>Do not call this when needing to resolve a location pattern.</b>
0290:             * Call the context's <code>getResources</code> method instead, which
0291:             * will delegate to the ResourcePatternResolver.
0292:             * @return the ResourcePatternResolver for this context
0293:             * @see #getResources
0294:             * @see org.springframework.core.io.support.PathMatchingResourcePatternResolver
0295:             */
0296:            protected ResourcePatternResolver getResourcePatternResolver() {
0297:                return new PathMatchingResourcePatternResolver(this );
0298:            }
0299:
0300:            //---------------------------------------------------------------------
0301:            // Implementation of ConfigurableApplicationContext interface
0302:            //---------------------------------------------------------------------
0303:
0304:            public void setParent(ApplicationContext parent) {
0305:                this .parent = parent;
0306:            }
0307:
0308:            public void addBeanFactoryPostProcessor(
0309:                    BeanFactoryPostProcessor beanFactoryPostProcessor) {
0310:                this .beanFactoryPostProcessors.add(beanFactoryPostProcessor);
0311:            }
0312:
0313:            /**
0314:             * Return the list of BeanFactoryPostProcessors that will get applied
0315:             * to the internal BeanFactory.
0316:             * @see org.springframework.beans.factory.config.BeanFactoryPostProcessor
0317:             */
0318:            public List getBeanFactoryPostProcessors() {
0319:                return this .beanFactoryPostProcessors;
0320:            }
0321:
0322:            public void addApplicationListener(ApplicationListener listener) {
0323:                this .applicationListeners.add(listener);
0324:            }
0325:
0326:            /**
0327:             * Return the list of statically specified ApplicationListeners.
0328:             * @see org.springframework.context.ApplicationListener
0329:             */
0330:            public List getApplicationListeners() {
0331:                return this .applicationListeners;
0332:            }
0333:
0334:            public void refresh() throws BeansException, IllegalStateException {
0335:                synchronized (this .startupShutdownMonitor) {
0336:                    // Prepare this context for refreshing.
0337:                    prepareRefresh();
0338:
0339:                    // Tell the subclass to refresh the internal bean factory.
0340:                    ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
0341:
0342:                    // Prepare the bean factory for use in this context.
0343:                    prepareBeanFactory(beanFactory);
0344:
0345:                    try {
0346:                        // Allows post-processing of the bean factory in context subclasses.
0347:                        postProcessBeanFactory(beanFactory);
0348:
0349:                        // Invoke factory processors registered as beans in the context.
0350:                        invokeBeanFactoryPostProcessors(beanFactory);
0351:
0352:                        // Register bean processors that intercept bean creation.
0353:                        registerBeanPostProcessors(beanFactory);
0354:
0355:                        // Initialize message source for this context.
0356:                        initMessageSource();
0357:
0358:                        // Initialize event multicaster for this context.
0359:                        initApplicationEventMulticaster();
0360:
0361:                        // Initialize dependent beans for any lifecycle beans in this context.
0362:                        initLifecycleDependentBeans();
0363:
0364:                        // Initialize other special beans in specific context subclasses.
0365:                        onRefresh();
0366:
0367:                        // Check for listener beans and register them.
0368:                        registerListeners();
0369:
0370:                        // Instantiate all remaining (non-lazy-init) singletons.
0371:                        finishBeanFactoryInitialization(beanFactory);
0372:
0373:                        // Last step: publish corresponding event.
0374:                        finishRefresh();
0375:                    }
0376:
0377:                    catch (BeansException ex) {
0378:                        // Destroy already created singletons to avoid dangling resources.
0379:                        beanFactory.destroySingletons();
0380:
0381:                        // Reset 'active' flag.
0382:                        cancelRefresh(ex);
0383:
0384:                        // Propagate exception to caller.
0385:                        throw ex;
0386:                    }
0387:                }
0388:            }
0389:
0390:            /**
0391:             * Prepare this context for refreshing, setting its startup date and
0392:             * active flag.
0393:             */
0394:            protected void prepareRefresh() {
0395:                this .startupDate = System.currentTimeMillis();
0396:
0397:                synchronized (this .activeMonitor) {
0398:                    this .active = true;
0399:                }
0400:
0401:                if (logger.isInfoEnabled()) {
0402:                    logger.info("Refreshing " + this );
0403:                }
0404:            }
0405:
0406:            /**
0407:             * Tell the subclass to refresh the internal bean factory.
0408:             * @return the fresh BeanFactory instance
0409:             * @see #refreshBeanFactory()
0410:             * @see #getBeanFactory()
0411:             */
0412:            protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
0413:                refreshBeanFactory();
0414:                ConfigurableListableBeanFactory beanFactory = getBeanFactory();
0415:
0416:                if (logger.isInfoEnabled()) {
0417:                    logger.info("Bean factory for application context ["
0418:                            + ObjectUtils.identityToString(this ) + "]: "
0419:                            + ObjectUtils.identityToString(beanFactory));
0420:                }
0421:                if (logger.isDebugEnabled()) {
0422:                    logger.debug(beanFactory.getBeanDefinitionCount()
0423:                            + " beans defined in " + this );
0424:                }
0425:
0426:                return beanFactory;
0427:            }
0428:
0429:            /**
0430:             * Configure the factory's standard context characteristics,
0431:             * such as the context's ClassLoader and post-processors.
0432:             * @param beanFactory the BeanFactory to configure
0433:             */
0434:            protected void prepareBeanFactory(
0435:                    ConfigurableListableBeanFactory beanFactory) {
0436:                // Tell the internal bean factory to use the context's class loader.
0437:                beanFactory.setBeanClassLoader(getClassLoader());
0438:
0439:                // Populate the bean factory with context-specific resource editors.
0440:                beanFactory
0441:                        .addPropertyEditorRegistrar(new ResourceEditorRegistrar(
0442:                                this ));
0443:
0444:                // Configure the bean factory with context callbacks.
0445:                beanFactory
0446:                        .addBeanPostProcessor(new ApplicationContextAwareProcessor(
0447:                                this ));
0448:                beanFactory
0449:                        .ignoreDependencyInterface(ResourceLoaderAware.class);
0450:                beanFactory
0451:                        .ignoreDependencyInterface(ApplicationEventPublisherAware.class);
0452:                beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
0453:                beanFactory
0454:                        .ignoreDependencyInterface(ApplicationContextAware.class);
0455:
0456:                // BeanFactory interface not registered as resolvable type in a plain factory.
0457:                // MessageSource registered (and found for autowiring) as a bean.
0458:                beanFactory.registerResolvableDependency(BeanFactory.class,
0459:                        beanFactory);
0460:                beanFactory.registerResolvableDependency(ResourceLoader.class,
0461:                        this );
0462:                beanFactory.registerResolvableDependency(
0463:                        ApplicationEventPublisher.class, this );
0464:                beanFactory.registerResolvableDependency(
0465:                        ApplicationContext.class, this );
0466:
0467:                // Detect a LoadTimeWeaver and prepare for weaving, if found.
0468:                if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)
0469:                        && JdkVersion.isAtLeastJava15()) {
0470:                    // Register the (JDK 1.5 specific) LoadTimeWeaverAwareProcessor.
0471:                    try {
0472:                        Class ltwapClass = ClassUtils
0473:                                .forName(
0474:                                        "org.springframework.context.weaving.LoadTimeWeaverAwareProcessor",
0475:                                        getClass().getClassLoader());
0476:                        BeanPostProcessor ltwap = (BeanPostProcessor) BeanUtils
0477:                                .instantiateClass(ltwapClass);
0478:                        ((BeanFactoryAware) ltwap).setBeanFactory(beanFactory);
0479:                        beanFactory.addBeanPostProcessor(ltwap);
0480:                    } catch (ClassNotFoundException ex) {
0481:                        throw new IllegalStateException(
0482:                                "Spring's LoadTimeWeaverAwareProcessor class is not available");
0483:                    }
0484:                    // Set a temporary ClassLoader for type matching.
0485:                    beanFactory
0486:                            .setTempClassLoader(new ContextTypeMatchClassLoader(
0487:                                    beanFactory.getBeanClassLoader()));
0488:                }
0489:            }
0490:
0491:            /**
0492:             * Modify the application context's internal bean factory after its standard
0493:             * initialization. All bean definitions will have been loaded, but no beans
0494:             * will have been instantiated yet. This allows for registering special
0495:             * BeanPostProcessors etc in certain ApplicationContext implementations.
0496:             * @param beanFactory the bean factory used by the application context
0497:             */
0498:            protected void postProcessBeanFactory(
0499:                    ConfigurableListableBeanFactory beanFactory) {
0500:            }
0501:
0502:            /**
0503:             * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
0504:             * respecting explicit order if given.
0505:             * <p>Must be called before singleton instantiation.
0506:             */
0507:            protected void invokeBeanFactoryPostProcessors(
0508:                    ConfigurableListableBeanFactory beanFactory) {
0509:                // Invoke factory processors registered with the context instance.
0510:                for (Iterator it = getBeanFactoryPostProcessors().iterator(); it
0511:                        .hasNext();) {
0512:                    BeanFactoryPostProcessor factoryProcessor = (BeanFactoryPostProcessor) it
0513:                            .next();
0514:                    factoryProcessor.postProcessBeanFactory(beanFactory);
0515:                }
0516:
0517:                // Do not initialize FactoryBeans here: We need to leave all regular beans
0518:                // uninitialized to let the bean factory post-processors apply to them!
0519:                String[] postProcessorNames = beanFactory.getBeanNamesForType(
0520:                        BeanFactoryPostProcessor.class, true, false);
0521:
0522:                // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
0523:                // Ordered, and the rest.
0524:                List priorityOrderedPostProcessors = new ArrayList();
0525:                List orderedPostProcessorNames = new ArrayList();
0526:                List nonOrderedPostProcessorNames = new ArrayList();
0527:                for (int i = 0; i < postProcessorNames.length; i++) {
0528:                    if (isTypeMatch(postProcessorNames[i],
0529:                            PriorityOrdered.class)) {
0530:                        priorityOrderedPostProcessors.add(beanFactory
0531:                                .getBean(postProcessorNames[i]));
0532:                    } else if (isTypeMatch(postProcessorNames[i], Ordered.class)) {
0533:                        orderedPostProcessorNames.add(postProcessorNames[i]);
0534:                    } else {
0535:                        nonOrderedPostProcessorNames.add(postProcessorNames[i]);
0536:                    }
0537:                }
0538:
0539:                // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
0540:                Collections.sort(priorityOrderedPostProcessors,
0541:                        new OrderComparator());
0542:                invokeBeanFactoryPostProcessors(beanFactory,
0543:                        priorityOrderedPostProcessors);
0544:
0545:                // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
0546:                List orderedPostProcessors = new ArrayList();
0547:                for (Iterator it = orderedPostProcessorNames.iterator(); it
0548:                        .hasNext();) {
0549:                    String postProcessorName = (String) it.next();
0550:                    orderedPostProcessors.add(getBean(postProcessorName));
0551:                }
0552:                Collections.sort(orderedPostProcessors, new OrderComparator());
0553:                invokeBeanFactoryPostProcessors(beanFactory,
0554:                        orderedPostProcessors);
0555:
0556:                // Finally, invoke all other BeanFactoryPostProcessors.
0557:                List nonOrderedPostProcessors = new ArrayList();
0558:                for (Iterator it = nonOrderedPostProcessorNames.iterator(); it
0559:                        .hasNext();) {
0560:                    String postProcessorName = (String) it.next();
0561:                    nonOrderedPostProcessors.add(getBean(postProcessorName));
0562:                }
0563:                invokeBeanFactoryPostProcessors(beanFactory,
0564:                        nonOrderedPostProcessors);
0565:            }
0566:
0567:            /**
0568:             * Invoke the given BeanFactoryPostProcessor beans.
0569:             */
0570:            private void invokeBeanFactoryPostProcessors(
0571:                    ConfigurableListableBeanFactory beanFactory,
0572:                    List postProcessors) {
0573:                for (Iterator it = postProcessors.iterator(); it.hasNext();) {
0574:                    BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor) it
0575:                            .next();
0576:                    postProcessor.postProcessBeanFactory(beanFactory);
0577:                }
0578:            }
0579:
0580:            /**
0581:             * Instantiate and invoke all registered BeanPostProcessor beans,
0582:             * respecting explicit order if given.
0583:             * <p>Must be called before any instantiation of application beans.
0584:             */
0585:            protected void registerBeanPostProcessors(
0586:                    ConfigurableListableBeanFactory beanFactory) {
0587:                String[] postProcessorNames = beanFactory.getBeanNamesForType(
0588:                        BeanPostProcessor.class, true, false);
0589:
0590:                // Register BeanPostProcessorChecker that logs an info message when
0591:                // a bean is created during BeanPostProcessor instantiation, i.e. when
0592:                // a bean is not eligible for getting processed by all BeanPostProcessors.
0593:                int beanProcessorTargetCount = beanFactory
0594:                        .getBeanPostProcessorCount()
0595:                        + 1 + postProcessorNames.length;
0596:                beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(
0597:                        beanFactory, beanProcessorTargetCount));
0598:
0599:                // Separate between BeanPostProcessors that implement PriorityOrdered,
0600:                // Ordered, and the rest.
0601:                List priorityOrderedPostProcessors = new ArrayList();
0602:                List orderedPostProcessorNames = new ArrayList();
0603:                List nonOrderedPostProcessorNames = new ArrayList();
0604:                for (int i = 0; i < postProcessorNames.length; i++) {
0605:                    if (isTypeMatch(postProcessorNames[i],
0606:                            PriorityOrdered.class)) {
0607:                        priorityOrderedPostProcessors.add(beanFactory
0608:                                .getBean(postProcessorNames[i]));
0609:                    } else if (isTypeMatch(postProcessorNames[i], Ordered.class)) {
0610:                        orderedPostProcessorNames.add(postProcessorNames[i]);
0611:                    } else {
0612:                        nonOrderedPostProcessorNames.add(postProcessorNames[i]);
0613:                    }
0614:                }
0615:
0616:                // First, invoke the BeanPostProcessors that implement PriorityOrdered.
0617:                Collections.sort(priorityOrderedPostProcessors,
0618:                        new OrderComparator());
0619:                registerBeanPostProcessors(beanFactory,
0620:                        priorityOrderedPostProcessors);
0621:
0622:                // Next, invoke the BeanPostProcessors that implement Ordered.
0623:                List orderedPostProcessors = new ArrayList();
0624:                for (Iterator it = orderedPostProcessorNames.iterator(); it
0625:                        .hasNext();) {
0626:                    String postProcessorName = (String) it.next();
0627:                    orderedPostProcessors.add(getBean(postProcessorName));
0628:                }
0629:                Collections.sort(orderedPostProcessors, new OrderComparator());
0630:                registerBeanPostProcessors(beanFactory, orderedPostProcessors);
0631:
0632:                // Finally, invoke all other BeanPostProcessors.
0633:                List nonOrderedPostProcessors = new ArrayList();
0634:                for (Iterator it = nonOrderedPostProcessorNames.iterator(); it
0635:                        .hasNext();) {
0636:                    String postProcessorName = (String) it.next();
0637:                    nonOrderedPostProcessors.add(getBean(postProcessorName));
0638:                }
0639:                registerBeanPostProcessors(beanFactory,
0640:                        nonOrderedPostProcessors);
0641:            }
0642:
0643:            /**
0644:             * Register the given BeanPostProcessor beans.
0645:             */
0646:            private void registerBeanPostProcessors(
0647:                    ConfigurableListableBeanFactory beanFactory,
0648:                    List postProcessors) {
0649:                for (Iterator it = postProcessors.iterator(); it.hasNext();) {
0650:                    BeanPostProcessor postProcessor = (BeanPostProcessor) it
0651:                            .next();
0652:                    beanFactory.addBeanPostProcessor(postProcessor);
0653:                }
0654:            }
0655:
0656:            /**
0657:             * Initialize the MessageSource.
0658:             * Use parent's if none defined in this context.
0659:             */
0660:            protected void initMessageSource() {
0661:                ConfigurableListableBeanFactory beanFactory = getBeanFactory();
0662:                if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
0663:                    this .messageSource = (MessageSource) beanFactory.getBean(
0664:                            MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
0665:                    // Make MessageSource aware of parent MessageSource.
0666:                    if (this .parent != null
0667:                            && this .messageSource instanceof  HierarchicalMessageSource) {
0668:                        HierarchicalMessageSource hms = (HierarchicalMessageSource) this .messageSource;
0669:                        if (hms.getParentMessageSource() == null) {
0670:                            // Only set parent context as parent MessageSource if no parent MessageSource
0671:                            // registered already.
0672:                            hms
0673:                                    .setParentMessageSource(getInternalParentMessageSource());
0674:                        }
0675:                    }
0676:                    if (logger.isDebugEnabled()) {
0677:                        logger.debug("Using MessageSource ["
0678:                                + this .messageSource + "]");
0679:                    }
0680:                } else {
0681:                    // Use empty MessageSource to be able to accept getMessage calls.
0682:                    DelegatingMessageSource dms = new DelegatingMessageSource();
0683:                    dms
0684:                            .setParentMessageSource(getInternalParentMessageSource());
0685:                    this .messageSource = dms;
0686:                    beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME,
0687:                            this .messageSource);
0688:                    if (logger.isDebugEnabled()) {
0689:                        logger
0690:                                .debug("Unable to locate MessageSource with name '"
0691:                                        + MESSAGE_SOURCE_BEAN_NAME
0692:                                        + "': using default ["
0693:                                        + this .messageSource + "]");
0694:                    }
0695:                }
0696:            }
0697:
0698:            /**
0699:             * Initialize the ApplicationEventMulticaster.
0700:             * Uses SimpleApplicationEventMulticaster if none defined in the context.
0701:             * @see org.springframework.context.event.SimpleApplicationEventMulticaster
0702:             */
0703:            protected void initApplicationEventMulticaster() {
0704:                ConfigurableListableBeanFactory beanFactory = getBeanFactory();
0705:                if (beanFactory
0706:                        .containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
0707:                    this .applicationEventMulticaster = (ApplicationEventMulticaster) beanFactory
0708:                            .getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME,
0709:                                    ApplicationEventMulticaster.class);
0710:                    if (logger.isDebugEnabled()) {
0711:                        logger.debug("Using ApplicationEventMulticaster ["
0712:                                + this .applicationEventMulticaster + "]");
0713:                    }
0714:                } else {
0715:                    this .applicationEventMulticaster = new SimpleApplicationEventMulticaster();
0716:                    beanFactory.registerSingleton(
0717:                            APPLICATION_EVENT_MULTICASTER_BEAN_NAME,
0718:                            this .applicationEventMulticaster);
0719:                    if (logger.isDebugEnabled()) {
0720:                        logger
0721:                                .debug("Unable to locate ApplicationEventMulticaster with name '"
0722:                                        + APPLICATION_EVENT_MULTICASTER_BEAN_NAME
0723:                                        + "': using default ["
0724:                                        + this .applicationEventMulticaster
0725:                                        + "]");
0726:                    }
0727:                }
0728:            }
0729:
0730:            /**
0731:             * Registers dependent beans for any singleton lifecycle beans in this
0732:             * context, thus ensuring they are started and stopped in the correct order.
0733:             */
0734:            protected void initLifecycleDependentBeans() {
0735:                String lifecycleBeans[] = this .getBeanNamesForType(
0736:                        Lifecycle.class, false, false);
0737:                for (int i = 0; i < lifecycleBeans.length; i++) {
0738:                    String beanName = lifecycleBeans[i];
0739:                    if (getBeanFactory().containsBeanDefinition(beanName)) {
0740:                        BeanDefinition bd = getBeanFactory().getBeanDefinition(
0741:                                beanName);
0742:                        if (bd instanceof  AbstractBeanDefinition) {
0743:                            String[] dependsOn = ((AbstractBeanDefinition) bd)
0744:                                    .getDependsOn();
0745:                            if (dependsOn != null) {
0746:                                for (int j = 0; j < dependsOn.length; j++) {
0747:                                    getBeanFactory().registerDependentBean(
0748:                                            dependsOn[j], beanName);
0749:                                }
0750:                            }
0751:                        }
0752:                    }
0753:                }
0754:            }
0755:
0756:            /**
0757:             * Template method which can be overridden to add context-specific refresh work.
0758:             * Called on initialization of special beans, before instantiation of singletons.
0759:             * <p>This implementation is empty.
0760:             * @throws BeansException in case of errors
0761:             * @see #refresh()
0762:             */
0763:            protected void onRefresh() throws BeansException {
0764:                // For subclasses: do nothing by default.
0765:            }
0766:
0767:            /**
0768:             * Add beans that implement ApplicationListener as listeners.
0769:             * Doesn't affect other listeners, which can be added without being beans.
0770:             */
0771:            protected void registerListeners() {
0772:                // Register statically specified listeners first.
0773:                for (Iterator it = getApplicationListeners().iterator(); it
0774:                        .hasNext();) {
0775:                    addListener((ApplicationListener) it.next());
0776:                }
0777:                // Do not initialize FactoryBeans here: We need to leave all regular beans
0778:                // uninitialized to let post-processors apply to them!
0779:                Collection listenerBeans = getBeansOfType(
0780:                        ApplicationListener.class, true, false).values();
0781:                for (Iterator it = listenerBeans.iterator(); it.hasNext();) {
0782:                    addListener((ApplicationListener) it.next());
0783:                }
0784:            }
0785:
0786:            /**
0787:             * Subclasses can invoke this method to register a listener.
0788:             * Any beans in the context that are listeners are automatically added.
0789:             * @param listener the listener to register
0790:             */
0791:            protected void addListener(ApplicationListener listener) {
0792:                getApplicationEventMulticaster().addApplicationListener(
0793:                        listener);
0794:            }
0795:
0796:            /**
0797:             * Finish the initialization of this context's bean factory,
0798:             * initializing all remaining singleton beans.
0799:             */
0800:            protected void finishBeanFactoryInitialization(
0801:                    ConfigurableListableBeanFactory beanFactory) {
0802:                // Stop using the temporary ClassLoader for type matching.
0803:                beanFactory.setTempClassLoader(null);
0804:
0805:                // Instantiate all remaining (non-lazy-init) singletons.
0806:                beanFactory.preInstantiateSingletons();
0807:            }
0808:
0809:            /**
0810:             * Finish the refresh of this context, publishing the
0811:             * {@link org.springframework.context.event.ContextRefreshedEvent}.
0812:             */
0813:            protected void finishRefresh() {
0814:                publishEvent(new ContextRefreshedEvent(this ));
0815:            }
0816:
0817:            /**
0818:             * Cancel this context's refresh attempt, resetting the <code>active</code> flag
0819:             * after an exception got thrown.
0820:             * @param ex the exception that led to the cancellation
0821:             */
0822:            protected void cancelRefresh(BeansException ex) {
0823:                synchronized (this .activeMonitor) {
0824:                    this .active = false;
0825:                }
0826:            }
0827:
0828:            /**
0829:             * Register a shutdown hook with the JVM runtime, closing this context
0830:             * on JVM shutdown unless it has already been closed at that time.
0831:             * <p>Delegates to <code>doClose()</code> for the actual closing procedure.
0832:             * @see java.lang.Runtime#addShutdownHook
0833:             * @see #close()
0834:             * @see #doClose()
0835:             */
0836:            public void registerShutdownHook() {
0837:                if (this .shutdownHook == null) {
0838:                    // No shutdown hook registered yet.
0839:                    this .shutdownHook = new Thread() {
0840:                        public void run() {
0841:                            doClose();
0842:                        }
0843:                    };
0844:                    Runtime.getRuntime().addShutdownHook(this .shutdownHook);
0845:                }
0846:            }
0847:
0848:            /**
0849:             * DisposableBean callback for destruction of this instance.
0850:             * Only called when the ApplicationContext itself is running
0851:             * as a bean in another BeanFactory or ApplicationContext,
0852:             * which is rather unusual.
0853:             * <p>The <code>close</code> method is the native way to
0854:             * shut down an ApplicationContext.
0855:             * @see #close()
0856:             * @see org.springframework.beans.factory.access.SingletonBeanFactoryLocator
0857:             */
0858:            public void destroy() {
0859:                close();
0860:            }
0861:
0862:            /**
0863:             * Close this application context, destroying all beans in its bean factory.
0864:             * <p>Delegates to <code>doClose()</code> for the actual closing procedure.
0865:             * Also removes a JVM shutdown hook, if registered, as it's not needed anymore.
0866:             * @see #doClose()
0867:             * @see #registerShutdownHook()
0868:             */
0869:            public void close() {
0870:                synchronized (this .startupShutdownMonitor) {
0871:                    doClose();
0872:                    // If we registered a JVM shutdown hook, we don't need it anymore now:
0873:                    // We've already explicitly closed the context.
0874:                    if (this .shutdownHook != null) {
0875:                        Runtime.getRuntime().removeShutdownHook(
0876:                                this .shutdownHook);
0877:                    }
0878:                }
0879:            }
0880:
0881:            /**
0882:             * Actually performs context closing: publishes a ContextClosedEvent and
0883:             * destroys the singletons in the bean factory of this application context.
0884:             * <p>Called by both <code>close()</code> and a JVM shutdown hook, if any.
0885:             * @see org.springframework.context.event.ContextClosedEvent
0886:             * @see org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons()
0887:             * @see #close()
0888:             * @see #registerShutdownHook()
0889:             */
0890:            protected void doClose() {
0891:                if (isActive()) {
0892:                    if (logger.isInfoEnabled()) {
0893:                        logger.info("Closing " + this );
0894:                    }
0895:                    try {
0896:                        // Publish shutdown event.
0897:                        publishEvent(new ContextClosedEvent(this ));
0898:                    } catch (Throwable ex) {
0899:                        logger
0900:                                .error(
0901:                                        "Exception thrown from ApplicationListener handling ContextClosedEvent",
0902:                                        ex);
0903:                    }
0904:                    // Stop all Lifecycle beans, to avoid delays during individual destruction.
0905:                    stop();
0906:                    // Destroy all cached singletons in the context's BeanFactory.
0907:                    destroyBeans();
0908:                    // Close the state of this context itself.
0909:                    closeBeanFactory();
0910:                    onClose();
0911:                    synchronized (this .activeMonitor) {
0912:                        this .active = false;
0913:                    }
0914:                }
0915:            }
0916:
0917:            /**
0918:             * Template method for destroying all beans that this context manages.
0919:             * The default implementation destroy all cached singletons in this context,
0920:             * invoking <code>DisposableBean.destroy()</code> and/or the specified
0921:             * "destroy-method".
0922:             * <p>Can be overridden to add context-specific bean destruction steps
0923:             * right before or right after standard singleton destruction,
0924:             * while the context's BeanFactory is still active.
0925:             * @see #getBeanFactory()
0926:             * @see org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons()
0927:             */
0928:            protected void destroyBeans() {
0929:                getBeanFactory().destroySingletons();
0930:            }
0931:
0932:            /**
0933:             * Template method which can be overridden to add context-specific shutdown work.
0934:             * The default implementation is empty.
0935:             * <p>Called at the end of {@link #doClose}'s shutdown procedure, after
0936:             * this context's BeanFactory has been closed. If custom shutdown logic
0937:             * needs to execute while the BeanFactory is still active, override
0938:             * the {@link #destroyBeans()} method instead.
0939:             */
0940:            protected void onClose() {
0941:                // For subclasses: do nothing by default.
0942:            }
0943:
0944:            public boolean isActive() {
0945:                synchronized (this .activeMonitor) {
0946:                    return this .active;
0947:                }
0948:            }
0949:
0950:            //---------------------------------------------------------------------
0951:            // Implementation of BeanFactory interface
0952:            //---------------------------------------------------------------------
0953:
0954:            public Object getBean(String name) throws BeansException {
0955:                return getBeanFactory().getBean(name);
0956:            }
0957:
0958:            public Object getBean(String name, Class requiredType)
0959:                    throws BeansException {
0960:                return getBeanFactory().getBean(name, requiredType);
0961:            }
0962:
0963:            public Object getBean(String name, Object[] args)
0964:                    throws BeansException {
0965:                return getBeanFactory().getBean(name, args);
0966:            }
0967:
0968:            public boolean containsBean(String name) {
0969:                return getBeanFactory().containsBean(name);
0970:            }
0971:
0972:            public boolean isSingleton(String name)
0973:                    throws NoSuchBeanDefinitionException {
0974:                return getBeanFactory().isSingleton(name);
0975:            }
0976:
0977:            public boolean isPrototype(String name)
0978:                    throws NoSuchBeanDefinitionException {
0979:                return getBeanFactory().isPrototype(name);
0980:            }
0981:
0982:            public boolean isTypeMatch(String name, Class targetType)
0983:                    throws NoSuchBeanDefinitionException {
0984:                return getBeanFactory().isTypeMatch(name, targetType);
0985:            }
0986:
0987:            public Class getType(String name)
0988:                    throws NoSuchBeanDefinitionException {
0989:                return getBeanFactory().getType(name);
0990:            }
0991:
0992:            public String[] getAliases(String name) {
0993:                return getBeanFactory().getAliases(name);
0994:            }
0995:
0996:            //---------------------------------------------------------------------
0997:            // Implementation of ListableBeanFactory interface
0998:            //---------------------------------------------------------------------
0999:
1000:            public boolean containsBeanDefinition(String name) {
1001:                return getBeanFactory().containsBeanDefinition(name);
1002:            }
1003:
1004:            public int getBeanDefinitionCount() {
1005:                return getBeanFactory().getBeanDefinitionCount();
1006:            }
1007:
1008:            public String[] getBeanDefinitionNames() {
1009:                return getBeanFactory().getBeanDefinitionNames();
1010:            }
1011:
1012:            public String[] getBeanNamesForType(Class type) {
1013:                return getBeanFactory().getBeanNamesForType(type);
1014:            }
1015:
1016:            public String[] getBeanNamesForType(Class type,
1017:                    boolean includePrototypes, boolean allowEagerInit) {
1018:                return getBeanFactory().getBeanNamesForType(type,
1019:                        includePrototypes, allowEagerInit);
1020:            }
1021:
1022:            public Map getBeansOfType(Class type) throws BeansException {
1023:                return getBeanFactory().getBeansOfType(type);
1024:            }
1025:
1026:            public Map getBeansOfType(Class type, boolean includePrototypes,
1027:                    boolean allowEagerInit) throws BeansException {
1028:
1029:                return getBeanFactory().getBeansOfType(type, includePrototypes,
1030:                        allowEagerInit);
1031:            }
1032:
1033:            //---------------------------------------------------------------------
1034:            // Implementation of HierarchicalBeanFactory interface
1035:            //---------------------------------------------------------------------
1036:
1037:            public BeanFactory getParentBeanFactory() {
1038:                return getParent();
1039:            }
1040:
1041:            public boolean containsLocalBean(String name) {
1042:                return getBeanFactory().containsLocalBean(name);
1043:            }
1044:
1045:            /**
1046:             * Return the internal bean factory of the parent context if it implements
1047:             * ConfigurableApplicationContext; else, return the parent context itself.
1048:             * @see org.springframework.context.ConfigurableApplicationContext#getBeanFactory
1049:             */
1050:            protected BeanFactory getInternalParentBeanFactory() {
1051:                return (getParent() instanceof  ConfigurableApplicationContext) ? ((ConfigurableApplicationContext) getParent())
1052:                        .getBeanFactory()
1053:                        : (BeanFactory) getParent();
1054:            }
1055:
1056:            //---------------------------------------------------------------------
1057:            // Implementation of MessageSource interface
1058:            //---------------------------------------------------------------------
1059:
1060:            public String getMessage(String code, Object args[],
1061:                    String defaultMessage, Locale locale) {
1062:                return getMessageSource().getMessage(code, args,
1063:                        defaultMessage, locale);
1064:            }
1065:
1066:            public String getMessage(String code, Object args[], Locale locale)
1067:                    throws NoSuchMessageException {
1068:                return getMessageSource().getMessage(code, args, locale);
1069:            }
1070:
1071:            public String getMessage(MessageSourceResolvable resolvable,
1072:                    Locale locale) throws NoSuchMessageException {
1073:                return getMessageSource().getMessage(resolvable, locale);
1074:            }
1075:
1076:            /**
1077:             * Return the internal MessageSource used by the context.
1078:             * @return the internal MessageSource (never <code>null</code>)
1079:             * @throws IllegalStateException if the context has not been initialized yet
1080:             */
1081:            private MessageSource getMessageSource()
1082:                    throws IllegalStateException {
1083:                if (this .messageSource == null) {
1084:                    throw new IllegalStateException(
1085:                            "MessageSource not initialized - "
1086:                                    + "call 'refresh' before accessing messages via the context: "
1087:                                    + this );
1088:                }
1089:                return this .messageSource;
1090:            }
1091:
1092:            /**
1093:             * Return the internal message source of the parent context if it is an
1094:             * AbstractApplicationContext too; else, return the parent context itself.
1095:             */
1096:            protected MessageSource getInternalParentMessageSource() {
1097:                return (getParent() instanceof  AbstractApplicationContext) ? ((AbstractApplicationContext) getParent()).messageSource
1098:                        : getParent();
1099:            }
1100:
1101:            //---------------------------------------------------------------------
1102:            // Implementation of ResourcePatternResolver interface
1103:            //---------------------------------------------------------------------
1104:
1105:            public Resource[] getResources(String locationPattern)
1106:                    throws IOException {
1107:                return this .resourcePatternResolver
1108:                        .getResources(locationPattern);
1109:            }
1110:
1111:            //---------------------------------------------------------------------
1112:            // Implementation of Lifecycle interface
1113:            //---------------------------------------------------------------------
1114:
1115:            public void start() {
1116:                Map lifecycleBeans = getLifecycleBeans();
1117:                for (Iterator it = new HashSet(lifecycleBeans.keySet())
1118:                        .iterator(); it.hasNext();) {
1119:                    String beanName = (String) it.next();
1120:                    doStart(lifecycleBeans, beanName);
1121:                }
1122:                publishEvent(new ContextStartedEvent(this ));
1123:            }
1124:
1125:            public void stop() {
1126:                Map lifecycleBeans = getLifecycleBeans();
1127:                for (Iterator it = new HashSet(lifecycleBeans.keySet())
1128:                        .iterator(); it.hasNext();) {
1129:                    String beanName = (String) it.next();
1130:                    doStop(lifecycleBeans, beanName);
1131:                }
1132:                publishEvent(new ContextStoppedEvent(this ));
1133:            }
1134:
1135:            public boolean isRunning() {
1136:                Iterator it = getLifecycleBeans().values().iterator();
1137:                while (it.hasNext()) {
1138:                    Lifecycle lifecycle = (Lifecycle) it.next();
1139:                    if (!lifecycle.isRunning()) {
1140:                        return false;
1141:                    }
1142:                }
1143:                return true;
1144:            }
1145:
1146:            /**
1147:             * Return a Map of all singleton beans that implement the
1148:             * Lifecycle interface in this context.
1149:             * @return Map of Lifecycle beans with bean name as key
1150:             */
1151:            private Map getLifecycleBeans() {
1152:                ConfigurableListableBeanFactory beanFactory = getBeanFactory();
1153:                String[] beanNames = beanFactory.getBeanNamesForType(
1154:                        Lifecycle.class, false, false);
1155:                Map beans = new HashMap(beanNames.length);
1156:                for (int i = 0; i < beanNames.length; i++) {
1157:                    Object bean = beanFactory.getSingleton(beanNames[i]);
1158:                    if (bean != null) {
1159:                        beans.put(beanNames[i], bean);
1160:                    }
1161:                }
1162:                return beans;
1163:            }
1164:
1165:            /**
1166:             * Start the specified bean as part of the given set of Lifecycle beans,
1167:             * making sure that any beans that it depends on are started first.
1168:             * @param lifecycleBeans Map with bean name as key and Lifecycle instance as value
1169:             * @param beanName the name of the bean to start
1170:             */
1171:            private void doStart(Map lifecycleBeans, String beanName) {
1172:                Lifecycle bean = (Lifecycle) lifecycleBeans.get(beanName);
1173:                if (bean != null) {
1174:                    String[] dependenciesForBean = getBeanFactory()
1175:                            .getDependenciesForBean(beanName);
1176:                    for (int i = 0; i < dependenciesForBean.length; i++) {
1177:                        doStart(lifecycleBeans, dependenciesForBean[i]);
1178:                    }
1179:                    if (!bean.isRunning()) {
1180:                        bean.start();
1181:                    }
1182:                    lifecycleBeans.remove(beanName);
1183:                }
1184:            }
1185:
1186:            /**
1187:             * Stop the specified bean as part of the given set of Lifecycle beans,
1188:             * making sure that any beans that depends on it are stopped first.
1189:             * @param lifecycleBeans Map with bean name as key and Lifecycle instance as value
1190:             * @param beanName the name of the bean to stop
1191:             */
1192:            private void doStop(Map lifecycleBeans, String beanName) {
1193:                Lifecycle bean = (Lifecycle) lifecycleBeans.get(beanName);
1194:                if (bean != null) {
1195:                    String[] dependentBeans = getBeanFactory()
1196:                            .getDependentBeans(beanName);
1197:                    for (int i = 0; i < dependentBeans.length; i++) {
1198:                        doStop(lifecycleBeans, dependentBeans[i]);
1199:                    }
1200:                    if (bean.isRunning()) {
1201:                        bean.stop();
1202:                    }
1203:                    lifecycleBeans.remove(beanName);
1204:                }
1205:            }
1206:
1207:            //---------------------------------------------------------------------
1208:            // Abstract methods that must be implemented by subclasses
1209:            //---------------------------------------------------------------------
1210:
1211:            /**
1212:             * Subclasses must implement this method to perform the actual configuration load.
1213:             * The method is invoked by {@link #refresh()} before any other initialization work.
1214:             * <p>A subclass will either create a new bean factory and hold a reference to it,
1215:             * or return a single BeanFactory instance that it holds. In the latter case, it will
1216:             * usually throw an IllegalStateException if refreshing the context more than once.
1217:             * @throws BeansException if initialization of the bean factory failed
1218:             * @throws IllegalStateException if already initialized and multiple refresh
1219:             * attempts are not supported
1220:             */
1221:            protected abstract void refreshBeanFactory() throws BeansException,
1222:                    IllegalStateException;
1223:
1224:            /**
1225:             * Subclasses must implement this method to release their internal bean factory.
1226:             * This method gets invoked by {@link #close()} after all other shutdown work.
1227:             * <p>Should never throw an exception but rather log shutdown failures.
1228:             */
1229:            protected abstract void closeBeanFactory();
1230:
1231:            /**
1232:             * Subclasses must return their internal bean factory here. They should implement the
1233:             * lookup efficiently, so that it can be called repeatedly without a performance penalty.
1234:             * <p>Note: Subclasses should check whether the context is still active before
1235:             * returning the internal bean factory. The internal factory should generally be
1236:             * considered unavailable once the context has been closed.
1237:             * @return this application context's internal bean factory (never <code>null</code>)
1238:             * @throws IllegalStateException if the context does not hold an internal bean factory yet
1239:             * (usually if {@link #refresh()} has never been called) or if the context has been
1240:             * closed already
1241:             * @see #refreshBeanFactory()
1242:             * @see #closeBeanFactory()
1243:             */
1244:            public abstract ConfigurableListableBeanFactory getBeanFactory()
1245:                    throws IllegalStateException;
1246:
1247:            /**
1248:             * Return information about this context.
1249:             */
1250:            public String toString() {
1251:                StringBuffer sb = new StringBuffer(ObjectUtils
1252:                        .identityToString(this ));
1253:                sb.append(": display name [").append(getDisplayName());
1254:                sb.append("]; startup date [").append(
1255:                        new Date(getStartupDate()));
1256:                sb.append("]; ");
1257:                ApplicationContext parent = getParent();
1258:                if (parent == null) {
1259:                    sb.append("root of context hierarchy");
1260:                } else {
1261:                    sb.append("parent: ").append(
1262:                            ObjectUtils.identityToString(parent));
1263:                }
1264:                return sb.toString();
1265:            }
1266:
1267:            /**
1268:             * BeanPostProcessor that logs an info message when a bean is created during
1269:             * BeanPostProcessor instantiation, i.e. when a bean is not eligible for
1270:             * getting processed by all BeanPostProcessors.
1271:             */
1272:            private class BeanPostProcessorChecker implements  BeanPostProcessor {
1273:
1274:                private final ConfigurableListableBeanFactory beanFactory;
1275:
1276:                private final int beanPostProcessorTargetCount;
1277:
1278:                public BeanPostProcessorChecker(
1279:                        ConfigurableListableBeanFactory beanFactory,
1280:                        int beanPostProcessorTargetCount) {
1281:                    this .beanFactory = beanFactory;
1282:                    this .beanPostProcessorTargetCount = beanPostProcessorTargetCount;
1283:                }
1284:
1285:                public Object postProcessBeforeInitialization(Object bean,
1286:                        String beanName) {
1287:                    return bean;
1288:                }
1289:
1290:                public Object postProcessAfterInitialization(Object bean,
1291:                        String beanName) {
1292:                    if (!(bean instanceof  BeanPostProcessor)
1293:                            && this .beanFactory.getBeanPostProcessorCount() < this .beanPostProcessorTargetCount) {
1294:                        if (logger.isInfoEnabled()) {
1295:                            logger
1296:                                    .info("Bean '"
1297:                                            + beanName
1298:                                            + "' is not eligible for getting processed by all "
1299:                                            + "BeanPostProcessors (for example: not eligible for auto-proxying)");
1300:                        }
1301:                    }
1302:                    return bean;
1303:                }
1304:            }
1305:
1306:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.