[TOC]
## 一、談談自己對于 Spring IoC 和 AOP 的理解
### IoC
IoC(Inverse of Control:控制反轉)是一種**設計思想**,就是將原本在程序中手動創建對象的控制權,交由Spring框架來管理。IoC 在其他語言中也有應用,并非 Spring 特有。**IoC 容器是 Spring 用來實現 IoC 的載體, IoC 容器實際上就是個Map(key,value),Map 中存放的是各種對象。**
**IoC 容器就像是一個工廠一樣,當我們需要創建一個對象的時候,只需要配置好配置文件/注解即可,完全不用考慮對象是如何被創建出來的。**
### AOP
AOP(Aspect-Oriented Programming:面向切面編程)能夠將那些與業務無關,**卻為業務模塊所共同調用的邏輯或責任(例如事務處理、日志管理、權限控制等)封裝起來**,便于**減少系統的重復代碼**,**降低模塊間的耦合度**,并**有利于未來的可拓展性和可維護性**。
#### 動態代理
**Spring AOP就是基于動態代理的**,如果要代理的對象,實現了某個接口,那么Spring AOP會使用**JDK Proxy**,去創建代理對象,而對于沒有實現接口的對象,就無法使用 JDK Proxy 去進行代理了,這時候Spring AOP會使用**Cglib**,這時候Spring AOP會使用**Cglib**生成一個`被代理對象的子類`來作為代理,如下圖所示:

當然你也可以使用 `AspectJ `,Spring AOP 已經集成了AspectJ ,AspectJ 應該算的上是 Java 生態系統中最完整的 AOP 框架了。
### Spring AOP 和 AspectJ AOP 有什么區別?
| 比較| SpringAOP | AspectJ |
| --- | --- | --- |
|**增強類型**| 運行時增強 | 編譯時增強 |
| **易用程度**| 相對簡單 | 相對復雜 |
| **性能選型** | 切面較少用| 切面復雜用|
|**實現原理**| 通過攔截器+反射;實質上是通過反射將被代理類的加載器和接口與代理對象關聯起來。| 基于ASM實現,性能比較高|
1. Spring AOP 屬于**運行時增強**,而 AspectJ 是**編譯時增強**。Spring AOP 基于代理(Proxying),而 AspectJ 基于字節碼操作(Bytecode Manipulation)。
2. Spring AOP 已經集成了 AspectJ ,AspectJ 應該算的上是 Java 生態系統中最完整的 AOP 框架了。AspectJ 相比于 Spring AOP 功能更加強大,但是 Spring AOP 相對來說更簡單,
3. 如果我們的切面比較少,那么兩者性能差異不大。但是,當切面太多的話,最好選擇 AspectJ ,它比Spring AOP 快很多。
#### 使用區別
JDK 動態代理與 CGLIB 動態代理都是將真實對象`隱藏`在代理對象的后面,以達到 `代理` 的效果。與 JDK 動態代理所不同的是 CGLIB 動態代理使用 Enhancer 來創建代理對象,而 JDK 動態代理使用的是 Proxy.newProxyInstance 來創建代理對象;還有一點是 CGLIB 可以代理大部分類,而 JDK 動態代理只能代理實現了接口的類。
### 動態代理的實現原理
JDK:實質上是通過反射將被代理類的加載器和接口與代理對象關聯起來。
案例:jdk動態代理的使用方法。
```
/**
* 基于jdk反射包下Proxy進行service的代理
* 結果:報錯,JDK的動態代理需要是一個接口;cglib才能動態代理類對象
*/
@Test
public void test_proxy_class() {
UserCertificateService userCertificateService = (UserCertificateService) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader()
, new Class[]{UserCertificateService.class}, ((proxy, method, args) -> "你被代理了"));
UserCertificate userCertificate = userCertificateService.selectById(100);
System.out.println(JSONObject.toJSONString(userCertificate));
}
```
```
java.lang.IllegalArgumentException: com.keyou.evm.lpm.service.UserCertificateService is not an interface
```
- 前言
- 第一部分 計算機網絡與操作系統
- 大量的 TIME_WAIT 狀態 TCP 連接,對業務有什么影響?怎么處理?
- 性能占用
- 第二部分 Java基礎
- 2-1 JVM
- JVM整體結構
- 方法區
- JVM的生命周期
- 堆對象結構
- 垃圾回收
- 調優案例
- 類加載機制
- 執行引擎
- 類文件結構
- 2-2 多線程
- 線程狀態
- 鎖與阻塞
- 悲觀鎖與樂觀鎖
- 阻塞隊列
- ConcurrentHashMap
- 線程池
- 線程框架
- 徹底搞懂AQS
- 2-3 Spring框架基礎
- Spring注解
- Spring IoC 和 AOP 的理解
- Spring工作原理
- 2-4 集合框架
- 死磕HashMap
- 第三部分 高級編程
- Socket與NIO
- 緩沖區
- Bybuffer
- BIO、NIO、AIO
- Netty的工作原理
- Netty高性能原因
- Rabbitmq
- mq消息可靠性是怎么保障的?
- 認證授權
- 第四部分 數據存儲
- 第1章 mysql篇
- MySQL主從一致性
- Mysql的數據組織方式
- Mysql性能優化
- 數據庫中的樂觀鎖與悲觀鎖
- 深度分頁
- 從一條SQL語句看Mysql的工作流程
- 第2章 Redis
- Redis緩存
- redis key過期策略
- 數據持久化
- 基于Redis分布式鎖的實現
- Redis高可用
- 第3章 Elasticsearch
- 全文查詢為什么快
- battle with mysql
- 第五部分 數據結構與算法
- 常見算法題
- 基于數組實現的一個隊列
- 第六部分 真實面試案例
- 初級開發面試材料
- 答案部分
- 現場編碼
- 第七部分 面試官角度
- 第八部分 計算機基礎
- 第九部分 微服務
- OpenFeign工作原理