三分钟深入了解Spring底层

Pivotal中国研发中心, EMC,VMware和 通用电气 (GE)的联合投资
 
说说你对spring的了解,是IOC、AOP吗?
spring中有很多项目,IOC-AOP是spring framework中的核心技术的一部分
一个springbean一定是一个对象
spring bean---object
经过一个完整的生命周期
bean的生命周期:
    先明确两个概念spring bean和对象
1、spring bean ——受spring容器管理的对象,可能经过了完整的spring bean生命周期(为什么是可能?难道还有bean是没有经过bean生命周期的?答案是有的,具体我们后面文章分析),最终存在spring容器当中;一个bean一定是个对象
2、对象 ——任何符合java语法规则实例化出来的对象,但是一个对象并不一定是spring bean;
 
所谓的bean的生命周期就是磁盘上的类通过spring扫描,然后实例化,跟着初始化,继而放到容器当中的过程;
 
spring容器初始化bean的大概过程
1:实例化一个ApplicationContext的对象;
2:调用bean工厂后置处理器完成扫描;
3:循环解析扫描出来的类信息;
4:实例化一个BeanDefinition对象来存储解析出来的信息;
5:把实例化好的beanDefinition对象put到 beanDefinitionMap 当中缓存起来,以便后面实例化bean;
6:再次调用bean工厂后置处理器;
7:当然spring还会干很多事情,比如国际化,比如注册BeanPostProcessor等等,如果我们只关心如何实例化一个bean的话那么这一步就是spring调用 finishBeanFactoryInitialization 方法来实例化单例的bean,实例化之前spring要做验证,需要遍历所有扫描出来的类,依次判断这个bean是否Lazy,是否prototype,是否abstract等等;
8:如果验证完成spring在实例化一个bean之前需要推断构造方法,因为spring实例化对象是通过构造方法反射,故而需要知道用哪个构造方法;
9:推断完构造方法之后spring调用构造方法反射实例化一个 对象 ;注意我这里说的是对象、对象、对象;这个时候对象已经实例化出来了,但是并不是一个完整的bean,最简单的体现是这个时候实例化出来的对象属性是没有注入,所以不是一个完整的bean;
10:spring处理合并后的beanDefinition(合并?是spring当中非常重要的一块内容,后面的文章我会分析);
11:判断是否支持循环依赖,如果支持则提前把一个工厂存入singletonFactories——map;
12:判断是否需要完成属性注入
13:如果需要完成属性注入,则开始注入属性
14:判断bean的类型回调Aware接口
15:调用生命周期回调方法
16:如果需要代理则完成代理
17:put到单例池——bean完成——存在spring容器当中
 
 
 
什么是spring容器?是一个非常抽象的概念
 spring的各个组件组合在一起称为spring容器,比如spring单例池、springBean工厂、spring扫描器、spring读取器、spring后置处理器
 
spring后置处理器:
spring IOC的源码分析
 
xml based \  java based (主流)  \Annotation
不仅仅            
 
spring5的源码是用gradle构建的
 
需要导入的依赖
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>

因为有些依赖maven已经帮我们导入了

 
springbean的生命周期===spring如何把一个bean产生的和把一个bean销毁的
 
初始化spring上下文  容器 环境 一摸一样
public class Test {
    public static void main(String[] args) {
//基于XML
//        ClassPathXMLApplicationContext
//            classPathXMLApplicationContext = new ClassPathXMLApplicationContext("spring.xml");
        AnnotationConfigApplicationContext

//基于Java
                annotationConfigApplicationContext
                =new AnnotationConfigApplicationContext(Appconfig.class);
        System.out.println(annotationConfigApplicationContext.getBean(Test.class));
    }

}

解析上面代码:会先调用ClassPathXMLApplicationContext的构造方法,此时会调用父类的构造方法(无参)this.beanFactory = new DefaultListableBeanFactory();(能够产生bean的)

spring容器当中存在一个工厂--生产bean的
那什么是bean?---代码级别就是DefaultListableBeanFactory
DefaultListableBeanFactory---原料beanDefinitMap(最重要)
大体: annotationConfigApplicationContext
                =new AnnotationConfigApplicationContext(Appconfig.class);它会解析
Appconfig类,该类扫描,扫描到很多类之后进行for循环,它会把这个类的信息:名字、作用域、需不需要懒加载,把这些封装到 genericBeanDefinition对象中,然后把这个对象put到map中。然后遍历map,初始化对象genericBeanDefinition.getBeanClass().newInstance()
首先把类文件加载到jvm
  1. spring容器启动,通过bean工厂的后置处理器( ConfigurationClassPostProcessor)完成扫描(读取类的信息)。---读取到的类信息会放到BeanDefinition类中,原因:实例化一个bean除了.class文件中的信息还要具备 scope,lazy,dependsOn等等信息需要存储
  2. 实例化一个BeanDefinition的对象,调用各种set方法存储信息。每扫描到一个符合规则的类,spring都会实例化一个BeanDefinition对象,然后根据类的类名生成一个bean的名字,当然你可以提供自己的名字生成器覆盖spring内置的规则
  3. 然后spring会把这个beanDefinition对象和生成的beanName放到一个map当中,key=beanName,value=beanDefinition对象
  4. BeanFactoryPostProcessor在容器实例化任何其他bean之前读取配置元数据,并可以根据需要进行修改,例如:可以把bean的scope从singleton改为prototype。
spring产生一个be'an跟类产生的beanDefinition对象有关系,跟类没有关系
 
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {}
 
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {}
 
public GenericApplicationContext() {
    this.customClassLoader = false;
    this.refreshed = new AtomicBoolean();
    this.beanFactory = new DefaultListableBeanFactory();
}
this.beanFactory 说明spring包含一个工厂,它的这个工厂具体就是new DefaultListableBeanFactory()  ----beanDefinitMap(相当于原料)
正常情况:遍历map,new?反射?序列化?克隆?都不是
new出来放到spring单例池中
非正常情况:代码级别:所有继承ApplicationContext类的都是容器
 
spring产生一个bean跟map中beanDefinite对象有关系,跟这个类没有关系
AnnotationConfigApplicationContext ac =new AnnotationConfigApplicationContext(Appconfig.class);
 
扫描包下面的类
当类过多的时候,他会进行for循环
 
refresh() 
 
类变成beanDefinition,放到map中
上述这一步怎么做的,如下
map中的对象实例化到单例池中
 
FactoryBean  BeanFactory区别
 
FactoryBean 普通Bean 区别:普通Bean会放到单例池中
 
循环依赖---spring如何解决循环依赖的--两次getSingleton
 
Sring后置处理器---生命周期
 
 
 
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值