Spring 初识

spring 核心思想

  1. IOC/DI:一个意思,IOC 是思想,DI 是实现
  2. AOP:面向切面编程,OOP 是面向对象面呈

IOC 容器

  1. ApplicationContext 是顶级容器。ClassPathXmlApplicationContext 是 xml 方式配置的具体容器; AnnotationConfigApplicationContext 是注解实现的具体容器
  2. 底层依靠 BeanFactory 实现,内部有个 beanFactory 属性
  3. beanFactory.singletonObjects 属性,是一个 map,这个就是单例池,所有的完整的 bean 放在这里
  4. beanFactory.beanDefinitionMap 属性,也是一个 map,放的是所有的的 bean 定义对象(xml定义bean的信息,id,class,lazy,scope 等)
  5. beanFactory.factoryBeanObjectCache 属性,也是一个 map,放的是由 FactoryBean 方式创建的 bean
    1. 创建bean的方式是多样的,如果是 FactoryBean 方式,真实 bean 放在 factoryBeanObjectCache,此时 singletonObjects 放的是工厂对象
    2. 如果创建方式不是 FactoryBean,bean 就放在 singletonObjects 中

AOP

  1. 根本作用是增强 bean,生成 bean 的代理对象,后面调用的时候也是使用这个代理对象,从而达到扩展 bean 的目的,比如事物、日志

  2. 底层根据代理实现,可选的有 JDK 动态代理和 cglib

    1. 如果有接口,就使用 jdk 动态代理,也是 spring 默认的方式
    2. 如果没有接口,就只能使用 cglib 来创建,此时必须保证类没有被 final 修饰,因为创建的代理对象是类的子类的对象
  3. AOP 也是一种思想,实现方式有 AspectJ 和 Advisor

    1. AspectJ 更强大更灵活 Advisor 功能更单一但是更方便
    2. spring 事物管理就是使用 Advisor 实现的,因为事物的功能就比较单一:开启事物、提交事物、回滚事物
    3. 如果自己要做 AOP 一般都是使用 AspectJ

DI

  1. 方式是多样的,可以构造注入、setter 注入、属性注入(属性注入最方便最主流,这里只说属性注入)
  2. @Value 注入基本类型,字符串、布尔值、整形、BigDecimal 等,也可以使用 SpEL 表达式读取 properties 和 yaml 配置
  3. @Autowired 和 @Resource 注入 bean
    1. @Autowired 是 spring 的注解,@Resource 是 java 的(spring 也提供了解析方法,所以也能用)
    2. @Autowired 先根据类型注入,如果发现多个再根据名称匹配。@Resource 相反,@Resource 先根据名称注入,如果找不到再根据类型注入
    3. @Autowired 如果有多个会报错,可以配合 @Qualifier(name = xxx) 指定名称,如果根据名称还是有多个依然会报错
    4. bean 可以使用使用 @Primary 修饰,提高优先级,@Autowired 如果有多个就不会报错了,优先使用这个 bean
    5. @Resource 可以指定名称 @Resource(name = xxx)
    6. @Autowired 和 @Resource 根据名称匹配 bean 时如果不指定 name 属性,都是属性名而不是类首字母小写

循环依赖

  1. 三种场景会产生

    1. bean 内部引入自己
    2. 两个 bean 互相依赖
    3. 多个 bean 互相依赖
  2. 解决方案是三级缓存

    1. 一级缓存:singletonObjects 最终放 bean 的单例池
    2. 二级缓存:earlySingletonObjects 半成本的 bean,已经有被引用了
    3. 三级缓存:singletonFactories 半成品的 bean,还未被引用,对象刚被创建就丢这里
  3. 三级缓存工作原理,需要知道 bean 生命周期才能理解,在后面的文章中再详细说

扩展点(这里只列出能扩展的方式,后面文章再说怎么具体扩展)

  1. BeanFactoryPostProcessor
  2. 各种 aware 回调接口
  3. beanPostProcessor
  4. InitializingBean
  5. 自定义 init 方法
posted @ 2024-06-29 12:10  CyrusHuang  阅读(1)  评论(0编辑  收藏  举报