Servlet/Portlet ApplicationContexts use a specific id based on servlet/portlet name; DefaultListableBeanFactory references are serializable now when initialized with an id; scoped proxies are serializable now, for web scopes as well as for singleton beans; injected request/session references are serializable proxies for the current request now

This commit is contained in:
Juergen Hoeller
2009-05-07 22:29:55 +00:00
parent 4ccb352aac
commit 266a65982d
26 changed files with 582 additions and 167 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -65,6 +65,11 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life
String SYSTEM_ENVIRONMENT_BEAN_NAME = "systemEnvironment";
/**
* Set the unique id of this application context.
*/
void setId(String id);
/**
* Set the parent of this application context.
* <p>Note that the parent shouldn't be changed: It should only be set outside

View File

@@ -382,7 +382,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
catch (BeansException ex) {
// Destroy already created singletons to avoid dangling resources.
beanFactory.destroySingletons();
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
@@ -794,7 +794,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* destroys the singletons in the bean factory of this application context.
* <p>Called by both <code>close()</code> and a JVM shutdown hook, if any.
* @see org.springframework.context.event.ContextClosedEvent
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons()
* @see #destroyBeans()
* @see #close()
* @see #registerShutdownHook()
*/
@@ -803,6 +803,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
if (logger.isInfoEnabled()) {
logger.info("Closing " + this);
}
try {
// Publish shutdown event.
publishEvent(new ContextClosedEvent(this));
@@ -810,15 +811,19 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
catch (Throwable ex) {
logger.error("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
}
// Stop all Lifecycle beans, to avoid delays during individual destruction.
Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
for (String beanName : new LinkedHashSet<String>(lifecycleBeans.keySet())) {
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;

View File

@@ -122,6 +122,7 @@ public abstract class AbstractRefreshableApplicationContext extends AbstractAppl
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
@@ -134,9 +135,18 @@ public abstract class AbstractRefreshableApplicationContext extends AbstractAppl
}
}
@Override
protected void cancelRefresh(BeansException ex) {
synchronized (this.beanFactoryMonitor) {
this.beanFactory.setSerializationId(null);
}
super.cancelRefresh(ex);
}
@Override
protected final void closeBeanFactory() {
synchronized (this.beanFactoryMonitor) {
this.beanFactory.setSerializationId(null);
this.beanFactory = null;
}
}

View File

@@ -99,6 +99,7 @@ public class GenericApplicationContext extends AbstractApplicationContext implem
*/
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
this.beanFactory.setSerializationId(getId());
this.beanFactory.setParameterNameDiscoverer(new LocalVariableTableParameterNameDiscoverer());
this.beanFactory.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
}
@@ -149,6 +150,12 @@ public class GenericApplicationContext extends AbstractApplicationContext implem
this.beanFactory.setParentBeanFactory(getInternalParentBeanFactory());
}
@Override
public void setId(String id) {
super.setId(id);
this.beanFactory.setSerializationId(id);
}
/**
* Set a ResourceLoader to use for this context. If set, the context will
* delegate all <code>getResource</code> calls to the given ResourceLoader.
@@ -219,11 +226,12 @@ public class GenericApplicationContext extends AbstractApplicationContext implem
}
/**
* Do nothing: We hold a single internal BeanFactory that will never
* Not much to do: We hold a single internal BeanFactory that will never
* get released.
*/
@Override
protected final void closeBeanFactory() {
this.beanFactory.setSerializationId(null);
}
/**