没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
试读
43页
本文深入探讨了Spring框架中IoC容器的源码机制,涵盖了容器的初始化、Bean工厂的实例化、Bean定义的读取及Spring Bean的生命周期管理。通过精细的分析,本文揭示了AnnotationConfigApplicationContext的实例化过程,详细解读了DefaultListableBeanFactory的作用及其在Bean生产和获取中的关键性作用。同时,本文对Spring Bean的生命周期进行了深入剖析,从创建、依赖注入到销毁的每个阶段都进行了详尽的讲解。透过这些分析,本文不仅为Java开发者提供了对Spring IoC更深层次的理解,也为高效利用Spring框架提供了实践指导。适合拥有一定Spring框架基础的开发者阅读,特别是那些希望深入理解框架内部工作原理的高级开发人员。
资源推荐
资源详情
资源评论
Spring-IoC源码
Spring-IoC源码
前言
SpringIoC容器的加载过程
1.实例化化容器:AnnotationConfigApplicationContext:
2.实例化工厂:DefaultListableBeanFactory
3.实例化建BeanDefinition读取器:AnnotatedBeanDefinitionReader:
4.创建BeanDefinition扫描器:ClassPathBeanDefinitionScanner
5.注册配置类为BeanDefinition:register(annotatedClasses);
6.refresh()
6.5-invokeBeanFactoryPostProcessors(beanFactory)
6-11-finishBeanFactoryInitialization(beanFactory);
SpringBean的生命周期
前言
Spring最重要的概念是IOC和AOP,其中IOC又是Spring中的根基:
本文要说的IOC总体来说有两处地方最重要,一个是创建Bean容器,一个是初始化Bean。为了保持文章的严谨性,如果同学们发现文
章有误请一定不吝指出。
Demo:
配置类MainConfig.java:
1 /**
2 *Createdbyxslson2019/8/15.
3 */
4 @Configuration
5 @ComponentScan(basePackages={"com.tuling.iocbeanlifecicle"})
6 publicclassMainConfig{
7
8 }
BeanCar.java:
1
2 @Component
3 publicclassCar{
4
5
6 privateStringname;
7 @Autowired
8 privateTanktank;
9
10 publicvoidsetTank(Tanktank){
11 this.tank=tank;
12 }
13
14 publicTankgetTank(){
15 returntank;
16 }
17
18 publicStringgetName(){
19 returnname;
20 }
21
22
23 publicvoidsetName(Stringname){
24 this.name=name;
25 }
26
27
28 publicCar(){
29 System.out.println("car加载....");
30 }
31
32
33
34 }
BeanMainStart.java:
1 publicstaticvoidmain(String[]args){
2 //加载spring上下文
3 AnnotationConfigApplicationContextcontext=newAnnotationConfigApplicationContext(MainConfig.class);
4
5 Carcar=context.getBean("car",Car.class);
6 System.out.println(car.getName());
7 }
SpringIoC容器的加载过程
1.实例化化容器:AnnotationConfigApplicationContext:
从这里出发:
1 //加载spring上下文
2 AnnotationConfigApplicationContextcontext=newAnnotationConfigApplicationContext(MainConfig.class);
3
AnnotationConfigApplicationContext的结构关系:
创建AnnotationConfigApplicationContext对象
1 //根据参数类型可以知道,其实可以传入多个annotatedClasses,但是这种情况出现的比较少
2 publicAnnotationConfigApplicationContext(Class<?>...annotatedClasses){
3 //调用无参构造函数,会先调用父类GenericApplicationContext的构造函数
4 //父类的构造函数里面就是初始化DefaultListableBeanFactory,并且赋值给beanFactory
5 //本类的构造函数里面,初始化了一个读取器:AnnotatedBeanDefinitionReaderread,一个扫描器ClassPathBeanDefi
nitionScannerscanner
6 //scanner的用处不是很大,它仅仅是在我们外部手动调用.scan等方法才有用,常规方式是不会用到scanner对象的
7 this();
8 //把传入的类进行注册,这里有两个情况,
9 //传入传统的配置类
10 //传入bean(虽然一般没有人会这么做
11 //看到后面会知道spring把传统的带上@Configuration的配置类称之为FULL配置类,不带@Configuration的称之为Lite配
置类
12 //但是我们这里先把带上@Configuration的配置类称之为传统配置类,不带的称之为普通bean
13 register(annotatedClasses);
14 //刷新
15 refresh();
16 }
我们先来为构造方法做一个简单的说明:
1.这是一个有参的构造方法,可以接收多个配置类,不过一般情况下,只会传入一个配置类。
2.这个配置类有两种情况,一种是传统意义上的带上@Configuration注解的配置类,还有一种是没有
带上@Configuration,但是带有@Component,@Import,@ImportResouce,@Service,
@ComponentScan等注解的配置类,在Spring内部把前者称为Full配置类,把后者称之为Lite配置
类。在本源码分析中,有些地方也把Lite配置类称为普通Bean。
使用断点调试,通过this()调用此类无参的构造方法,代码到下面:
1 publicclassAnnotationConfigApplicationContextextendsGenericApplicationContextimplementsAnnotatio
nConfigRegistry{
2
3 //注解bean定义读取器,主要作用是用来读取被注解的了bean
4 privatefinalAnnotatedBeanDefinitionReaderreader;
5
6 //扫描器,它仅仅是在我们外部手动调用.scan等方法才有用,常规方式是不会用到scanner对象的
7 privatefinalClassPathBeanDefinitionScannerscanner;
8
9 /**
10 *CreateanewAnnotationConfigApplicationContextthatneedstobepopulated
11 *through{@link#register}callsandthenmanually{@linkplain#refreshrefreshed}.
12 */
13 publicAnnotationConfigApplicationContext(){
14 //会隐式调用父类的构造方法,初始化DefaultListableBeanFactory
15
16 //初始化一个Bean读取器
17 this.reader=newAnnotatedBeanDefinitionReader(this);
18
19 //初始化一个扫描器,它仅仅是在我们外部手动调用.scan等方法才有用,常规方式是不会用到scanner对象的
20 this.scanner=newClassPathBeanDefinitionScanner(this);
21 }
22 }
首先无参构造方法中就是对读取器reader和扫描器scanner进行了实例化,reader的类型是
AnnotatedBeanDefinitionReader,可以看出它是一个“打了注解的Bean定义读取器”,scanner的类型是
ClassPathBeanDefinitionScanner,它仅仅是在外面手动调用.scan方法,或者调用参数为String的构造方法,传
入需要扫描的包名才会用到,像这样方式传入的配置类是不会用到这个scanner对象的。
AnnotationConfigApplicationContext类是有继承关系的,会隐式调用父类的构造方法:
下面代码
2.实例化工厂:DefaultListableBeanFactory
1 publicclassGenericApplicationContextextendsAbstractApplicationContextimplementsBeanDefinitionReg
istry{
2
3 privatefinalDefaultListableBeanFactorybeanFactory;
4
5 @Nullable
6 privateResourceLoaderresourceLoader;
7
8 privatebooleancustomClassLoader=false;
9
10 privatefinalAtomicBooleanrefreshed=newAtomicBoolean();
11
12
13 /**
14 *CreateanewGenericApplicationContext.
15 *@see#registerBeanDefinition
16 *@see#refresh
17 */
18 publicGenericApplicationContext(){
19 this.beanFactory=newDefaultListableBeanFactory();
20 }
21 }
DefaultListableBeanFactory的关系图
DefaultListableBeanFactory是相当重要的,从字面意思就可以看出它是一个Bean的工厂,什么是Bean的工厂?当然就是用来生产
和获得Bean的。
3.实例化建BeanDefinition读取器:AnnotatedBeanDefinitionReader:
其主要做了2件事情
1.注册内置BeanPostProcessor
2.注册相关的BeanDefinition
让我们把目光回到AnnotationConfigApplicationContext的无参构造方法,让我们看看Spring在初始化
AnnotatedBeanDefinitionReader的时候做了什么:
1 publicAnnotatedBeanDefinitionReader(BeanDefinitionRegistryregistry){
2 this(registry,getOrCreateEnvironment(registry));
3 }
这里的BeanDefinitionRegistry当然就是AnnotationConfigApplicationContext的实例了,这里又直接调
用了此类其他的构造方法:
1 publicAnnotatedBeanDefinitionReader(BeanDefinitionRegistryregistry,Environmentenvironment){
2 Assert.notNull(registry,"BeanDefinitionRegistrymustnotbenull");
3 Assert.notNull(environment,"Environmentmustnotbenull");
4 this.registry=registry;
5 this.conditionEvaluator=newConditionEvaluator(registry,environment,null);
6 AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
剩余42页未读,继续阅读
资源评论
光芒软件工匠
- 粉丝: 789
- 资源: 64
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功