说说你对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
-
spring容器启动,通过bean工厂的后置处理器( ConfigurationClassPostProcessor)完成扫描(读取类的信息)。---读取到的类信息会放到BeanDefinition类中,原因:实例化一个bean除了.class文件中的信息还要具备 scope,lazy,dependsOn等等信息需要存储
-
实例化一个BeanDefinition的对象,调用各种set方法存储信息。每扫描到一个符合规则的类,spring都会实例化一个BeanDefinition对象,然后根据类的类名生成一个bean的名字,当然你可以提供自己的名字生成器覆盖spring内置的规则
-
然后spring会把这个beanDefinition对象和生成的beanName放到一个map当中,key=beanName,value=beanDefinition对象
-
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后置处理器---生命周期