【SpringBoot】浅谈向容器注入Bean有几种方式

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: SpringBoot的核心之一是通过IOC容器管理各个bean对象,前几天看到一个大厂面试题问向Spring容器中注入bean有哪几种方式,今天整理了下跟大家分析一波。


前言


SpringBoot的核心之一是通过IOC容器管理各个bean对象,前几天看到一个大厂面试题问向Spring容器中注入bean有哪几种方式,今天整理了下跟大家分析一波。


这个题看似简单,实则暗藏玄机,可能大部分掘友能回答出一部分,要回答全面在众多面试者中脱颖而出似乎不是那么简单。


首先面试官问出这个问题,思路应该要立刻转到SpringBoot的启动流程来,按SpringBoot是怎么扫描出要注入的类入手。


启动流程模糊的掘友可以回顾下之前的文章:【SpringBoot启动流程】https://developer.aliyun.com/article/1038860?spm=a2c6h.13148508.setting.15.229f4f0ew1zijc


@Component + @ComponentScan


SpringBoot启动类的@SpringBootApplication注解中就标注了 @ComponentScan注解,这个注解默认扫描当前包及其子包下的标注有@Component@Controller@Service@Repository等的类加载到容器中。


这一条应该都能答出来,属于基础八股了。


@Import注解


了解过SpringBoot源码的掘友应该对这个注解不陌生,SpringBoot之所以拥有自动装配能力,全依仗于启动类@SpringBootApplication注解中的另一个核心注解@EnableAutoConfiguration


点进去这个注解会发现 @Import(AutoConfigurationImportSelector.class),也就是通过将AutoConfigurationImportSelector类加载到容器中。


并通过此类的getAutoConfigurationEntry()方法,查找并筛选出位于META-INF/spring.factories文件中的所有需要注入的自动配置类并加载。


这个注解也可以直接注入class,SpringBoot默认是注入ImportSelector接口,重写selectImports规则实现,本质上都是将外部类加载到当前classpath中并注入成bean。


@Configuration + @Bean


这个组合相信大家都有用过,比如想利用ioc容器管理一个map容器,只需要在配置类上标注上@Configuration声明配置类,在某个方法上标注@Bean并返回一个new HashMap即可。


@ConfigurationpublicclassTestConfig {
@BeanpublicMapTestAutoMap() {
returnnewHashMap();
   }
}



BeanDefinitionRegistryPostProcessor


万变不离其宗,掌握SpringBoot启动流程和SpringBean的生命周期,很多问题就能连点成线的串起来。


我们知道SpringBean的生命周期中有很多前后置方法,整体上可以概括为普通类对象转化为beanDefinition再转化为spring中的bean这么三个阶段。


而Spring会在启动的AbstratApplicationContxt类中的refresh方法中执行

invokeBeanFactoryPostProcessors,这个方法中会回调所有实现

BeanDefinitionRegistryPostProcessor接口的钩子方法。


可以简单理解成beanDefinition加载完毕之后,会对beanDefinition进行后置处理。所以理论上实现BeanDefinitionRegistryPostProcessor接口就可以手动将bean注入到容器中。

publicclassTestBeanProcessor {
publicstaticvoidmain(String[] args) {
AnnotationConfigApplicationContextapplicationContext=newAnnotationConfigApplicationContext();
UptownBeanProcessorbeanDefinitionRegistryPostProcessor=newUptownBeanProcessor();
applicationContext.addBeanFactoryPostProcessor(beanDefinitionRegistryPostProcessor);
applicationContext.refresh();
Objectbean=applicationContext.getBean("test_map");
System.out.println(bean);
   }
}
classUptownBeanProcessorimplementsBeanDefinitionRegistryPostProcessor {
@OverridepublicvoidpostProcessBeanDefinitionRegistry(BeanDefinitionRegistryregistry) throwsBeansException {
AbstractBeanDefinitionbeanDefinition=BeanDefinitionBuilder.rootBeanDefinition(HashMap.class).getBeanDefinition();
registry.registerBeanDefinition("test_map", beanDefinition);
   }
@OverridepublicvoidpostProcessBeanFactory(ConfigurableListableBeanFactorybeanFactory) throwsBeansException {
   }
}



总结

  • 按照SpringBoot启动原理和SpringBean的生命周期为思路
  • @Component + @ComponentScan
  • @Bean + @Configuration
  • @Import
  • BeanDefinitionRegistryPostProcessor接口实现postProcessBeanDefinitionRegistry后置函数







相关文章
|
8天前
|
Java Spring
解决Springboot集成ElasticSearch 报错:A bean with that name has already been defined in null and overriding
解决Springboot集成ElasticSearch 报错:A bean with that name has already been defined in null and overriding
|
19天前
|
Java 开发者 Spring
Springboot中的@Bean用法以及常见问题
【5月更文挑战第27天】@Bean 注解是Spring框架中用于声明Spring应用上下文中的bean的一种方式。在Spring Boot中,@Bean注解通常与@Configuration注解一起使用,在配置类(Configuration class)中定义bean。
32 2
|
22天前
|
Java 容器 Spring
Spring的加载配置文件、容器和获取bean的方式
Spring的加载配置文件、容器和获取bean的方式
28 3
Spring的加载配置文件、容器和获取bean的方式
|
1月前
|
XML Java 数据库
【SpringBoot:详解Bean装配】
【SpringBoot:详解Bean装配】
12 3
|
1月前
|
存储 Java 应用服务中间件
Springboot项目打war包部署到外置tomcat容器【详解版】
该文介绍了将Spring Boot应用改为war包并在外部Tomcat中部署的步骤:1) 修改pom.xml打包方式为war;2) 排除内置Tomcat依赖;3) 创建`ServletInitializer`类继承`SpringBootServletInitializer`;4) build部分需指定`finalName`;5) 使用`mvn clean package`打包,将war包放入外部Tomcat的webapps目录,通过startup脚本启动Tomcat并访问应用。注意,应用访问路径和静态资源引用需包含war包名。
|
1月前
|
Java Spring 容器
SpringBoot 使用Quartz执行定时任务对象时无法注入Bean问题
SpringBoot 使用Quartz执行定时任务对象时无法注入Bean问题
36 1
|
1月前
|
Java Maven Docker
【SpringBoot系列】SpringBoot应用程序容器化及容器优化
【4月更文挑战第4天】SpringBoot应用程序容器化及容器大小优化
34 0
|
1月前
|
JSON Java 数据库连接
属性注入掌握:Spring Boot配置属性的高级技巧与最佳实践
属性注入掌握:Spring Boot配置属性的高级技巧与最佳实践
30 1
|
1月前
|
Java Spring 容器
SpringBoot中bean的生命周期
Spring Boot的Bean生命周期涉及实例化、属性注入、初始化和销毁。在实例化后,Spring通过构造函数或Setter注入属性,然后调用初始化方法(@PostConstruct、InitializingBean接口)。Bean在应用中使用后,当容器关闭时,会调用销毁方法(@PreDestroy、DisposableBean接口)。依赖注入、配置管理、组件扩展和切面编程是其常见应用场景。示例代码展示了如何通过实现BeanNameAware、BeanFactoryAware等接口以及使用@PostConstruct注解来控制Bean的初始化。
48 2
SpringBoot中bean的生命周期
|
1天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的民宿预订系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的民宿预订系统的详细设计和实现(源码+lw+部署文档+讲解等)
41 17