1. Introduction

Normally, in Spring applications, we inject beans into Spring IoC using @Beans, @Service, @Controller, @Configuration, or other specific annotations. We can then use Spring IOC-managed beans using @AutoWired or JSR250, JSR330 specification annotations provided by the Spring framework.

2. Get beans from the application context

Today we will learn how to get beans from ApplicationContext. There are cases where we have to get beans from the application context.

2.1 Get all beans

ApplicationContext provides a method, getBeanDefinitionNames(), to get the names of all beans that have been successfully injected into the Spring IoC container. We can then get the specific Bean using the Bean name with its getBean(String Name) method. We use the CommandLineRunner interface introduced in the previous article to print the results.

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; import java.util.stream.Stream; /** * @author Felordcn */ @SpringBootApplication public class WarSpringBootApplication implements CommandLineRunner { @Autowired private ApplicationContext applicationContext; public static void main(String[] args) { SpringApplication.run(WarSpringBootApplication.class, args); } @Override public void run(String... args) throws Exception { String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames(); Stream.of(beanDefinitionNames).forEach(beanName->{ System.out.println("beanName : " + beanName); Object bean = applicationContext.getBean(beanName); System.out.println("Spring bean : " + bean); }); }}Copy the code

Running the application outputs:

22:15:54 2019-11-05. 6356-392 the INFO [main]. Cn felord. War. WarSpringBootApplication: Started WarSpringBootApplication in 4.663 seconds (JVM running for 7.58) beanName: org.springframework.context.annotation.internalConfigurationAnnotationProcessor Spring bean : org.springframework.context.annotation.ConfigurationClassPostProcessor@6c44052e beanName : org.springframework.context.annotation.internalAutowiredAnnotationProcessor Spring bean : org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor@5c371e13 beanName : org.springframework.context.annotation.internalCommonAnnotationProcessor Spring bean : org.springframework.context.annotation.CommonAnnotationBeanPostProcessor@530a8454 beanName : org.springframework.context.event.internalEventListenerProcessor Spring bean : org.springframework.context.event.EventListenerMethodProcessor@1e34c607 beanName : org.springframework.context.event.internalEventListenerFactory Spring bean : org.springframework.context.event.DefaultEventListenerFactory@5215cd9a beanName : fooController Spring bean : cn.felord.war.controller.FooController@31198ceb beanName : IServiceImpl Spring bean : cn.felord.war.controller.IServiceImpl@51671b08 <more... >Copy the code

2.2 Get a specific Bean by name

We can also see some clues from the printed information.

  • somebeanNameIs the fully qualified name of the class.
  • @Component,@Repository,@Service,@ControllerAnnotation creationBeanIf the bean name is not specified, the default rule for the name is the first letter of the class name in lowercase, as incn.felord.war.controller.FooControllerfooController. If the first two or more letters of the class name are uppercase, the name is the same as the class name, as incn.felord.war.controller.IServiceImplIServiceImpl
  • @BeanIdentification of theBean is the defaultIs the method name.
  • Configure class annotations@ConfigurationClass fully qualified names are generally used.

Note, however, that if you specify a name when declaring the Bean, it is just the name you specify. If we are familiar with these rules, it is a good idea to use the getBean(String Name) method mentioned above.

2.3 Get beans by type

If we don’t know the name of a particular type of Bean we want, we can get the Bean by type. ApplicationContext provides a method getBeansOfType() that can load all beans of a particular type of Bean. It returns a Map where the key is the Bean name and the value is the actual object of the Bean.

We modify the run method in the example in Section 2.1:

@Override public void run(String... args) throws Exception { Map<String, FooController> beansOfType = applicationContext.getBeansOfType(FooController.class); Beansoftype.foreach ((beanName,bean)->{system.out.println ("beanName: "+ beanName); System.out.println("bean: "+ bean); }); }Copy the code

Running again, the console prints:

BeanName: fooController bean: cn. Felord. War. Controller. F80bf fooController @ 545Copy the code

2.4 Get a Bean that declares the annotation tag for a particular Bean

The ApplicationContext’s getBeansWithAnnotation() method lets us get the Bean created by @Service, @Controller, or any other annotation that can be used to create the Bean.

@Override public void run(String... args) throws Exception { Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(Controller.class); BeansWithAnnotation. ForEach ((beanName, bean) - > {System. Out. Println (" beanName: "+ beanName); System.out.println("bean: "+ bean); }); }Copy the code

Print out:

BeanName: fooController bean: cn. Felord. War. Controller. 18 ca3c62 fooController @ beanName: basicErrorController bean:  org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController@2c0f7678Copy the code

3. Summary

In this article, you learn how to get a list of all beans from the Spring application context. Sometimes we need to check whether the beans we expect are loaded in the Spring context, or we need to check the specific beans that Spring IoC declares. Of course you can use the Spring Boot Actuator’s Beans endpoints to get all beans.

Follow our public id: Felordcn for more information

Personal blog: https://felord.cn