面试官:聊一聊Spring实例化Bean都有哪些方式?

createh52个月前 (01-11)技术教程25

Spring功能简介

我们都知道Spring是一个ioc容器,它主要给我们提供ioc,aop以及依赖注入功能,通过spring我们在应用中并不需要了解对象如何创建,这个都交给spring容器去管理。通过简单的声明式配置就可完成对象的装配,可以简单的理解成Spring内部就是一个很大的Map,里面存储了很多实例化好的java对象,我们需要的时候制需要getBean 或者通过属性,setter,构造器,接口 等自动注入方式直接依赖其他的Bean。Spring容器表面看起来非常的简单,但是它内部实际上是一个非常复杂的过程,Spring的源码非常的庞大,分支和接口也非常多,本节不说源码,只是简单的和大家分享Spring的核心流程和Bean创建的几种方式。看完后你一定对Spring创建Bean的过程有更深的理解。

Spring容器bean创建流程

spring容器创建Bean的过程非常复杂,这里我通过一个图简单的把Bean创建的核心流程画出来,有助于大家可用进一步了解Bean创建的过程。

上图可用看到,Spring创建bean主要经过四个流程

  1. 资源定位 ,可从xml配置文件,java注解,java配置类等各种入口加载bean的来源
  2. 加载解析,将各种入口资源解析成BeanDefinition
  3. 注册,将第二步解析出来的各种BeanDefinition注册到BeanDefinition容器中等待实例化
  4. 实例化,将BeanDefinition容器中的BeanDefinition实例化成最终的Bean对象

其中在BeanDefinition到Bean的过程中需要经过BeanFactoryPostProcessor前置处理器,在Bean实例化前可以对BeanDefinition进行修改,创建Bean后会通过BeanPostProcessor后置处理器对Bean进行修改或者进一步包装。很多优秀的框架都是基于前置和后置处理器对Spring做二次扩展,实现了很多强大的功能,特别是SpringBoot在这方面更是突出的代表。

Bean的创建方式

通过上面对Bean创建流程的分析后,大概就清楚在具体应用中我们到底有那些方式可用创建Bean了,实际应用中主要可用通过以下几个方式创建Bean.

  1. 通过注解扫描方式

我们常见的 @Component,@Service,@Controller,@Configuration 这几个注解都被Spring扫描到并自动注入到容器,其中后面三个其实就是@Component,只不过从名字上区分不同类别而已。

  1. 其次用@import导入配置类,这种配置方式就是直接导入一个类进行配置,比如我们非常熟悉的 @EnableAsync,@EnableScheduling 这两个注解内部就是通过@import导入的。
  2. 直接使用BeanDefinitionRegistry接口,通过编程的方式自定义BeanDefinition后注入到容器。

总结

注解扫描的方式多用于本项目默认扫描的包路径,比如@SpringBootApplication注解所在的包路径下才能被扫描到。

@import用于导入不在默认扫描路径下的配置类,比如一些外部的第三方包

前面两种都是通过声明式方式配置Bean,这两种方式都在容器启动后Bean初始化完成了。通过BeanDefinitionRegistry接口可以动态的创建Bean,比如在运行的过程中创建Bean并交给Spring托管,这种方式最灵活。比如我们可以根据配置文件动态的创建多个数据源,也可以在各种数据源管理应用运行的过程中再创建数据源,其实Spring底层最终都是通过这个接口注册BeanDefinition的。

相关文章

Java 8:一文掌握 Lambda 表达式 | CSDN 博文精选

作者 | Android 大强哥责编 | 郭芮出品 | CSDN 博客本文将介绍 Java 8 新增的 Lambda 表达式,包括 Lambda 表达式的常见用法以及方法引用的用法,并对 Lambda...

spring阅读--容器及实例化

鲁班学院:戴明智(D55)从今天开始,我们一起过一遍Spring的官网,一边读,一边结合在课堂上学习的知识,讲一讲自己的理解。不管是之前关于动态代理的文章,还是读Spring的官网,都是为了之后对Sp...

长篇图解java反射机制及其应用场景

一、什么是java反射?在java的面向对象编程过程中,通常我们需要先知道一个Class类,然后new 类名()方式来获取该类的对象。也就是说我们需要在写代码的时候(编译期或者编译期之前)就知道我们要...

详解面试中常考的 Java 反射机制

反射(Reflection) 是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说“自审”,并能直接操作程序的内部属性和方法。反射是一项高级开发人员应该掌握的“黑...

你见过哪些实用到爆的 Java 代码技巧?

专注于Java领域优质技术,欢迎关注作者:java小瓜哥导语自从毕业后,今年已经是我工作的第 8 个年头了,我甚至都快忘记了到底是那年毕业的。从出来本人一直在做 Java 相关的工作,现在终于有时间坐...

彻夜怒肝!熬夜整理13个Java基础实例,程序员的辛苦钱建议不要赚

今日分享开始啦,请大家多多指教~Java代码实现是比较基础的内容,今天给大家介绍几个题目训练,自己可以动手操作实现一下哦!一、根据年龄数值输出年龄段题目内容:根据年龄, 来打印出当前年龄的人是少年(低...