【136期】面试官:Spring AOP、AspectJ、CGLIB ?它们有什么关系?

需要来了,在需要在调用say()方法之后,需要记录日志。那就是通过AspectJ的后置增强吧。

LogAspect 日志记录组件,实现对com.ywsc.fenfenzhong.aspectj.learn.SayHelloService 后置增强:

package com.ywsc.fenfenzhong.aspectj.learn;

public aspect LogAspect{

pointcut logPointcut():execution(void SayHelloService.say());

after():logPointcut(){

System.out.println(“记录日志 …”);

}

}

3、编译SayHelloService
  • 执行命令  ajc -d . SayHelloService.java LogAspect.java

  • 生成 SayHelloService.class

  • 执行命令   java SayHelloService

  • 输出  Hello AspectJ  记录日志

ajc.exe 可以理解为 javac.exe 命令,都用于编译 Java 程序,区别是 ajc.exe 命令可识别 AspectJ 的语法;我们可以将 ajc.exe 当成一个增强版的 javac.exe 命令.执行*ajc命令后的 SayHelloService.class 文件不是由原来的 SayHelloService.java 文件编译得到的,该 SayHelloService.class 里新增了打印日志的内容——这表明 AspectJ 在编译时“自动”编译得到了一个新类,这个新类增强了原有的 SayHelloService.java 类的功能,因此 AspectJ 通常被称为编译时增强的 AOP 框架。*

与 AspectJ 相对的还有另外一种 AOP 框架,它不需要在编译时对目标类进行增强,而是运行时生成目标类的代理类,该代理类要么与目标类实现相同的接口,要么是目标类的子类——总之,代理类的实例可作为目标类的实例来使用。一般来说,编译时增强的 AOP 框架在性能上更有优势——因为运行时动态增强的 AOP 框架需要每次运行时都进行动态增强。

再谈 Spring AOP


Spring AOP也是对目标类增强,生成代理类。但是与AspectJ的最大区别在于—Spring AOP的运行时增强,而AspectJ是编译时增强。

曾经以为AspectJ是Spring AOP一部分,是因为Spring AOP使用了AspectJ的Annotation。使用了Aspect来定义切面,使用Pointcut来定义切入点,使用Advice来定义增强处理。虽然使用了Aspect的Annotation,但是并没有使用它的编译器和织入器。其实现原理是JDK 动态代理,在运行时生成代理类。

为了启用 Spring 对 @AspectJ 方面配置的支持,并保证 Spring 容器中的目标 Bean 被一个或多个方面自动增强,必须在 Spring 配置文件中添加如下配置

aop:aspectj-autoproxy/

当启动了 @AspectJ 支持后,在 Spring 容器中配置一个带 @Aspect 注释的 Bean,Spring 将会自动识别该 Bean,并将该 Bean 作为方面 Bean 处理。方面Bean与普通 Bean 没有任何区别,一样使用 <bean…/> 元素进行配置,一样支持使用依赖注入来配置属性值。

使用Spring AOP的改写 Hello World的例子。

业务组件 SayHelloService:

package com.ywsc.fenfenzhong.aspectj.learn;

import org.springframework.stereotype.Component;

@Component

public class SayHelloService {

public void say(){

System.out.print(“Hello  AspectJ”);

}

}

做后置增强的日志处理。

package com.ywsc.fenfenzhong.aspectj.learn;

import org.aspectj.lang.annotation.After;

import org.aspectj.lang.annotation.Aspect;

import org.springframework.stereotype.Component;

@Aspect

@Component

public class LogAspect {

@After(“execution(* com.ywsc.fenfenzhong.aspectj.learn.SayHelloService.*(…))”)

public void log(){

System.out.println(“记录日志:公众号Java精选,你懂的,想要的视频 …”);

}

}

package com.ywsc.fenfenzhong.mongodb;

import com.ywsc.fenfenzhong.aspectj.learn.SayHelloService;

public class TestCase {

public static void main(String[] args) {

SayHelloService sayHelloService = ApplicationUtil.getContext().getBean(SayHelloService.class);

sayHelloService.say();

}

}

输出结果:

Hello  AspectJ

记录日志…

总结


AOP 代理 = 原来的业务类+增强处理。

这个生成AOP 代理由 Spring 的 IoC 容器负责生成。也由 IoC 容器负责管理。因此,AOP 代理可以直接使用容器中的其他 Bean 实例作为目标,这种关系可由 IoC 容器的依赖注入提供。回顾Hello World的例子,其中程序员参

与的只有 3 个部分:

  • 定义普通业务组件。

  • 定义切入点,一个切入点可能横切多个业务组件。

  • 定义增强处理,增强处理就是在 AOP 框架为普通业务组件织入的处理动作。

最后说说CGLIB


CGLIB(Code Generation Library)它是一个代码生成类库。它可以在运行时候动态是生成某个类的子类。代理模式为要访问的目标对象提供了一种途径,当访问对象时,它引入了一个间接的层。

JDK自从1.3版本开始,就引入了动态代理,并且经常被用来动态地创建代理。JDK的动态代理用起来非常简单,唯一限制便是使用动态代理的对象必须实现一个或多个接口。而CGLIB缺不必有此限制。要想Spring AOP 通过CGLIB生成代理,只需要在Spring 的配置文件引入

aop:aspectj-autoproxy proxy-target-class=“true”/

CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM(Java字节码操控框架),来转换字节码并生成新的类。由于没有了解过class 文件和字节码,因而也就写不下去了。

也许学习下来最大的收获便是弄清楚了 AspectJ 和 Spring AOP 在实现上几乎无关。

作者: dolphin叔叔

www.jianshu.com/p/fe8d1e8bd63e

精品资料,超赞福利!

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

总结

我们总是喜欢瞻仰大厂的大神们,但实际上大神也不过凡人,与菜鸟程序员相比,也就多花了几分心思,如果你再不努力,差距也只会越来越大。实际上,作为程序员,丰富自己的知识储备,提升自己的知识深度和广度是很有必要的。

Mybatis源码解析

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
果你再不努力,差距也只会越来越大。实际上,作为程序员,丰富自己的知识储备,提升自己的知识深度和广度是很有必要的。

Mybatis源码解析

[外链图片转存中…(img-ps0EQGt1-1713521288267)]

[外链图片转存中…(img-Y2p6RCb6-1713521288269)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 22
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值