Spring 初識

CyrusHuang發表於2024-06-29

spring 核心思想

  1. IOC/DI:一個意思,IOC 是思想,DI 是實現
  2. AOP:面向切面程式設計,OOP 是物件導向面呈

IOC 容器

  1. 底層依靠 BeanFactory 實現,內部有個 beanFactory 屬性
  2. beanFactory.singletonObjects 屬性,是一個 map,這個就是單例池,所有的完整的 bean 放在這裡
  3. beanFactory.beanDefinitionMap 屬性,也是一個 map,放的是所有的的 bean 定義物件(xml定義bean的資訊,id,class,lazy,scope 等)
  4. beanFactory.factoryBeanObjectCache 屬性,也是一個 map,放的是由 FactoryBean 方式建立的 bean
  5. 建立bean的方式是多樣的,如果是 FactoryBean 方式,真實 bean 放在 factoryBeanObjectCache,此時 singletonObjects 放的是工廠物件
  6. 如果建立方式不是 FactoryBean,bean 就放在 singletonObjects 中

AOP

  1. 根本作用是增強 bean,生成 bean 的代理物件,後面呼叫的時候也是使用這個代理物件,從而達到擴充套件 bean 的目的,比如事物、日誌
  2. 底層根據代理實現,可選的有 JDK 動態代理和 cglib
  3. 如果有介面,就使用 jdk 動態代理,也是 spring 預設的方式
  4. 如果沒有介面,就只能使用 cglib 來建立,此時必須保證類沒有被 final 修飾,因為建立的代理物件是類的子類的物件
  5. AOP 也是一種思想,實現方式有 AspectJ 和 Advisor
  6. AspectJ 更強大更靈活 Advisor 功能更單一但是更方便
  7. spring 事物管理就是使用 Advisor 實現的,因為事物的功能就比較單一:開啟事物、提交事物、回滾事物
  8. 如果自己要做 AOP 一般都是使用 AspectJ

DI

  1. 方式是多樣的,可以構造注入、setter 注入、屬性注入(屬性注入最方便最主流,這裡只說屬性注入)
  2. @Value 注入基本型別,字串、布林值、整形、BigDecimal 等,也可以使用 SpEL 表示式讀取 properties 和 yaml 配置
  3. @Autowired 和 @Resource 注入 bean
  4. @Autowired 是 spring 的註解,@Resource 是 java 的(spring 也提供瞭解析方法,所以也能用)
  5. @Autowired 先根據型別注入,如果發現多個再根據名稱匹配。@Resource 相反,@Resource 先根據名稱注入,如果找不到再根據型別注入
  6. @Autowired 如果有多個會報錯,可以配合 @Qualifier(name = xxx) 指定名稱,如果根據名稱還是有多個依然會報錯
  7. bean 可以使用使用 @Primary 修飾,提高優先順序,@Autowired 如果有多個就不會報錯了,優先使用這個 bean
  8. @Resource 可以指定名稱 @Resource(name = xxx)
  9. @Autowired 和 @Resource 根據名稱匹配 bean 時如果不指定 name 屬性,都是屬性名而不是類首字母小寫

迴圈依賴

  1. 三種場景會產生
  2. bean 內部引入自己
  3. 兩個 bean 互相依賴
  4. 多個 bean 互相依賴
  5. 解決方案是三級快取
  6. 一級快取:singletonObjects 最終放 bean 的單例池
  7. 二級快取:earlySingletonObjects 半成本的 bean,已經有被引用了
  8. 三級快取:singletonFactories 半成品的 bean,還未被引用,物件剛被建立就丟這裡
  9. 三級快取工作原理,需要知道 bean 生命週期才能理解,在後面的文章中再詳細說

擴充套件點(這裡只列出能擴充套件的方式,後面文章再說怎麼具體擴充套件)

  1. BeanFactoryPostProcessor
  2. 各種 aware 回撥介面
  3. beanPostProcessor
  4. InitializingBean
  5. 自定義 init 方法