How to print all Beans managed by Spring?

1. Introduction

In this article we will explore how to print all spring managed beans along with their class names.

2. Content

We will use the ApplicationContext interface to print all the beans and its class name. ApplicationContext interface extends several interfaces one of which is ListableBeanFactory. ListableBeanFactory interface has a method called getBeanDefinitionNames which returns a String[] array. This array contains bean names which are managed by Spring IOC Container.

Let us dive in.

3. Implement CommandLineRunner interface

Spring boot lets you execute a piece of code just after the application has started. Usually you will have one such implementation of CommandLineRunner interface. If you have more than one use @Order annotation of Spring to provide the sequence of operations.

Let us first see how the Main application class is written.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@EnableAutoConfiguration
@ComponentScan({ "com.justamonad" })
public class SpringBootModuleApplication 
							extends SpringBootServletInitializer {

	public static void main(String[] args) {
		SpringApplication.run(SpringBootModuleApplication.class);
	}

}

Moving on, let us name our class as GetAllBeans.

import org.springframework.boot.CommandLineRunner;

public class GetAllBeans implements CommandLineRunner {

	@Override
	public void run(String... args) throws Exception {
		// TODO Auto-generated method stub
		//
	}
}

Now let us inject the ApplicationContext interface to our class. We are using constructor injection. We have to annotate the class with @Named annotation too. You can use @Component annotation too. I am using JSR 330 annotations.

import javax.inject.Inject;
import javax.inject.Named;

import org.springframework.boot.CommandLineRunner;
import org.springframework.context.ApplicationContext;

@Named
public class GetAllBeans implements CommandLineRunner {

	private final ApplicationContext applicationContext;

	@Inject
	public GetAllBeans(ApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
	}

	@Override
	public void run(String... args) throws Exception {
		
	}

}

Now let us print all beans using ApplicationContext interface’s getBeanDefinitionNames method.

@Named
public class GetAllBeans implements CommandLineRunner {

	private final ApplicationContext applicationContext;

	@Inject
	public GetAllBeans(ApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
	}

	@Override
	public void run(String... args) throws Exception {
	  String[] beans = applicationContext.getBeanDefinitionNames();
	  Arrays.sort(beans);
	  for (String bean : beans) {
	    System.out.println(bean + " : " + 
							applicationContext.getType(bean));
	  }
	}

}
applicationTaskExecutor : class org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
basicErrorController : class org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController
beanNameHandlerMapping : class org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
beanNameViewResolver : class org.springframework.web.servlet.view.BeanNameViewResolver
characterEncodingFilter : class org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter
conventionErrorViewResolver : class org.springframework.boot.autoconfigure.web.servlet.error.DefaultErrorViewResolver
defaultServletHandlerMapping : interface org.springframework.web.servlet.HandlerMapping
// and others. Output is trimmed.

4. Using field injection.

Field injection is not a recommended way to inject dependencies. Below code is purely for informative purposes.

@Named
public class GetAllBeans implements CommandLineRunner {

	@Inject
	private ApplicationContext applicationContext;

	@Override
	public void run(String... args) throws Exception {
	  String[] beans = applicationContext.getBeanDefinitionNames();
	  Arrays.sort(beans);
	  for (String bean : beans) {
	    System.out.println(bean + " : " + 
							applicationContext.getType(bean));
	  }
	}
}

5. Using setter injection

As the field injection, setter injection is also not a recommended approach. Below code is just for informative purposes.

@Named
public class GetAllBeans implements CommandLineRunner {

	private ApplicationContext applicationContext;
	
	@Inject
	public void setApplicationContext(
							ApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
	}

	@Override
	public void run(String... args) throws Exception {
	  String[] beans = applicationContext.getBeanDefinitionNames();
	  Arrays.sort(beans);
	  for (String bean : beans) {
	    System.out.println(bean + " : " + 
							applicationContext.getType(bean));
	  }
	}

}

6. Printing beans using Stream API

@Override
public void run(String... args) throws Exception {
	String[] beans = applicationContext.getBeanDefinitionNames();
	Arrays.stream(beans)
		.sorted()
		.forEach(bean -> System.out.println(bean));
}

7. Conclusion

That is all on how to print all bean names using ApplicationContext.

Code can be found on Github. Click here.

Leave a Reply

Your email address will not be published. Required fields are marked *