Update admin MBean to only be ready when its own context is ready

Previously, if there was a hierarchy of SpringApplications, the admin
MBean would report that the application was ready as soon as any
application in the hierarchy was ready. This could lead to a client
trying to query a property in the environment before it's available.

This commit updates the MBean registrar to that the MBean only reports
that the application is ready when the context that contains the
registrar has refreshed and fired its ApplicationReadyEvent.

Closes gh-6362
pull/6458/head
Andy Wilkinson 8 years ago
parent 4963cfd67b
commit c2db9fa385

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -44,6 +44,7 @@ import org.springframework.util.Assert;
* {@link MBeanServer}.
*
* @author Stephane Nicoll
* @author Andy Wilkinson
* @since 1.3.0
*/
public class SpringApplicationAdminMXBeanRegistrar
@ -80,7 +81,9 @@ public class SpringApplicationAdminMXBeanRegistrar
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
this.ready = true;
if (this.applicationContext.equals(event.getApplicationContext())) {
this.ready = true;
}
}
@Override

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -30,20 +30,26 @@ import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.test.util.ReflectionTestUtils;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link SpringApplicationAdminMXBeanRegistrar}.
*
* @author Stephane Nicoll
* @author Andy Wilkinson
*/
public class SpringApplicationAdminMXBeanRegistrarTests {
@ -89,6 +95,25 @@ public class SpringApplicationAdminMXBeanRegistrarTests {
assertThat(isApplicationReady(objectName), is(true));
}
@Test
public void eventsFromOtherContextsAreIgnored() throws MalformedObjectNameException {
SpringApplicationAdminMXBeanRegistrar registrar = new SpringApplicationAdminMXBeanRegistrar(
OBJECT_NAME);
ConfigurableApplicationContext context = mock(
ConfigurableApplicationContext.class);
registrar.setApplicationContext(context);
registrar.onApplicationEvent(new ApplicationReadyEvent(new SpringApplication(),
null, mock(ConfigurableApplicationContext.class)));
assertFalse(isApplicationReady(registrar));
registrar.onApplicationEvent(
new ApplicationReadyEvent(new SpringApplication(), null, context));
assertTrue(isApplicationReady(registrar));
}
private boolean isApplicationReady(SpringApplicationAdminMXBeanRegistrar registrar) {
return (Boolean) ReflectionTestUtils.getField(registrar, "ready");
}
@Test
public void environmentIsExposed() {
final ObjectName objectName = createObjectName(OBJECT_NAME);

Loading…
Cancel
Save