spring源码分析-spring中的bean

接触过spring的人都知道,在spring中我们称java对象为bean,我们在spring的debug日志或者报错日志也能看到各种bean的描述。其实,spring的bean和java的对象之间是有区别的,很难简单的描述他们的关系,可以说一样,也可以说是不一样的。下面我们就来扯一扯

  • java对象

在说java对象前我们先来看一幅图

 

 

 稍微熟悉java的同学肯定一看就明白,这么简单!不错是很简单,我们每天就在干这样的事情,但是我们如果要往深里看其实还是很复杂的过程:

  1. 我们在IDE里面编辑好我们的java类-xxx.java
  2. 编译xxx。java->xxx.class,这里面涉及到编译原理的内容
  3. 编译完的xxx.class文件在java 虚拟机方法区创建Class类的实例
  4. 当我们new一个对象的时候,根据方法区中的Class实例创建xxx类的实例对象

至此,我们完成了类xxx的一个对象的创建,在这过程中,会经历java类的加载过程,java对象的创建过程等系列步骤。这个过程很复杂,这里不展开,有机会会单独讲述。

  • spring bean

在spring中,我们实例化一个bean的过程就复杂很多,我们先来看幅简图

 

 

 

 

 

 有没有发现和上面的图差不多,就是多了几个步骤。确实哈哈,其实spring实例化bean的远比这个复杂,我们先熟悉一下大致过程,具体的过程后面文章再详细讨论。

我们以注解为例,spring中的bean是扫描我们的注解类,然后进行实例化,并将实例化后的对象放到spring容器中。注意这句话,其中扫描、实例化、放进容器,这几个都是关键词。后面文件会一一讲述。我们现在讨论的是实例化,我们可以这么想象,在spring中对扫描到的所有类,是否立即实例化并放到容器中?大家可以想一想。................5秒钟过去了,我就不卖关子了,其实是不能立即放到容器中的,如果队spring做过扩展的同学可能会对各种后置处理器有印象,实现了BeanFactoryPostProcessor和BeanPostProcessor的各种类,这些后置处理器是能动态的改变对象的所有信息,没错,是所有信息。也就是说spring中的bean是在java对象的基础上做了很多spring的处理,简单来说一句话:spring中的bean一定是一个java对象,但是java对象不一定是spring的bean。可能这个不是很严谨,大家姑且这么听着,只要能理解两者之间的关系就行。

  • BeanDefinition

上文描述了java读写和spring bean的区别,我们知道了spring中一个bean所经历的过程要比java对象长且复杂很多,我们来看一个栗子:

 

 

 

 

 

 

 

 

 我们提供了2个类:A和B,都是空类,啥也没干。但是A类上面有Component注解,B类没有我们跑下下面的程序

 

 

 

顺理成章结果打印了A类的bean描述。但是我现在类做一个改变,新增一个类

 

 

 我们再来看结果:

 

 

 我靠,怎么打印了B的描述,而报A不存在???我明明是在A上加了注解,B类上什么都没干,它仅仅是个java普通类。仔细看我新增的那个类,聪明的你可能会发现一点端倪,尽管可能不大明白,没关系,后面会讲。

通过这个栗子我们可以得出2个结论:

  1. 证明了上面的观点,spring的bean是可以被改变的,它不是简单的java创建对象。
  2. spring中能做到这样,应该是借助了什么中间力量来实现的,就好比本栗子中的代码中我们发现一个对象:BeanDefinition。没错,我们说了这么多就是想引出这个哈哈,她至关重要,可以这么说,在spring中,没有她你就很难做到spring容器托管对象。

至此我们知道了一个普通java对象和spring bean的关系,我们也知道了spring中bean是有生命周期的,同时发现spring中有个神秘的BeanDefinition存在。至于它是用来干什么的现在还不知道,不过没关系,下篇文章就讲BeanDefinition,敬请期待。

PS:上面都是基于spring中的单例模式(singletom)讲述的,原型的会不一样,不过在实际工作中,谁用过原型呢?很少。

 

posted @ 2019-11-13 15:09  蓝了个枫  阅读(399)  评论(0编辑  收藏  举报