0.spring官网文档阅读:https://blog.csdn.net/qq_41907991/article/details/105502255

https://www.cnblogs.com/zrtqsk/p/3735273.html
1.生命周期流程图:


2.ApplicationContext实例化bean的过程源码详解:
优秀源码分析:https://www.cnblogs.com/leeSmall/p/10188408.html

2.spring bean循环依赖:
1.beanfactory中getBean()时的创建实例流程:

1.哪三级缓存?
1./** singletonObjects:存放初始化好的bean,可以直接使用的bean*/
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);
2./**二级缓存:经过一级缓存处理后的实例化bean,是singletonFactory 制造出来的 singleton 的缓存。*/
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
3./**一级缓存:存放刚实例化的bean(尚未初始化),这部分缓存的bean可以通过实现SmartInstantiationAwareBeanPostProcessor接口的getEarlyBeanReference方法进行拓展,拓展时机为在将刚实例化*/
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
2.如何解决循环依赖?原文链接:https://blog.csdn.net/weixin_42228338/article/details/97163101
以 BeanA 和 BeanB 两个类相互依赖为例
1.创建原始 bean 对象:
1.假设 beanA 先被创建,创建后的原始对象为 BeanA@1234,上面代码中的 bean 变量指向就是这个对象。
instanceWrapper = createBeanInstance(beanName, mbd, args);
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
2.暴露早期引用:
1.beanA 指向的原始对象创建好后,就开始把指向原始对象的引用通过 ObjectFactory 暴露出去。getEarlyBeanReference 方法的第三个参数 bean 指向的正是 createBeanInstance 方法创建出原始 bean 对象 BeanA@1234。
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
3.解析依赖:
1.populateBean 用于向 beanA 这个原始对象中填充属性,当它检测到 beanA 依赖于 beanB 时,会首先去实例化 beanB。beanB 在此方法处也会解析自己的依赖,当它检测到 beanA 这个依赖,于是调用 BeanFactroy.getBean("beanA") 这个方法,从容器中获取 beanA。
populateBean(beanName, mbd, instanceWrapper);
4.获取早期引用:
1.populateBean 调用 BeanFactroy.getBean("beanA") 以获取 beanB 的依赖。getBean("beanA") 会先调用 getSingleton("beanA"),尝试从缓存中获取 beanA。此时由于 beanA 还没完全实例化好,于是 this.singletonObjects.get("beanA") 返回 null。
2.接着 this.earlySingletonObjects.get("beanA") 也返回空,因为 beanA 早期引用还没放入到这个缓存中。
3.最后调用 singletonFactory.getObject() 返回 singletonObject,此时 singletonObject != null。singletonObject 指向 BeanA@1234,也就是 createBeanInstance 创建的原始对象。
4.此时 beanB 获取到了这个原始对象的引用,beanB 就能顺利完成实例化。beanB 完成实例化后,beanA 就能获取到 beanB 所指向的实例,beanA 随之也完成了实例化工作。
5.由于 beanB.beanA 和 beanA 指向的是同一个对象 BeanA@1234,所以 beanB 中的 beanA 此时也处于可用状态了。

5.流程图来对这个过程进行讲解:

3.为何使用三级缓存而非二级?
原文链接:https://my.oschina.net/u/4340310/blog/4332450
以下是个人对三级缓存意义的理解
1.一级缓存就是普通的ioc的容器。
2.二级缓存是为了解决循环依赖。
3.三级缓存是spring提供给开发者一个拓展的入口(比如AOP)
4.一级缓存行不行?二级缓存行不行?为什么要三级缓存?
优秀原文链接:https://www.cnblogs.com/youzhibing/archive/2021/02/07/14337244.html
1.一级缓存,可以解决循环依赖,但是要区分成品和半成品,比较复杂。
2.二级缓存,可以解决循环依赖,但是处理AOP代理对象时,若将半成品代理对象和成品代理对象放在一级缓存,同样会比较复杂;若将A依赖B,B创建时无法提前创建A的代理对象。
3.三级缓存为了解决aop代理对象,三级缓存提供提前创建代理对象的方法,二级缓存缓半成品A的代理对象,B初始化完成,A接着初始化完成,A对象由半成品转为成品,代理对象从二级缓存移到一级缓存。
2.代码入口:
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(String)
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(String, Class<T>, Object[], boolean)
3.扩展详细讲解:
1. InstantiationAwareBeanPostProcessor 可以在 Bean 实例创建前、后进行增强处理
2.如果你想在bean实例创建前后进行处理可以继承InstantiationAwareBeanPostProcessor的子类InstantiationAwareBeanPostProcessorAdaper,然后覆写里面你需要实现的方法,创建前处理就实现创建前处理的方法。
3.扩展点实战应用:
1.扩展点:https://zhuanlan.zhihu.com/p/363941714

2.扩展点原理和实际应用:
深入理解Spring 之 Spring 进阶开发必知必会 之 Spring 扩展接口
https://www.jianshu.com/p/685ced8abe92
1.FactroyBean 我们熟悉的AOP基础bean
2.BeanPostProcess 在每个bena初始化成前后做操作。
3.InstantiationAwareBeanPostProcessor 在Bean实例化前后做一些操作。
4.BeanNameAware、ApplicationContextAware 和 BeanFactoryAware 针对bean工厂,可以获取上下文,可以获取当前bena的id。
5.BeanFactoryPostProcessor Spring允许在Bean创建之前,读取Bean的元属性,并根据自己的需求对元属性进行改变,比如将Bean的scope从singleton改变为prototype。
6.InitialingBean 在属性设置完毕后做一些自定义操作 DisposableBean 在关闭容器前做一些操作。
7总结:
我们了解了 Spring 留给我们的扩展接口,以提高我们使用 Spring 的水平,
在以后的业务中,也就可以基于 Spring 做一些除了简单的注入这种基本功能之外的功能。
同时,我们也发现,Spring 的扩展性非常的高,符合设计模式中的开闭原则,对修改关闭,对扩展开放,
实现这些的基础就是 Spring 的 IOC,IOC 可以说是 Spring 的核心, 在 IOC 的过程中,对预定义的接口做了很多的预留工作。
这让其他框架与 Spring 的组合变得更加的简单,我们在以后的开发工作中也可以借鉴 Spring 的思想,让程序更加的优美。
链接:https://www.jianshu.com/p/685ced8abe92
3.核心类:
1.核心类:

2.学会IOC容器这里使用的设计模式
1.模板方法设计模式、观察者模式(主要是这两个)、策略模式、工厂模式
2.搞清楚不同创建方式的bean的创建过程
3.完整代码获取地址:https://github.com/leeSmall/FrameSourceCodeStudy/tree/master/spring-source-study
4.spring AOP
1.spring 生成AOP的代理对象。实现基于jdk动态代理,cglib代理。本质是通过Java反射实现。
2.FactoryBean&BeanFactory&ObjectFactory
这三个接口都为Springframework的核心接口,
1.BeanFactory本身就是一个bean的工厂,同时也是我们的IOC容器,
2.而FactoryBean是一个特殊的Bean,这里面有三个方法,分别为:getObject,getObjectType,isSingleton。根据文档解释,它只是一个生产对象的工厂,被Spring管理 。
3.这个工厂负责提供我们需要的对象。当需要特殊的方式创建Bean时,则考虑实现该接口。
3.ProxyFactoryBean是生成目标对象代理的核心

4.ProxyConfig:该类定义代理类最基本的代理配置
5.Advised:通知接口,该接口没有方法定义,其常见的子接口有BeforeAdvise,AfterAdvise,MethodInterceptor等
6.PointCut:切点接口,Pointcut由ClassFilter和MethodMatcher构成。它通过ClassFilter定位到某些特定类上,通过MethodMatcher定位到某些特定方法上,这样Pointcut就拥有了描述某些类的某些特定方法的能力。
7.基于AOP的核心类与接口实现代理
1、先定义基本的JavaBean:
2、自定义注解
3、定义JavaBean的代理
4、主程序
原文链接:https://www.cnblogs.com/niechen/p/9016816.html
8.AOP设计思想:
1.在原有基础上扩展功能,没有代码入侵,基本功能和扩展功能解耦合。
2.https://www.cnblogs.com/qlqwjy/p/8747476.html
9.AOP源码解析,AOP原理:
https://www.cnblogs.com/hellxz/p/9629012.html
10.spring Aop和AspectJ的区别:什么是AOP?Spring AOP和AspectJ的区别是什么?
https://www.cnblogs.com/chaoesha/p/13037368.html

5.spring事务实现原理:
1.spring事务的配置方式:
1.声明式事务
1.建立在AOP之上,本质是在目标方法前创建或 加入一个事务,目标方法执行完,根据业务情况提交或回滚。
2.编程式事务
1.优点:在代码块中管理事务;
2.缺点:侵入性,实现复杂
2.事务的传播机制:
1.PROPAGATION_REQUIRED:spring默认的事务
1.外层有事务,一块提交,一块回滚。
2.外层没有事务,创建一个新的事务。
2.PROPAGATION_REQUES_NEW
1.每次开启新的事务,同时挂起外层事务,当前事务执行完成,恢复上层事务。
3.PROPAGATION_SUPPORT
1.依赖外部事务,外层有事务则加入,没有则无事务。
4.PROPAGATION_NOT_SUPPORT
1.不支持事务,外层有事务则挂起,执行完当前代码,则恢复外层事务。无论是否异常,都不会回滚当前代码。
5.PROPAGATION_NEVER
1.该事务传播机制不支持外层事务,有外层事务抛出异常。
6.PROPAGATION_MANDATORY
1.该事务传播机制,外层没有事务,则抛出异常。
7.PROPAGATION_NESTED
1.该事务可以保存点,回滚时,不会全部回滚。每个事务各自回滚各自的事务,如果子事务没有把异常吃掉,则还是会引起全部回滚。
3.事务的回滚规则:
1.运行时异常:会回滚
2.检查异常:不会回滚
4.事务的隔离级别:
5.spring声明式事务的参考配置:
1.传播特性:
@Transactional(propagation=Propagation.REQUIRED)
2.隔离级别:
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
3.只读:
1.@Transactional(readOnly=true);该属性用于设置当前事务是否为只读事务,设置为true表示只读,false则表示可读写,默认值为false。
4.超时:
1.@Transactional(timeout=30)
5.回滚:
1.指定单一异常类:@Transactional(rollbackFor=RuntimeException.class)
2.指定多个异常类:@Transactional(rollbackFor={RuntimeException.class, Exception.class})
6.马士兵spring笔记:https://max.book118.com/html/2018/1112/8037111141001132.shtm
7.spring继承interceptor实现自定义spring拦截器:https://www.cnblogs.com/htyj/p/9260281.html
1.本地缓存案例:
1.自定义注解
2.继承interceptor实现自定义拦截器进行拦截,将自定义注解的方法信息和方法参数,和注解配置的操作缓存本地,
3.使用spring aop动态代理:在方法执行完成进行切入操作,拿到方法返回结果。
4.本地缓存操作:根据缓存操作进行处理本地缓存(清空缓存,驱逐缓存,缓存等操作)
8.spring的beanFactoryAware理解
http://www.pinhuba.com/spring/101249.htm
1.我们既然可以通过set来拿到我们要的对象,为什么还要用这个beanFactory呢?
1.道理很简单,因为有些情况是需要动态的去获取对象的,比如说我有10个银行的处理对象,他们都继承了我的BankService对象,但是具体处理的时候要哪家银行的对象呢?这个依赖于用户的选择。
2.你可以注入10个BankService实例,然后用if --else来搞,不过那样太坨了。每增加一家银行你都需要改代码。
3.通过beanFactory的话,那就一行代码搞定,只要给beanName就OK了,动点脑筋吧beanName配置的有规律点,然后根据用户的银行选择,凑出个beanName,大功告成了!
4.简单一句话的理解是:beanFactory让你可以不依赖注入方式,随意的读取IOC容器里面的对象,不过beanFactory本身还是要注入的。
9.spring bean的生命周期:
https://blog.csdn.net/qq_35634181/article/details/104473308