Skip to content

Instantly share code, notes, and snippets.

@aleung
Created November 8, 2011 06:41
Show Gist options
  • Save aleung/1347171 to your computer and use it in GitHub Desktop.
Save aleung/1347171 to your computer and use it in GitHub Desktop.
Dump beans information in a Springframework application context. Licensed under WTFPL v2. More detail in blog post: http://aleung.github.io/blog/2011/11/08/Dump-beans-information-from-live-Spring-application-context/
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"
default-lazy-init="false" default-autowire="byName">
<!-- Enable @Autowired -->
<context:annotation-config/>
<!-- Load all beans with @Repository -->
<context:component-scan base-package="leoliang.springtest"/>
<bean id="aNormalBean" class="leoliang.springtest.NormalBean">
<property name="anotherBean" ref="anotherBean"/>
</bean>
<bean class="leoliang.springtest.ApplicationContextDumper" />
</beans>
package leoliang.springtest;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.AbstractRefreshableApplicationContext;
public class ApplicationContextDumper implements ApplicationContextAware {
private Map<String, Integer> beanReferenceCounter = new HashMap<String, Integer>();
private StringBuilder outputMessage;
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
outputMessage = new StringBuilder();
beanReferenceCounter.clear();
outputMessage.append("--- ApplicationContextDumper begin ---\n");
dumpApplicationContext(context);
dumpBeansWithoutReference();
outputMessage.append("--- ApplicationContextDumper end ---\n");
System.out.print(outputMessage);
}
private void dumpBeansWithoutReference() {
outputMessage.append("Beans without reference:\n");
for (String bean : beanReferenceCounter.keySet()) {
if (beanReferenceCounter.get(bean) == 0) {
outputMessage.append(" ").append(bean).append('\n');
}
}
}
private void initBeanReferenceIfNotExist(String beanName) {
Integer count = beanReferenceCounter.get(beanName);
if (count == null) {
beanReferenceCounter.put(beanName, 0);
}
}
private void increaseBeanReference(String beanName) {
Integer count = beanReferenceCounter.get(beanName);
if (count == null) {
count = new Integer(0);
}
beanReferenceCounter.put(beanName, ++count);
}
private void dumpApplicationContext(ApplicationContext context) {
// Read context id isn't available. https://jira.springsource.org/browse/SPR-8816
String appContextInfo = String.format("ApplicationContext %s : %s", context.getId(), context.getClass()
.getName());
ApplicationContext parent = context.getParent();
if (parent != null) {
appContextInfo += String.format(" -> %s", parent.getId());
}
outputMessage.append(appContextInfo).append('\n');
ConfigurableListableBeanFactory factory = ((AbstractRefreshableApplicationContext) context).getBeanFactory();
for (String beanName : factory.getBeanDefinitionNames()) {
if (factory.getBeanDefinition(beanName).isAbstract()) {
continue;
}
initBeanReferenceIfNotExist(beanName);
Object bean = factory.getBean(beanName);
outputMessage.append(String.format(" %s : %s\n", beanName, bean.getClass().getName()));
for (String dependency : factory.getDependenciesForBean(beanName)) {
outputMessage.append(String.format(" -> %s\n", dependency));
increaseBeanReference(dependency);
}
}
if (parent != null) {
outputMessage.append("Parent:\n");
dumpApplicationContext(parent);
}
}
}
<beans>
<bean id="parentBeanFactory" class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg>
<list>
<value>classpath:**/parentContext.xml</value>
</list>
</constructor-arg>
</bean>
<bean id="myBeanFactory" class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg>
<list>
<value>classpath:**/applicationContext.xml</value>
</list>
</constructor-arg>
<constructor-arg>
<ref bean="parentBeanFactory" />
</constructor-arg>
</bean>
</beans>
public static void main(String[] args) {
String[] paths = { "classpath:**/beanRefContext.xml" };
new ClassPathXmlApplicationContext(paths);
}
--- ApplicationContextDumper begin ---
ApplicationContext org.springframework.context.support.ClassPathXmlApplicationContext@e1d5ea : org.springframework.context.support.ClassPathXmlApplicationContext -> parentBeanFactory
org.springframework.context.annotation.internalConfigurationAnnotationProcessor : org.springframework.context.annotation.ConfigurationClassPostProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor : org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor : org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor : org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
repositoryBean : leoliang.springtest.RepositoryBean
-> aNormalBean
aNormalBean : leoliang.springtest.NormalBean
-> anotherBean
leoliang.springtest.ApplicationContextDumper#0 : leoliang.springtest.ApplicationContextDumper
Parent:
ApplicationContext parentBeanFactory : org.springframework.context.support.ClassPathXmlApplicationContext
anotherBean : leoliang.springtest.AnotherBean
Beans without reference:
repositoryBean
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
leoliang.springtest.ApplicationContextDumper#0
--- ApplicationContextDumper end ---
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="abstractBean" abstract="true" />
<bean id="anotherBean" class="leoliang.springtest.AnotherBean" parent="abstractBean" />
</beans>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment