文章图片
文章图片
文章图片
话不多说 , 发车!
说下 AOPAOP , Aspect Oriented Programming , 面向切面编程 。
将一些通用的逻辑集中实现 , 然后通过 AOP 进行逻辑的切入 , 减少了零散的碎片化代码 , 提高了系统的可维护性 。
具体是含义可以理解为:通过代理的方式 , 在调用想要的对象方法时候 , 进行拦截处理 , 执行切入的逻辑 , 然后再调用真正的方法实现 。
例如 , 你实现了一个 A 对象 , 里面有 addUser 方法 , 此时你需要记录该方法的调用次数 。
那么你就可以搞个代理对象 , 这个代理对象也提供了 addUser 方法 , 最终你调用的是代理对象的 addUser, 在这个代理对象内部填充记录调用次数的逻辑 , 最终的效果就类似下面代码:
Enhancer en = new Enhancer();
//2.设置父类 , 也就是代理目标类 , 上面提到了它是通过生成子类的方式
en.setSuperclass(target.getClass());
//3.设置回调函数 , 这个this其实就是代理逻辑实现类 , 也就是切面 , 可以理解为JDK 动态代理的handler
en.setCallback(this);
//4.创建代理对象 , 也就是目标类的子类了 。
return en.create();
JDK 动态代理和 CGLIB 两者经常还可能被面试官问性能对比 , 所以咱们也列一下(以下内容取自:haiq的博客):
- jdk6 下 , 在运行次数较少的情况下 , jdk动态代理与 cglib 差距不明显 , 甚至更快一些;而当调用次数增加之后 ,cglib 表现稍微更快一些
- jdk7 下 , 情况发生了逆转!在运行次数较少(1000000)的情况下 , jdk动态代理比 cglib 快了差不多30%;而当调用次数增加之后(50000000) ,动态代理比 cglib 快了接近1倍
- jdk8 表现和 jdk7 基本一致
能说说拦截链的实现吗?我们都知道 Spring AOP 提供了多种拦截点 , 便捷我们对 AOP 的使用 , 比如 @Before、@After、@AfterReturning、@AfterThrowing 等等 。
方便我们在目标方法执行前、后、抛错等地方进行一些逻辑的切入 。
那 Spring 具体是如何链起这些调用顺序的呢?
这就是拦截链干的事 , 实际上这些注解都对应着不同的 interceptor 实现 。
然后 Spring 会利用一个集合把所有类型的 interceptor 组合起来 , 我在代码里用了 @Before、@After、@AfterReturning、@AfterThrowing这几个注解 。
于是集合里就有了这些 interceptor(多了一个 expose...等下解释) , 这是由 Spring 扫描到注解自动加进来的:
然后通过一个对象 CglibMethodInvocation 将这个集合封装起来 , 紧接着调用这个对象的 proceed 方法 , 可看到这个集合 chain 被传入了 。
我们来看下 CglibMethodInvocation#proceed 方法逻辑 。
要注意 , 这里就开始 递归套娃 了 , 核心调用逻辑就在这里:
可以看到有个 currentInterceptorIndex 变量 , 通过递归 , 每次新增这索引值 , 来逐得到下一个 interceptor。
并且每次都传入当前对象并调用 interceptor#invoke, 这样就实现了拦截链的调用 , 所以这是个递归 。
- 裁员|阿里腾讯被爆裁员20%最直接反映了实体经济与互联网产业的区别!
- |线上店铺自运营与代运营的区别
- ai|1秒识别200个假大牌,清华阿里邀全国人才用20张图锻造“打假AI”
- 阿里巴巴|Java和JavaScript之间的区别
- exynos|别被数字骗了!三星新一代处理器Exynos 1280性能堪忧!
- 装机更轻松、灯效更智能!蓝宝石Radeon RX 6900 XT 16G D6超白金极光特别版显卡深度评测
- ota|iOS15.4真的耗电吗?可能你更新方法不对,聊聊OTA和线刷的区别
- 裁员|互联网大厂大规模裁员,别抱怨,毕业式裁员是给打工人最后的体面
- 索尼|索尼Sony电视型号详解,X系列和A系列区别很大,你选对了吗?
- 显卡|装一台(伪)小钢炮主机,测测win10和win11的区别大不大