add RefreshScopeRefreshedEvent when RefreshScope.refresh*() is called. This is so apps can do something when a POST is received at /refresh even if the environment hasn't changed.

This commit is contained in:
Spencer Gibb
2014-12-03 11:36:47 -07:00
parent 2caf87f92e
commit 28b27dfac7
3 changed files with 56 additions and 8 deletions

View File

@@ -15,6 +15,9 @@ package org.springframework.cloud.context.scope.refresh;
import java.io.Serializable;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.cloud.context.scope.GenericScope;
@@ -54,7 +57,10 @@ import org.springframework.cloud.context.scope.GenericScope;
*
*/
@ManagedResource
public class RefreshScope extends GenericScope {
public class RefreshScope extends GenericScope implements ApplicationContextAware {
protected static final String SCOPED_TARGET_PREFIX = "scopedTarget.";
private ApplicationContext context;
/**
* Create a scope instance and give it the default name: "refresh".
@@ -66,17 +72,23 @@ public class RefreshScope extends GenericScope {
@ManagedOperation(description = "Dispose of the current instance of bean name provided and force a refresh on next method execution.")
public void refresh(String name) {
if (!name.startsWith("scopedTarget.")) {
if (!name.startsWith(SCOPED_TARGET_PREFIX)) {
// User wants to refresh the bean with this name but that isn't the one in the cache...
name = "scopedTarget." + name;
name = SCOPED_TARGET_PREFIX + name;
}
// Ensure lifecycle is finished if bean was disposable
super.destroy(name);
context.publishEvent(new RefreshScopeRefreshedEvent(name));
}
@ManagedOperation(description = "Dispose of the current instance of all beans in this scope and force a refresh on next method execution.")
public void refreshAll() {
super.destroy();
context.publishEvent(new RefreshScopeRefreshedEvent());
}
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
this.context = context;
}
}

View File

@@ -0,0 +1,24 @@
package org.springframework.cloud.context.scope.refresh;
import org.springframework.context.ApplicationEvent;
/**
* @author Spencer Gibb
*/
public class RefreshScopeRefreshedEvent extends ApplicationEvent {
public static final String DEFAULT_NAME = "__refreshAll__";
private String name;
public RefreshScopeRefreshedEvent() {
this(DEFAULT_NAME);
}
public RefreshScopeRefreshedEvent(String name) {
super(name);
this.name = name;
}
public String getName() {
return name;
}
}

View File

@@ -15,10 +15,6 @@
*/
package org.springframework.cloud.context.scope.refresh;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Before;
@@ -35,6 +31,7 @@ import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.context.scope.refresh.RefreshScopeIntegrationTests.TestConfiguration;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@@ -43,6 +40,8 @@ import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.*;
@SpringApplicationConfiguration(classes = TestConfiguration.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class RefreshScopeIntegrationTests {
@@ -88,6 +87,9 @@ public class RefreshScopeIntegrationTests {
assertEquals(2, ExampleService.getInitCount());
assertEquals(1, ExampleService.getDestroyCount());
assertNotSame(id1, id2);
assertNotNull(ExampleService.event);
assertEquals(RefreshScopeRefreshedEvent.DEFAULT_NAME,
ExampleService.event.getName());
}
@Test
@@ -104,6 +106,10 @@ public class RefreshScopeIntegrationTests {
assertEquals(2, ExampleService.getInitCount());
assertEquals(1, ExampleService.getDestroyCount());
assertNotSame(id1, id2);
assertNotNull(ExampleService.event);
assertEquals(
org.springframework.cloud.context.scope.refresh.RefreshScope.SCOPED_TARGET_PREFIX
+ "service", ExampleService.event.getName());
}
public static interface Service {
@@ -113,12 +119,13 @@ public class RefreshScopeIntegrationTests {
}
public static class ExampleService implements Service, InitializingBean,
DisposableBean {
DisposableBean, ApplicationListener<RefreshScopeRefreshedEvent> {
private static Log logger = LogFactory.getLog(ExampleService.class);
private volatile static int initCount = 0;
private volatile static int destroyCount = 0;
private volatile static RefreshScopeRefreshedEvent event;
private String message = null;
private volatile long delay = 0;
@@ -141,6 +148,7 @@ public class RefreshScopeIntegrationTests {
public static void reset() {
initCount = 0;
destroyCount = 0;
event = null;
}
public static int getInitCount() {
@@ -168,6 +176,10 @@ public class RefreshScopeIntegrationTests {
return message;
}
@Override
public void onApplicationEvent(RefreshScopeRefreshedEvent e) {
event = e;
}
}
@Configuration