初学者必看的SpringBoo自动装配原理1

前言学习springboot,绝对避不开自动装配这个概念,这也是springboot的关键之一
本人也是springboot的初学者,下面的一些总结都是结合个人理解和实践得出的,如果有错误或者疏漏,请一定一定一定(不是欢迎,是一定)帮我指出,在评论区回复即可,一起学习!
篇幅较长分四篇了,希望你可以有耐心.
如果只关心springboot装配过程,可以直接跳到第7部分
想要理解spring自动装配,需要明确两个含义:
装配,装配什么?自动,怎么自动?1. warm up在开始之前,让我们先来看点简单的开胃菜:spring中bean注入的三种形式
首先我们先来一个person类,这里为了篇幅长度考虑使用了lombok
如果你不知道lombok是什么,那就最好不要知道,加了几个注解之后我的pojo类person就完成了
/** * @author dzzhyk */@data@noargsconstructor@allargsconstructorpublic class person { private string name; private integer age; private boolean sex;}在spring中(不是spring boot),要实现bean的注入,我们有3种注入方式:
1.1 setter注入这是最基本的注入方式
首先我们创建applicationcontext.xml文件,在里面加入:
这里使用property为bean对象赋值
紧接着我们会在test包下写一个version1.testversion1类
/** * 第一种bean注入实现方式 - 在xml文件中直接配置属性 */public class testversion1 { @test public void test(){ applicationcontext ca = new classpathxmlapplicationcontext(applicationcontext.xml); person person = ca.getbean(person, person.class); system.out.println(person); }}这里我使用了classpathxmlapplicationcontext来加载spring配置文件并且读取其中定义的bean,然后使用getbean方法使用id和类来获取这个person的bean对象,结果成功输出:
person(name=dzzhyk, age=20, sex=true)1.2 构造器注入接下来是使用构造器注入,我们需要更改applicationcontext.xml文件中的property为construct-arg
version2.testversion2内容不变:
public class testversion2 { @test public void test(){ applicationcontext ca = new classpathxmlapplicationcontext(applicationcontext.xml); person person = ca.getbean(person, person.class); system.out.println(person); }}依然正常输出结果:
person(name=dzzhyk, age=20, sex=true)1.3 属性注入使用注解方式的属性注入bean是比较优雅的做法
首先我们需要在applicationcontext.xml中开启注解支持和自动包扫描:
在pojo类中对person类加上@component注解,将其标记为组件,并且使用@value注解为各属性赋初值
@componentpublic class person { @value(dzzhyk) private string name; @value(20) private integer age; @value(true) private boolean sex;}然后添加新的测试类version3.testversion3
public class testversion3 { @test public void test(){ applicationcontext ac = new classpathxmlapplicationcontext(applicationcontext.xml); person person = ac.getbean(person, person.class); system.out.println(person); }}运行也可以得到如下结果:
person(name=dzzhyk, age=20, sex=true)2. warm up again什么?还有什么?接下来我们来聊聊spring的两种配置方式:基于xml的配置和基于javaconfig类的配置方式,这对于理解springboot的自动装配原理是非常重要的。
首先我们在person的基础上再创建几个pojo类:这个person有car、有dog
public class car { private string brand; private integer price;}public class dog { private string name; private integer age;}public class person { private string name; private integer age; private boolean sex; private dog dog; private car car;}2.1 基于xml的配置接下来让我们尝试使用xml的配置方式来为一个person注入
然后跟普通的bean注入一样,使用classpathxmlapplicationcontext来加载配置文件,然后获取bean
/** * 使用xml配置 */public class testversion1 { @test public void test(){ classpathxmlapplicationcontext ca = new classpathxmlapplicationcontext(applicationcontext.xml); person person = ca.getbean(person, person.class); system.out.println(person); }}输出结果如下:
person(name=dzzhyk, age=20, sex=true, dog=dog(name=旺财, age=5), car=car(brand=奥迪双钻, price=100000))2.2 基于javaconfig类的配置想要成为javaconfig类,需要使用@configuration注解
我们新建一个包命名为config,在config中新增一个personconfig类
@configuration@componentscanpublic class personconfig { @bean public person person(dog dog, car car){ return new person(dzzhyk, 20, true, dog, car); } @bean public dog dog(){ return new dog(旺财, 5); } @bean public car car(){ return new car(奥迪双钻, 100000); }}此时我们的xml配置文件可以完全为空了,此时应该使用annotationconfigapplicationcontext来获取注解配置
/** * 使用javaconfig配置 */public class testversion2 { @test public void test(){ annotationconfigapplicationcontext ac = new annotationconfigapplicationcontext(personconfig.class); person person = ac.getbean(person, person.class); system.out.println(person); }}仍然正常输出了结果:
person(name=dzzhyk, age=20, sex=true, dog=dog(name=旺财, age=5), car=car(brand=奥迪双钻, price=100000))3. beandefinitionabstractbeandefinition是spring中所有bean的抽象定义对象,我把他叫做bean定义
当bean.class被jvm类加载到内存中时,会被spring扫描到一个map容器中:
beandefinitionmap这个容器存储了bean定义,但是bean此时还没有进行实例化,在进行实例化之前,还有一个
beanfactorypostprocessor可以对bean对象进行一些自定义处理
我们打开beanfactoryprocessor这个接口的源码可以发现如下内容:
/** modify the application context's internal bean factory after its standard* initialization. all bean definitions will have been loaded, but no beans* will have been instantiated yet. this allows for overriding or adding* properties even to eager-initializing beans.*/在spring完成标准的初始化过程后,实现beanfactorypostprocessor接口的对象可以用于定制bean factory,所有的bean definition都会被加载,但是此时还没有被实例化。这个接口允许对一些bean定义做出属性上的改动。
简言之就是实现了beanfactorypostprocessor这个接口的类,可以在bean实例化之前完成一些对bean的改动。
大致流程我画了个图:
至此我们能总结出springioc容器的本质:(我的理解)
由beandefinitionmap、beanfactorypostprocessor、beanpostprocessor、beanmap等等容器共同组成、共同完成、提供依赖注入和控制反转功能的一组集合,叫ioc容器。

PCB布线的基础知识
微分方程的算子形式和拉普拉斯变换式之间的是什么关系?
遥控器代换表
数据中心集群化,将迎来新一轮投资高峰
啤酒洗瓶机轴径磨损的修复方法
初学者必看的SpringBoo自动装配原理1
比特币有什么问题存在
TVS瞬态抑制二极体于快速成长的汽车及5G通讯应用
三层交换机与路由器的主要区别
轮廓仪与粗糙度仪的相同点和不同点
台积电将在6月8日召开2021年度股东大会
iOS 14出现问题:第三方应用更新后,苹果将偷偷地更换自家APP
助力现代化产业体系建设!三安出席2023中国汽车论坛
供应安捷伦8562EC频谱分析仪13.2GHz
IEEE限制华为事件发酵,北大教授申请退出IEEE学术期刊编委会
TOP267EG直插ESIP-7液晶电视机开关电源驱动IC芯片
亚信安全针对整个5G核心网络提出了5Guard理念
HMD Global正在努力打造一个新的旗舰店
内存报警怎么办
DIYRaspberry Pi无人机第二部分–Naza-M Lite指南