| Method from org.springframework.context.support.AbstractApplicationContext Detail: |
public void addApplicationListener(ApplicationListener listener) {
this.applicationListeners.add(listener);
}
|
public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor beanFactoryPostProcessor) {
this.beanFactoryPostProcessors.add(beanFactoryPostProcessor);
}
|
protected void addListener(ApplicationListener listener) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
Subclasses can invoke this method to register a listener.
Any beans in the context that are listeners are automatically added. |
protected void cancelRefresh(BeansException ex) {
synchronized (this.activeMonitor) {
this.active = false;
}
}
Cancel this context's refresh attempt, resetting the active flag
after an exception got thrown. |
public void close() {
synchronized (this.startupShutdownMonitor) {
doClose();
// If we registered a JVM shutdown hook, we don't need it anymore now:
// We've already explicitly closed the context.
if (this.shutdownHook != null) {
Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
}
}
}
Close this application context, destroying all beans in its bean factory.
Delegates to doClose() for the actual closing procedure.
Also removes a JVM shutdown hook, if registered, as it's not needed anymore. |
abstract protected void closeBeanFactory()
|
public boolean containsBean(String name) {
return getBeanFactory().containsBean(name);
}
|
public boolean containsBeanDefinition(String name) {
return getBeanFactory().containsBeanDefinition(name);
}
|
public boolean containsLocalBean(String name) {
return getBeanFactory().containsLocalBean(name);
}
|
public void destroy() {
close();
}
|
protected void destroyBeans() {
getBeanFactory().destroySingletons();
}
Template method for destroying all beans that this context manages.
The default implementation destroy all cached singletons in this context,
invoking DisposableBean.destroy() and/or the specified
"destroy-method".
Can be overridden to add context-specific bean destruction steps
right before or right after standard singleton destruction,
while the context's BeanFactory is still active. |
protected void doClose() {
if (isActive()) {
if (logger.isInfoEnabled()) {
logger.info("Closing " + this);
}
try {
// Publish shutdown event.
publishEvent(new ContextClosedEvent(this));
}
catch (Throwable ex) {
logger.error("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
}
// Stop all Lifecycle beans, to avoid delays during individual destruction.
Map lifecycleBeans = getLifecycleBeans();
for (Iterator it = new LinkedHashSet(lifecycleBeans.keySet()).iterator(); it.hasNext();) {
String beanName = (String) it.next();
doStop(lifecycleBeans, beanName);
}
// Destroy all cached singletons in the context's BeanFactory.
destroyBeans();
// Close the state of this context itself.
closeBeanFactory();
onClose();
synchronized (this.activeMonitor) {
this.active = false;
}
}
}
Actually performs context closing: publishes a ContextClosedEvent and
destroys the singletons in the bean factory of this application context.
Called by both close() and a JVM shutdown hook, if any. |
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
Finish the initialization of this context's bean factory,
initializing all remaining singleton beans. |
protected void finishRefresh() {
publishEvent(new ContextRefreshedEvent(this));
}
|
public String[] getAliases(String name) {
return getBeanFactory().getAliases(name);
}
|
public List getApplicationListeners() {
return this.applicationListeners;
}
Return the list of statically specified ApplicationListeners. |
public AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException {
return getBeanFactory();
}
Return this context's internal bean factory as AutowireCapableBeanFactory,
if already available. |
public Object getBean(String name) throws BeansException {
return getBeanFactory().getBean(name);
}
|
public Object getBean(String name,
Class requiredType) throws BeansException {
return getBeanFactory().getBean(name, requiredType);
}
|
public Object getBean(String name,
Object[] args) throws BeansException {
return getBeanFactory().getBean(name, args);
}
|
public int getBeanDefinitionCount() {
return getBeanFactory().getBeanDefinitionCount();
}
|
public String[] getBeanDefinitionNames() {
return getBeanFactory().getBeanDefinitionNames();
}
|
abstract public ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException
Subclasses must return their internal bean factory here. They should implement the
lookup efficiently, so that it can be called repeatedly without a performance penalty.
Note: Subclasses should check whether the context is still active before
returning the internal bean factory. The internal factory should generally be
considered unavailable once the context has been closed. |
public List getBeanFactoryPostProcessors() {
return this.beanFactoryPostProcessors;
}
Return the list of BeanFactoryPostProcessors that will get applied
to the internal BeanFactory. |
public String[] getBeanNamesForType(Class type) {
return getBeanFactory().getBeanNamesForType(type);
}
|
public String[] getBeanNamesForType(Class type,
boolean includePrototypes,
boolean allowEagerInit) {
return getBeanFactory().getBeanNamesForType(type, includePrototypes, allowEagerInit);
}
|
public Map getBeansOfType(Class type) throws BeansException {
return getBeanFactory().getBeansOfType(type);
}
|
public Map getBeansOfType(Class type,
boolean includePrototypes,
boolean allowEagerInit) throws BeansException {
return getBeanFactory().getBeansOfType(type, includePrototypes, allowEagerInit);
}
|
public String getDisplayName() {
return (this.displayName != null ? this.displayName : getId());
}
Return a friendly name for this context. |
public String getId() {
return this.id;
}
|
protected BeanFactory getInternalParentBeanFactory() {
return (getParent() instanceof ConfigurableApplicationContext) ?
((ConfigurableApplicationContext) getParent()).getBeanFactory() : (BeanFactory) getParent();
}
Return the internal bean factory of the parent context if it implements
ConfigurableApplicationContext; else, return the parent context itself. |
protected MessageSource getInternalParentMessageSource() {
return (getParent() instanceof AbstractApplicationContext) ?
((AbstractApplicationContext) getParent()).messageSource : getParent();
}
Return the internal message source of the parent context if it is an
AbstractApplicationContext too; else, return the parent context itself. |
public String getMessage(MessageSourceResolvable resolvable,
Locale locale) throws NoSuchMessageException {
return getMessageSource().getMessage(resolvable, locale);
}
|
public String getMessage(String code,
Object[] args,
Locale locale) throws NoSuchMessageException {
return getMessageSource().getMessage(code, args, locale);
}
|
public String getMessage(String code,
Object[] args,
String defaultMessage,
Locale locale) {
return getMessageSource().getMessage(code, args, defaultMessage, locale);
}
|
public ApplicationContext getParent() {
return this.parent;
}
Return the parent context, or null if there is no parent
(that is, this context is the root of the context hierarchy). |
public BeanFactory getParentBeanFactory() {
return getParent();
}
|
protected ResourcePatternResolver getResourcePatternResolver() {
return new PathMatchingResourcePatternResolver(this);
}
Return the ResourcePatternResolver to use for resolving location patterns
into Resource instances. Default is a
org.springframework.core.io.support.PathMatchingResourcePatternResolver ,
supporting Ant-style location patterns.
Can be overridden in subclasses, for extended resolution strategies,
for example in a web environment.
Do not call this when needing to resolve a location pattern.
Call the context's getResources method instead, which
will delegate to the ResourcePatternResolver. |
public Resource[] getResources(String locationPattern) throws IOException {
return this.resourcePatternResolver.getResources(locationPattern);
}
|
public long getStartupDate() {
return this.startupDate;
}
Return the timestamp (ms) when this context was first loaded. |
public Class getType(String name) throws NoSuchBeanDefinitionException {
return getBeanFactory().getType(name);
}
|
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster = (ApplicationEventMulticaster)
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isDebugEnabled()) {
logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster();
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this.applicationEventMulticaster + "]");
}
}
}
Initialize the ApplicationEventMulticaster.
Uses SimpleApplicationEventMulticaster if none defined in the context. |
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = (MessageSource) beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent MessageSource if no parent MessageSource
// registered already.
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isDebugEnabled()) {
logger.debug("Using MessageSource [" + this.messageSource + "]");
}
}
else {
// Use empty MessageSource to be able to accept getMessage calls.
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
"': using default [" + this.messageSource + "]");
}
}
}
Initialize the MessageSource.
Use parent's if none defined in this context. |
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// Invoke factory processors registered with the context instance.
for (Iterator it = getBeanFactoryPostProcessors().iterator(); it.hasNext();) {
BeanFactoryPostProcessor factoryProcessor = (BeanFactoryPostProcessor) it.next();
factoryProcessor.postProcessBeanFactory(beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List priorityOrderedPostProcessors = new ArrayList();
List orderedPostProcessorNames = new ArrayList();
List nonOrderedPostProcessorNames = new ArrayList();
for (int i = 0; i < postProcessorNames.length; i++) {
if (isTypeMatch(postProcessorNames[i], PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(postProcessorNames[i]));
}
else if (isTypeMatch(postProcessorNames[i], Ordered.class)) {
orderedPostProcessorNames.add(postProcessorNames[i]);
}
else {
nonOrderedPostProcessorNames.add(postProcessorNames[i]);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
Collections.sort(priorityOrderedPostProcessors, new OrderComparator());
invokeBeanFactoryPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List orderedPostProcessors = new ArrayList();
for (Iterator it = orderedPostProcessorNames.iterator(); it.hasNext();) {
String postProcessorName = (String) it.next();
orderedPostProcessors.add(getBean(postProcessorName));
}
Collections.sort(orderedPostProcessors, new OrderComparator());
invokeBeanFactoryPostProcessors(beanFactory, orderedPostProcessors);
// Finally, invoke all other BeanFactoryPostProcessors.
List nonOrderedPostProcessors = new ArrayList();
for (Iterator it = nonOrderedPostProcessorNames.iterator(); it.hasNext();) {
String postProcessorName = (String) it.next();
nonOrderedPostProcessors.add(getBean(postProcessorName));
}
invokeBeanFactoryPostProcessors(beanFactory, nonOrderedPostProcessors);
}
|
public boolean isActive() {
synchronized (this.activeMonitor) {
return this.active;
}
}
|
public boolean isPrototype(String name) throws NoSuchBeanDefinitionException {
return getBeanFactory().isPrototype(name);
}
|
public boolean isRunning() {
Iterator it = getLifecycleBeans().values().iterator();
while (it.hasNext()) {
Lifecycle lifecycle = (Lifecycle) it.next();
if (!lifecycle.isRunning()) {
return false;
}
}
return true;
}
|
public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
return getBeanFactory().isSingleton(name);
}
|
public boolean isTypeMatch(String name,
Class targetType) throws NoSuchBeanDefinitionException {
return getBeanFactory().isTypeMatch(name, targetType);
}
|
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isInfoEnabled()) {
logger.info("Bean factory for application context [" + getId() + "]: " +
ObjectUtils.identityToString(beanFactory));
}
if (logger.isDebugEnabled()) {
logger.debug(beanFactory.getBeanDefinitionCount() + " beans defined in " + this);
}
return beanFactory;
}
Tell the subclass to refresh the internal bean factory. |
protected void onClose() {
// For subclasses: do nothing by default.
}
Template method which can be overridden to add context-specific shutdown work.
The default implementation is empty.
Called at the end of #doClose 's shutdown procedure, after
this context's BeanFactory has been closed. If custom shutdown logic
needs to execute while the BeanFactory is still active, override
the #destroyBeans() method instead. |
protected void onRefresh() throws BeansException {
// For subclasses: do nothing by default.
}
|
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
Modify the application context's internal bean factory after its standard
initialization. All bean definitions will have been loaded, but no beans
will have been instantiated yet. This allows for registering special
BeanPostProcessors etc in certain ApplicationContext implementations. |
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader.
beanFactory.setBeanClassLoader(getClassLoader());
// Populate the bean factory with context-specific resource editors.
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this));
// Configure the bean factory with context callbacks.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME) && JdkVersion.isAtLeastJava15()) {
// Register the (JDK 1.5 specific) LoadTimeWeaverAwareProcessor.
try {
Class ltwapClass = ClassUtils.forName(
"org.springframework.context.weaving.LoadTimeWeaverAwareProcessor",
AbstractApplicationContext.class.getClassLoader());
BeanPostProcessor ltwap = (BeanPostProcessor) BeanUtils.instantiateClass(ltwapClass);
((BeanFactoryAware) ltwap).setBeanFactory(beanFactory);
beanFactory.addBeanPostProcessor(ltwap);
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException("Spring's LoadTimeWeaverAwareProcessor class is not available");
}
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
Configure the factory's standard context characteristics,
such as the context's ClassLoader and post-processors. |
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
synchronized (this.activeMonitor) {
this.active = true;
}
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
}
Prepare this context for refreshing, setting its startup date and
active flag. |
public void publishEvent(ApplicationEvent event) {
Assert.notNull(event, "Event must not be null");
if (logger.isDebugEnabled()) {
logger.debug("Publishing event in context [" + getId() + "]: " + event);
}
getApplicationEventMulticaster().multicastEvent(event);
if (this.parent != null) {
this.parent.publishEvent(event);
}
}
Publish the given event to all listeners.
Note: Listeners get initialized after the MessageSource, to be able
to access it within listener implementations. Thus, MessageSource
implementations cannot publish events. |
public void refresh() throws IllegalStateException, BeansException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
// Destroy already created singletons to avoid dangling resources.
beanFactory.destroySingletons();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
}
}
|
abstract protected void refreshBeanFactory() throws IllegalStateException, BeansException
Subclasses must implement this method to perform the actual configuration load.
The method is invoked by #refresh() before any other initialization work.
A subclass will either create a new bean factory and hold a reference to it,
or return a single BeanFactory instance that it holds. In the latter case, it will
usually throw an IllegalStateException if refreshing the context more than once. |
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List priorityOrderedPostProcessors = new ArrayList();
List orderedPostProcessorNames = new ArrayList();
List nonOrderedPostProcessorNames = new ArrayList();
for (int i = 0; i < postProcessorNames.length; i++) {
if (isTypeMatch(postProcessorNames[i], PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(postProcessorNames[i]));
}
else if (isTypeMatch(postProcessorNames[i], Ordered.class)) {
orderedPostProcessorNames.add(postProcessorNames[i]);
}
else {
nonOrderedPostProcessorNames.add(postProcessorNames[i]);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
Collections.sort(priorityOrderedPostProcessors, new OrderComparator());
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
List orderedPostProcessors = new ArrayList();
for (Iterator it = orderedPostProcessorNames.iterator(); it.hasNext();) {
String postProcessorName = (String) it.next();
orderedPostProcessors.add(getBean(postProcessorName));
}
Collections.sort(orderedPostProcessors, new OrderComparator());
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Finally, register all other BeanPostProcessors.
List nonOrderedPostProcessors = new ArrayList();
for (Iterator it = nonOrderedPostProcessorNames.iterator(); it.hasNext();) {
String postProcessorName = (String) it.next();
nonOrderedPostProcessors.add(getBean(postProcessorName));
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
}
|
protected void registerListeners() {
// Register statically specified listeners first.
for (Iterator it = getApplicationListeners().iterator(); it.hasNext();) {
addListener((ApplicationListener) it.next());
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
Collection listenerBeans = getBeansOfType(ApplicationListener.class, true, false).values();
for (Iterator it = listenerBeans.iterator(); it.hasNext();) {
addListener((ApplicationListener) it.next());
}
}
Add beans that implement ApplicationListener as listeners.
Doesn't affect other listeners, which can be added without being beans. |
public void registerShutdownHook() {
if (this.shutdownHook == null) {
// No shutdown hook registered yet.
this.shutdownHook = new Thread() {
public void run() {
doClose();
}
};
Runtime.getRuntime().addShutdownHook(this.shutdownHook);
}
}
|
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
Set a friendly name for this context.
Typically done during initialization of concrete context implementations. |
public void setId(String id) {
this.id = id;
}
Set the unique id of this application context.
Default is the object id of the context instance, or the name
of the context bean if the context is itself defined as a bean. |
public void setParent(ApplicationContext parent) {
this.parent = parent;
}
|
public void start() {
Map lifecycleBeans = getLifecycleBeans();
for (Iterator it = new LinkedHashSet(lifecycleBeans.keySet()).iterator(); it.hasNext();) {
String beanName = (String) it.next();
doStart(lifecycleBeans, beanName);
}
publishEvent(new ContextStartedEvent(this));
}
|
public void stop() {
Map lifecycleBeans = getLifecycleBeans();
for (Iterator it = new LinkedHashSet(lifecycleBeans.keySet()).iterator(); it.hasNext();) {
String beanName = (String) it.next();
doStop(lifecycleBeans, beanName);
}
publishEvent(new ContextStoppedEvent(this));
}
|
public String toString() {
StringBuffer sb = new StringBuffer(getId());
sb.append(": display name [").append(getDisplayName());
sb.append("]; startup date [").append(new Date(getStartupDate()));
sb.append("]; ");
ApplicationContext parent = getParent();
if (parent == null) {
sb.append("root of context hierarchy");
}
else {
sb.append("parent: ").append(parent.getId());
}
return sb.toString();
}
Return information about this context. |