Spring两大核心为IOC(控制反转)和AOP(依赖注入)
浅谈IOC的理解
IOC控制反转,原来时我们需要自己创建对象。有了Spring后我们将整个对象交给Spring管理,当我们使用时直接调用即可
DI依赖注入,Spring 通过set或者有参构造的方式为我们创建对象时,自动将对象中的属性所需要的值注入进去的过程叫做依赖注入
容器:储存对象,使用的map结构来储存,在spring中一般存在三级缓存,singletonObjects存放完整的bean。
整个bean的生命周期,从创建到销毁都是容器为我们管理的。
浅谈AOP的理解
AOP面向切面编程思想,在面向对象OOP的思想中,将模块纵向抽取成一个个对象,而面向切面编程思想,将相似功能的模块进行横向的抽取成一个切面。通常用于权限控制、事务管理、日志记录等公共操作的过程叫做面向切面编程思想,这种思想提高了代码的复用性降低了耦合性,提高了可扩展性可维护性。SpringAOP是基于动态代理来实现的,如果这个类实现了某个接口就使用jdk的动态代理去创建代理对象,如果没有实现某个接口就使用CGlib代理去创建一个被代理对象的子类作为代理。
扩展:在bean的创建过程中有一个步骤可以对bean进行扩展,AOP本身就是一个扩展功能,所以在beanPostProcesser后置处理方法来进行实现
Bean的生命周期
1、通过xml文件或者注解的方式配置bean的定义信息
2、通过BeanDefinitionRader来读取bean的定义信息
3、将BeanDefinition(bean的定义信息)给Spring容器
4、执行beanFactoryPostProcessor(处理器)
5、通过beanFactory(反射)来实例化bean
--------------以下属于bean的初始化------------
6、通过set方法给bean的属性填充
7、调用一些away接口的方法(away接口有beanNameAway、beanClassLoaderAway(类加载器)、beanFactoryAway等接口)
8、执行前置处理器beanPostProcessor(before)
9、调用init方法
10、执行后置处理器beanPostProcessor(after)
-------------bean的初始化结束
11、得到完整的bean对象可以直接调用
12、销毁bean
浅谈循环依赖问题
下图是循环依赖的过程图
循环依赖就是定义定义两个对象;A对象中有一个属性为B对象,B对象中有一个属性A。当Spring容器创建A对象时先实例化A之后初始化,在初始化给属性赋值时需要B对象,之后创建B对象但是B对象在初始化给属性赋值时需要A对象。这样就造成循环依赖
循环依赖的问题怎么解决?
1、给对象的属性赋值有两种方式
1、构造器的方式 (不能解决循环依赖的问题)
2、set方式 (用三级缓存来解决循环依赖的问题)
2、三级缓存分别储存的什么?
一级成品的对象
二级半成品对象
三级缓lambda
3、如果只用一级缓存可以吗?
不可以,不能将半成品对象和成品对象放在一起,当获取对象的时候可能会获取到半成品的对象,这样的对象是不能用的。
4、如果只用二级缓存可以吗?
只有二级缓存也可以解决循环依赖的问题
但是添加AOP的实现之后会报错(错:没有最终版本的bean)
5、三级缓存到底做了什么事?
三级缓存的lembda表达式中可能会代理对象替换非代理对象。如果没有三级缓存,那么二级缓存中会有同一个名字的代理对象和非代理对象,调用bean时无法确定调用的是哪一个对象。在Spring容器中的bean都是单例的,在任何中都要保证容器中只有一个对象供外部调用,所以三级缓存完成了代理对象替换非代理对象的工作,最终返回唯一的对象。
三级缓存为了解决AOP代理过程中产生循环依赖的问题,如果没有AOP二级缓存完全能解决循环依赖的问题