From 811de8e50bb68bc055961ceb2719d1992b66df15 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 4 Sep 2015 14:38:23 +0200 Subject: [PATCH] AbstractApplicationContext allows for re-refresh and re-close Issue: SPR-13425 --- .../support/AbstractApplicationContext.java | 1 + .../ClassPathXmlApplicationContextTests.java | 32 +++++++++++-------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java index 0a23ea0314..81a4de473f 100644 --- a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java @@ -567,6 +567,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader */ protected void prepareRefresh() { this.startupDate = System.currentTimeMillis(); + this.closed.set(false); this.active.set(true); if (logger.isInfoEnabled()) { diff --git a/spring-context/src/test/java/org/springframework/context/support/ClassPathXmlApplicationContextTests.java b/spring-context/src/test/java/org/springframework/context/support/ClassPathXmlApplicationContextTests.java index 4b35c7a633..717d36ba93 100644 --- a/spring-context/src/test/java/org/springframework/context/support/ClassPathXmlApplicationContextTests.java +++ b/spring-context/src/test/java/org/springframework/context/support/ClassPathXmlApplicationContextTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2015 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. @@ -49,7 +49,7 @@ import static org.junit.Assert.*; * @author Juergen Hoeller * @author Chris Beams */ -public final class ClassPathXmlApplicationContextTests { +public class ClassPathXmlApplicationContextTests { private static final String PATH = "/org/springframework/context/support/"; private static final String RESOURCE_CONTEXT = PATH + "ClassPathXmlApplicationContextTests-resource.xml"; @@ -82,13 +82,23 @@ public final class ClassPathXmlApplicationContextTests { @Test public void testMultipleConfigLocations() { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext( - new String[] { FQ_CONTEXT_B, FQ_CONTEXT_C, FQ_CONTEXT_A}); + FQ_CONTEXT_B, FQ_CONTEXT_C, FQ_CONTEXT_A); assertTrue(ctx.containsBean("service")); assertTrue(ctx.containsBean("logicOne")); assertTrue(ctx.containsBean("logicTwo")); + + // re-refresh (after construction refresh) Service service = (Service) ctx.getBean("service"); ctx.refresh(); assertTrue(service.isProperlyDestroyed()); + + // regular close call + service = (Service) ctx.getBean("service"); + ctx.close(); + assertTrue(service.isProperlyDestroyed()); + + // re-activating and re-closing the context (SPR-13425) + ctx.refresh(); service = (Service) ctx.getBean("service"); ctx.close(); assertTrue(service.isProperlyDestroyed()); @@ -107,8 +117,7 @@ public final class ClassPathXmlApplicationContextTests { @Test public void testSingleConfigLocationWithClass() { - ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext( - SIMPLE_CONTEXT, getClass()); + ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(SIMPLE_CONTEXT, getClass()); assertTrue(ctx.containsBean("someMessageSource")); ctx.close(); } @@ -116,7 +125,7 @@ public final class ClassPathXmlApplicationContextTests { @Test public void testAliasWithPlaceholder() { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext( - new String[] { FQ_CONTEXT_B, FQ_ALIASED_CONTEXT_C, FQ_CONTEXT_A}); + FQ_CONTEXT_B, FQ_ALIASED_CONTEXT_C, FQ_CONTEXT_A); assertTrue(ctx.containsBean("service")); assertTrue(ctx.containsBean("logicOne")); assertTrue(ctx.containsBean("logicTwo")); @@ -144,16 +153,14 @@ public final class ClassPathXmlApplicationContextTests { private void checkExceptionFromInvalidValueType(Throwable ex) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ex.printStackTrace(new PrintStream(baos)); - String dump = FileCopyUtils.copyToString( - new InputStreamReader(new ByteArrayInputStream(baos.toByteArray()))); + String dump = FileCopyUtils.copyToString(new InputStreamReader(new ByteArrayInputStream(baos.toByteArray()))); assertTrue(dump.contains("someMessageSource")); assertTrue(dump.contains("useCodeAsDefaultMessage")); } @Test public void testContextWithInvalidLazyClass() { - ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext( - INVALID_CLASS_CONTEXT, getClass()); + ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(INVALID_CLASS_CONTEXT, getClass()); assertTrue(ctx.containsBean("someMessageSource")); try { ctx.getBean("someMessageSource"); @@ -167,8 +174,7 @@ public final class ClassPathXmlApplicationContextTests { @Test public void testContextWithClassNameThatContainsPlaceholder() { - ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext( - CLASS_WITH_PLACEHOLDER_CONTEXT, getClass()); + ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(CLASS_WITH_PLACEHOLDER_CONTEXT, getClass()); assertTrue(ctx.containsBean("someMessageSource")); assertTrue(ctx.getBean("someMessageSource") instanceof StaticMessageSource); ctx.close(); @@ -282,7 +288,7 @@ public final class ClassPathXmlApplicationContextTests { @Test public void testAliasThatOverridesEarlierBean() { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext( - new String[] {FQ_SIMPLE_CONTEXT, ALIAS_THAT_OVERRIDES_PARENT_CONTEXT}); + FQ_SIMPLE_CONTEXT, ALIAS_THAT_OVERRIDES_PARENT_CONTEXT); Object myMs = ctx.getBean("myMessageSource"); Object someMs2 = ctx.getBean("someMessageSource"); assertSame(myMs, someMs2);