[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**生成一个`被代理对象的子类`来作为代理,如下图所示:
![SpringAOPProcess](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/SpringAOPProcess.jpg)
当然你也可以使用 `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工作原理