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