Spring 开发框架

SpringCore 主要提供 IoC 依赖注入功能的支持
SpringMVC 快速构建 MVC 架构的 Web 程序
SpringBoot 简化 Spring 开发,减少配置文件,开箱即用

IOC 控制反转

当一个对象创建时,它所依赖的对象由外部传递给它,而非自己去创建所依赖的对象(比如通过new操作)。因此,也可以说在对象如何获取它的依赖对象这件事情上,控制权反转了。这便不难理解控制反转和依赖注入这两个名字的由来了。

将对象之间的相互依赖关系交给 IoC 容器来管理,并由 IoC 容器完成对象的注入
Bean 工厂模式

  • 单例 Singleton、多例/原型 Prototype Bean

AOP 面向切面编程

将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。实现方式:基于动态代理,有接口用 jdk 原生的代理方法,没借口用 CGLib

Bean 生命周期

自动装配:@Component;@Service;@Controller;@Configure + @Bean

xxx.class --> 默认无参构造方法 --> 普通对象 --> 依赖注入(属性赋值) --> 初始化前 --> 初始化 --> 初始化后 --> 代理对象 --> 得到Bean(源码)实例化 Bean 对象:默认调用无参构造器;若使用有参构造器,参数必须是容器中有的Bean【按参数查找 Bean 时,先按照 classname 后按照参数名】初始化前中后:BeanPostProcessor 的 postProcessAfterInitialization() --> @PostConstruct 注解 --> InitializingBean 的 afterPropertiesSet() 方法 --> BeanPostProcessor 的 postProcessAfterInitialization()(实现了 AOP 代理)

  • Aware 其实就是一个标识;只有满足 Aware 规范或者其子类规范的才能进行相关的赋值操作,这样做的话可以少写很多判断,并且可以在一个地方进行统一的判断赋值;
  • BeanPostProcessor 前置处理器的关键实现类:ApplicationContextAwareProcessor
  • BeanPostProcessor 后置处理器的关键实现类:AbstractAutoProxyCreator。这个方法负责帮我们创建代理,底层采用对象cglib 或动态代理【AOP其实就是 IOC 整体流程(Bean生命周期)里的一个扩展点】
  • InitializingBean 接口中的 afterPropertiesSet 方法:在这个方法里面去编写我们的业务逻辑,以及进行相关的属性赋值等等

底层实现

  • AbstractAutowireCapableBeanFactory 内的 initializeBean 调用了所有 BeanPostProcessor 的实现类
  • ApplicationContext 类型容器的内部维护了一个 BeanFactory 类型的容器(AnnotationConfigApplicationContext 的父类 GenericApplicationContext 维护了一个 Bean 工厂实现类:DefaultListableBeanFactory)
  • DefaultListableBeanFactory:Spring 默认的 BeanFactory 实现
  • DefaultSingletonBeanRegistry:DefaultListableBeanFactory 单例模式存储关系的地方 Map<String(BeanName),Object(instance)>
  • AbstractApplicationContext.refresh() 方法
    • 配置了对 BeanFactoryPostProcessor 的实现 postProcessBeanFactory(beanFactory) 和处理 invokeBeanFactoryPostProcessors(beanFactory)。BeanFactoryPostProcessor 可以自定义 ApplicationContext 容器中的 BeanFactory 进行处理,在还没有对任何Bean进行实例化之前(ConfigurationClassPostProcessor 通过注解解析配置类;PropertySourcesPlaceholderConfigurer:xml配置文件中导入的 properties 文件进行解析,并替换bean定义中的占位符)
    • 配置了对 BeanPostProcessor 的实现

  1. (1-1)依赖注入:@Autowired;@Resource
  2. 事务 @Transactional、@Configuration
  3. (1-2)单例 Singleton、多例/原型 Prototype Bean
  4. jvm类加载器classloader:bootstrap ext app 博客

TODO Spring 启动流程
Springboot 和 Spring 最大的区别就是不需要 xml 配置
Springboot 自动配置

  • “约定优于配置”理念
  • @EnableAutoConfiguration
  • 自动将一些配置类的bean注册进ioc容器

logback是 slf4j 的官方实现,log4j 是另一个实现,logback 和 log4j 才是二选一,slf4j 是门面日志的 api。

TODO
https://www.cnblogs.com/tuyang1129/p/12861617.html
https://www.cnblogs.com/tuyang1129/p/12866484.html

Spring 事务

Spring 的声明式事务信息是存在 ThreadLocal 中的,所以一个线程永远只能有一个事务,所以 Spring 的事务是无法实现事务一致性(同时提交、同时回滚)的

解决方法:可以通过编程式事务,或者通过分布式事务的思路:二阶段提交方式

如何解决循环依赖

三层缓存设计

  • 一级缓存,缓存正常的 bean 实例
  • 二级缓存,缓存还未进行依赖注入和初始化方法调用的 bean 实例
  • 三级缓存,缓存 bean 实例的 ObjectFactory,用于解决 BeanPostProcessor 代理类时正确地依赖注入

循环依赖的情况下,不管使用三级缓存还是两级缓存,代理类逻辑都必须提前曝光