一般,在Spring应用程序中,当咱们使用 @Bean
,@Service
,@Controller
,@Configuration
或者其它特定的注解将 Bean 注入 Spring IoC 。而后咱们可使用 Spring 框架提供的 @Autowired
或者 JSR250、JSR330 规范注解来使用由 Spring IoC 管理的 Bean 。html
今天咱们未来学习如何从 ApplicationContext
中获取 Bean 。由于有些状况下咱们不得不从应用程序上下文中来获取 Bean 。java
ApplicationContext
提供了获取全部已经成功注入 Spring IoC 容器的 Bean 名称的方法 getBeanDefinitionNames()
。而后咱们能够借助于其 getBean(String name)
方法使用 Bean 名称获取特定的 Bean。 咱们使用以前文章中介绍的 CommandLineRunner
接口来打印一下结果。web
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); }); } }
运行应用会输出:spring
2019-11-05 22:15:54.392 INFO 6356 --- [ 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...>
从上面打印的信息咱们也能看出来一些端倪。springboot
beanName
是类全限定名。@Component
、@Repository
、@Service
、@Controller
等注解建立 Bean 时,若是不指定bean名称,名称的默认规则是类名的首字母小写,如 cn.felord.war.controller.FooController
为 fooController
。若是类名前两个或以上个字母都是大写,那么名称与类名同样,如 cn.felord.war.controller.IServiceImpl
为 IServiceImpl
@Bean
标识的 Bean 默认 为方法名称。@Configuration
通常使用类全限定名。可是请注意:若是你在声明 Bean 的时候指定了名称就只是你指定的名称 。若是咱们熟悉这些规则,使用上面提到的getBean(String name)
方法不失为一种好办法。app
若是咱们不清楚咱们想要的特定类型 Bean 的名称,咱们能够根据类型来获取 Bean 。ApplicationContext
提供了能够加载特定类型的 Bean 的全部 Bean 的方法getBeansOfType()
。它将返回 Map <String,Object>
其中键是 Bean 名称,而值是 Bean
的实际对象。框架
咱们修改 2.1 章节 例子中的 run
方法:ide
@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); }); }
再次运行,控制台打印出:spring-boot
beanName : fooController bean : cn.felord.war.controller.FooController@545f80bf
ApplicationContext
的 getBeansWithAnnotation()
方法可让咱们获取 @Service
,@Controller
或任何其它能够用来建立 Bean 的注解建立的 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); }); }
打印出:
beanName : fooController bean : cn.felord.war.controller.FooController@18ca3c62 beanName : basicErrorController bean : org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController@2c0f7678
## 3. 总结
在本文中,咱们学习如何从 Spring 应用上下文中获取全部 Bean 的列表。有时咱们须要检查咱们指望的 Bean 是否在 Spring 上下文中加载,或者咱们须要检查 Spring IoC 声明的特定的 Bean 。固然你能够开启Spring Boot Actuator 的 beans
端点来获取全部的 Bean 信息。
关注公众号:Felordcn 获取更多资讯