Spring 应用上下文获取 Bean 的常用姿势实例总结

网友投稿 431 2022-12-06


Spring 应用上下文获取 Bean 的常用姿势实例总结

本文实例讲述了Spring 应用上下文获取 Bean 的常用姿势。分享给大家供大家参考,具体如下:

1. 前言

通常,在Spring应用程序中,当我们使用 @Bean,@Service,@Controller,@Configuration 或者其它特定的注解将 Bean 注入 Spring IoC 。然后我们可以使用 Spring 框架提供的 @Autowired 或者 jsR250、JSR330 规范注解来使用由 Spring IoC 管理的 Bean 。

2. 从应用程序上下文中获取 Bean

今天我们将来学习如何从 ApplicationContext 中获取 Bean 。因为有些情况下我们不得不从应用程序上下文中来获取 Bean 。

2.1 获取所有的 Bean

ApplicationContext 提供了获取所有已经成功注入 Spring IoC 容器的 Bean 名称的方法 getBeanDefinitionNames() 。然后我们可以借助于其 getBean(String name) 方法使用 Bean 名称获取特定的 Bean。 我们使用之前文章中介绍的 CommandLineRunner 接口来打印一下结果。

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) {

SpringAppliIAEpKcation.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);

});

}

}

运行应用会输出:

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

2.2 通过名称获取特定的 Bean

从上面打印的信息我们也能看出来一些端倪。

有的 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) 方法不失为一种好办法。

2.3 通过类型来获取 Bean

如果我们不清楚我们想要的特定类型 Bean 的名称,我们可以根据类型来获取 Bean 。ApplicationContext 提供了可以加载特定类型的 Bean 的所有 Bean 的方法getBeansOfType()。它将返回 Map 其中键是 Bean 名称,而值是 Bean 的实际对象。

我们修改 2.1 章节 例子中的 run 方法:

@Override

public void run(String... args) throws Exception {

Map beansOfType = applicationContext.getBeansOfType(FooController.class);

beansOfType.forEach((beanName,bean)->{

System.out.println("beanName : " + beanName);

System.out.println("bean : " + bean);

});

}

再次运行,控制台打印出:

beanName : fooController

bean : cn.felord.war.controller.FooController@545f80bf

2.4 获取特定 Bean 声明注解标记的 Bean

ApplicationContext 的 getBeansWithAnnotation() 方法可以让我们获取 @Service,@Controller或任何其它可以用来创建 Bean 的注解创建的 Bean 。

@Override

public void run(String... args) throws Exception {

Map 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 信息。

更多关于java相关内容感兴趣的读者可查看本站专题:《Spring框架入门与进阶教程》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》

希望本文所述对大家java程序设计有所帮助。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java基本数据类型包装类原理解析
下一篇:IntelliJ IDEA 2020下载与安装教程图文详解
相关文章

 发表评论

暂时没有评论,来抢沙发吧~