面试官:说说Spring AOP、AspectJ、CGLIB ?它们有什么关系?
欢迎关注方志朋的博客,回复”666“获面试宝典
AOP(Aspect Orient Programming),作为面向对象编程的一种补充,广泛应用于处理一些具有横切性质的系统级服务,如事务管理、安全检查、缓存、对象池管理等。
AOP 实现的关键就在于 AOP 框架自动创建的 AOP 代理,AOP 代理则可分为静态代理和动态代理两大类,其中静态代理是指使用 AOP 框架提供的命令进行编译,从而在编译阶段就可生成 AOP 代理类,因此也称为编译时增强;而动态代理则在运行时借助于 JDK 动态代理、CGLIB 等在内存中“临时”生成 AOP 动态代理类,因此也被称为运行时增强。
先说说AspectJ
在今天之前,我还以为AspectJ 是Spring的一部分,因为我们谈到Spring AOP一般都会提到AspectJ。原来AspectJ是一套独立的面向切面编程的解决方案。
下面我们抛开Spring,单纯的看看AspectJ。
1、AspectJ 安装
下载AspectJ jar包,然后双击安装。安装好的目录结构为:
bin:存放了 aj、aj5、ajc、ajdoc、ajbrowser 等命令,其中 ajc 命令最常用,它的作用类似于 javac
doc:存放了 AspectJ 的使用说明、参考手册、API 文档等文档
lib:该路径下的 4 个 JAR 文件是 AspectJ 的核心类库
2、AspectJ HelloWorld 实现
业务组件 SayHelloService:
package com.ywsc.fenfenzhong.aspectj.learn;
public class SayHelloService {public void say(){System.out.print("Hello AspectJ");}
}
需要来了,在需要在调用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("记录日志 ...");}
}
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 在实现上几乎无关。
来源 | https://www.jianshu.com/p/fe8d1e8bd63e
热门内容:
腾讯 Code Review 规范出炉!
如果从 0 开发电商平台,要用到哪些组件和框架?大多数人都说不全!
0.2秒居然复制了100G文件?
华为最美小姐姐,被外派墨西哥后...
我变秃了,也变强了 ...
突发!LayUI宣布下线
最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。
获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。
明天见(。・ω・。)ノ♡
面试官:说说Spring AOP、AspectJ、CGLIB ?它们有什么关系?相关推荐
- 面试官:Spring AOP、AspectJ、CGLIB 都是什么鬼?它们有什么关系?
AOP(Aspect Orient Programming),作为面向对象编程的一种补充,广泛应用于处理一些具有横切性质的系统级服务,如事务管理.安全检查.缓存.对象池管理等. AOP 实现的关键就在 ...
- Spring AOP,AspectJ,CGLIB 有点晕
AOP(Aspect Orient Programming),作为面向对象编程的一种补充,广泛应用于处理一些具有横切性质的系统级服务,如事务管理.安全检查.缓存.对象池管理等.AOP 实现的关键就在于 ...
- 关于 Spring AOP (AspectJ) 你该知晓的一切
[版权申明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/54629058 出自[zejian ...
- 面试官:spring boot和spring究竟有啥区别?
面试官:spring boot和spring究竟有啥区别? 前言 今天本篇文章主要聚焦说说,spring boot和spring究竟有啥区别,重点对比MVC模块以及Security模块在两大框架使用时 ...
- Spring AOP + AspectJ Annotation Example---reference
In this tutorial, we show you how to integrate AspectJ annotation with Spring AOP framework. In simp ...
- Spring AOP / AspectJ AOP 的区别?
Spring AOP / AspectJ AOP 的区别? Spring AOP属于运行时增强,而AspectJ是编译时增强. Spring AOP基于代理(Proxying),而AspectJ基于字 ...
- 面试官:Spring 用了哪些设计模式?说三种即可 = =
面试官:Spring 用了哪些设计模式?说三种即可 = = 转载:https://mp.weixin.qq.com/s/LGD54XaK4RmhZHxtU0BADg 转载理由:还可以
- Spring合集篇|面试官:Spring都讲不明白,自己走还是我送你?
spring合集|面试官:Spring都讲不明白,自己走还是我送你? 更多合集: B站主页 更多学习资料免费领取.
- 面试官:Spring中用了哪些设计模式?
spring中常用的设计模式达到九种,我们举例说明. 以后再也不怕面试官问我:Spring中用了哪些设计模式了. 1.简单工厂模式 又叫做静态工厂方法(StaticFactory Method)模式, ...
- 面试官: 讲讲 Spring 事务有哪些坑?
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 引言 今天,我们来讲 Spring 中和事务有关的考题. ...
最新文章
- Docker最全教程——从理论到实战(六)
- Android nomedia 避免图片等资源泄露在系统图库其中
- 点击lable标出现下拉搜索框及选择功能
- Jekyll Bootstrap初始
- iOS中EXC_BAD_ACCESS解决办法
- 基于numpy的多项式拟合预测人口数值
- c51 嵌入汇编语言,在C51中嵌入汇编
- pytorch 保存、读取 tensor 数据
- 三层架构之初识庐山真面目
- c# lu分解的代码_LU分解(1)
- 自己敲的low到爆炸的代码
- 表达式二叉树(蛋疼ing)
- 计算机应用教程 卢湘鸿答案,计算机应用教程(Windows 2000环境)习题解答与实验指导...
- EasyPlayer播放海康大华RTSP流时RTSPClient客户端连接兼容问题的解决
- 系列课程 ElasticSearch 之第 5 篇 —— Kibana 高级查询语句、DSL语言查询和过滤、中文分词器(elasticsearch.bat闪退解决办法)
- SAP与ERP的区别联系
- day_05 运算符 if和while的使用
- 基于Python的深度神经网络的中文期刊分类系统
- [WPF] WPF浏览器程序:如何发布并解决不信任程序问题
- 惠普电脑BIOS设置图文详细介绍
热门文章
- 暑期集训5:并查集 线段树 练习题F: HDU - 1166 ​​​​​​​
- cmd中实现scott的解锁和开锁以及授予dba权限
- 数据 + 进化算法 = 数据驱动的进化优化?进化算法 PK 数学优化
- 【代码片段】如何使用CSS来快速定义多彩光标
- 理解Lucene索引与搜索过程中的核心类
- Possion 分布
- Java学习笔记07--日期操作类
- 让你彻底明白什么叫游戏引擎(1)
- 【组队学习】【35期】吃瓜教程——西瓜书+南瓜书
- 【组队学习】【第30期】青少年编程(Scratch 三级)