From becc965847aa2923dfe52ee8c8666cc65903c386 Mon Sep 17 00:00:00 2001 From: Scott Andrews Date: Tue, 4 Nov 2008 17:20:09 +0000 Subject: [PATCH] SWF-929 Flow ApplicationContext is never closed - causes AMS to leave MBeans behind --- .../config/FlowRegistryFactoryBean.java | 9 ++++++++- .../registry/FlowDefinitionRegistryImpl.java | 20 ++++++++++++++++++- .../builder/model/FlowModelFlowBuilder.java | 1 + 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/spring-webflow/src/main/java/org/springframework/webflow/config/FlowRegistryFactoryBean.java b/spring-webflow/src/main/java/org/springframework/webflow/config/FlowRegistryFactoryBean.java index 993a79c3..48d536d0 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/config/FlowRegistryFactoryBean.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/config/FlowRegistryFactoryBean.java @@ -21,6 +21,7 @@ import java.util.Iterator; import java.util.Set; import org.springframework.beans.factory.BeanClassLoaderAware; +import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.binding.convert.ConversionExecutor; @@ -54,7 +55,7 @@ import org.springframework.webflow.engine.model.registry.FlowModelHolder; * @author Jeremy Grelle * @author Scott Andrews */ -class FlowRegistryFactoryBean implements FactoryBean, BeanClassLoaderAware, InitializingBean { +class FlowRegistryFactoryBean implements FactoryBean, BeanClassLoaderAware, InitializingBean, DisposableBean { private FlowLocation[] flowLocations; @@ -154,6 +155,12 @@ class FlowRegistryFactoryBean implements FactoryBean, BeanClassLoaderAware, Init return true; } + // implement DisposableBean + + public void destroy() throws Exception { + flowRegistry.destroy(); + } + private void registerFlowLocations() { if (flowLocations != null) { for (int i = 0; i < flowLocations.length; i++) { diff --git a/spring-webflow/src/main/java/org/springframework/webflow/definition/registry/FlowDefinitionRegistryImpl.java b/spring-webflow/src/main/java/org/springframework/webflow/definition/registry/FlowDefinitionRegistryImpl.java index a40b62a5..1512f1a0 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/definition/registry/FlowDefinitionRegistryImpl.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/definition/registry/FlowDefinitionRegistryImpl.java @@ -15,11 +15,15 @@ */ package org.springframework.webflow.definition.registry; +import java.util.Iterator; import java.util.Map; import java.util.TreeMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.style.ToStringCreator; import org.springframework.util.Assert; import org.springframework.webflow.definition.FlowDefinition; @@ -30,7 +34,7 @@ import org.springframework.webflow.definition.FlowDefinition; * @author Keith Donald * @author Scott Andrews */ -public class FlowDefinitionRegistryImpl implements FlowDefinitionRegistry { +public class FlowDefinitionRegistryImpl implements FlowDefinitionRegistry, DisposableBean { private static final Log logger = LogFactory.getLog(FlowDefinitionRegistryImpl.class); @@ -102,6 +106,20 @@ public class FlowDefinitionRegistryImpl implements FlowDefinitionRegistry { registerFlowDefinition(new StaticFlowDefinitionHolder(definition)); } + // implementing DisposableBean + + public void destroy() throws Exception { + Iterator flowDefinitionKeyIt = flowDefinitions.keySet().iterator(); + while (flowDefinitionKeyIt.hasNext()) { + FlowDefinitionHolder holder = this.getFlowDefinitionHolder((String) flowDefinitionKeyIt.next()); + FlowDefinition flowDefinition = holder.getFlowDefinition(); + ApplicationContext context = flowDefinition.getApplicationContext(); + if (context instanceof ConfigurableApplicationContext) { + ((ConfigurableApplicationContext) context).close(); + } + } + } + // internal helpers /** diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/FlowModelFlowBuilder.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/FlowModelFlowBuilder.java index a0995566..a512b957 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/FlowModelFlowBuilder.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/FlowModelFlowBuilder.java @@ -333,6 +333,7 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder { } else { flowContext = new GenericApplicationContext(); } + flowContext.setDisplayName("Flow ApplicationContext [" + getContext().getFlowId() + "]"); flowContext.setParent(parent); flowContext.getBeanFactory().registerScope("request", new RequestScope()); flowContext.getBeanFactory().registerScope("flash", new FlashScope());