Browse Source

Fixed LiveBeansView to not produce invalid JSON if last bean is not eligible

Also introducing overridable isBeanEligible template method.

Issue: SPR-11366
pull/455/head
Juergen Hoeller 12 years ago
parent
commit
c1eac209c3
  1. 46
      spring-context/src/main/java/org/springframework/context/support/LiveBeansView.java

46
spring-context/src/main/java/org/springframework/context/support/LiveBeansView.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2014 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -25,6 +25,7 @@ import javax.management.MBeanServer;
import javax.management.ObjectName; import javax.management.ObjectName;
import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationContextAware;
@ -40,7 +41,7 @@ import org.springframework.util.StringUtils;
* (driven by the {@value #MBEAN_DOMAIN_PROPERTY_NAME} environment property). * (driven by the {@value #MBEAN_DOMAIN_PROPERTY_NAME} environment property).
* *
* <p>Note: This feature is still in beta and primarily designed for use with * <p>Note: This feature is still in beta and primarily designed for use with
* Spring Tool Suite 3.1. * Spring Tool Suite 3.1 and higher.
* *
* @author Juergen Hoeller * @author Juergen Hoeller
* @since 3.2 * @since 3.2
@ -118,6 +119,17 @@ public class LiveBeansView implements LiveBeansViewMBean, ApplicationContextAwar
return generateJson(contexts); return generateJson(contexts);
} }
/**
* Find all applicable ApplicationContexts for the current application.
* <p>Called if no specific ApplicationContext has been set for this LiveBeansView.
* @return the set of ApplicationContexts
*/
protected Set<ConfigurableApplicationContext> findApplicationContexts() {
synchronized (applicationContexts) {
return new LinkedHashSet<ConfigurableApplicationContext>(applicationContexts);
}
}
/** /**
* Actually generate a JSON snapshot of the beans in the given ApplicationContexts. * Actually generate a JSON snapshot of the beans in the given ApplicationContexts.
* <p>This implementation doesn't use any JSON parsing libraries in order to avoid * <p>This implementation doesn't use any JSON parsing libraries in order to avoid
@ -143,11 +155,13 @@ public class LiveBeansView implements LiveBeansViewMBean, ApplicationContextAwar
result.append("\"beans\": [\n"); result.append("\"beans\": [\n");
ConfigurableListableBeanFactory bf = context.getBeanFactory(); ConfigurableListableBeanFactory bf = context.getBeanFactory();
String[] beanNames = bf.getBeanDefinitionNames(); String[] beanNames = bf.getBeanDefinitionNames();
for (int i = 0; i < beanNames.length; i++) { boolean elementAppended = false;
String beanName = beanNames[i]; for (String beanName : beanNames) {
BeanDefinition bd = bf.getBeanDefinition(beanName); BeanDefinition bd = bf.getBeanDefinition(beanName);
if (bd.getRole() != BeanDefinition.ROLE_INFRASTRUCTURE && if (isBeanEligible(beanName, bd, bf)) {
(!bd.isLazyInit() || bf.containsSingleton(beanName))) { if (elementAppended) {
result.append(",\n");
}
result.append("{\n\"bean\": \"").append(beanName).append("\",\n"); result.append("{\n\"bean\": \"").append(beanName).append("\",\n");
String scope = bd.getScope(); String scope = bd.getScope();
if (!StringUtils.hasText(scope)) { if (!StringUtils.hasText(scope)) {
@ -173,9 +187,7 @@ public class LiveBeansView implements LiveBeansViewMBean, ApplicationContextAwar
result.append("\""); result.append("\"");
} }
result.append("]\n}"); result.append("]\n}");
if (i < beanNames.length - 1) { elementAppended = true;
result.append(",\n");
}
} }
} }
result.append("]\n"); result.append("]\n");
@ -189,14 +201,16 @@ public class LiveBeansView implements LiveBeansViewMBean, ApplicationContextAwar
} }
/** /**
* Find all applicable ApplicationContexts for the current application. * Determine whether the specified bean is eligible for inclusion in the
* <p>Called if no specific ApplicationContext has been set for this LiveBeansView. * LiveBeansView JSON snapshot.
* @return the set of ApplicationContexts * @param beanName the name of the bean
* @param bd the corresponding bean definition
* @param bf the containing bean factory
* @return {@code true} if the bean is to be included; {@code false} otherwise
*/ */
protected Set<ConfigurableApplicationContext> findApplicationContexts() { protected boolean isBeanEligible(String beanName, BeanDefinition bd, ConfigurableBeanFactory bf) {
synchronized (applicationContexts) { return (bd.getRole() != BeanDefinition.ROLE_INFRASTRUCTURE &&
return new LinkedHashSet<ConfigurableApplicationContext>(applicationContexts); (!bd.isLazyInit() || bf.containsSingleton(beanName)));
}
} }
} }

Loading…
Cancel
Save