Spring中的AOP(二)
2.5 Spring的织入
在上一篇文章中,我们介绍了Pointcut、Advice、Advisor三个必要模块,剩下的工作就是把它们拼装起来,也就是织入过程。在Spring中,使用类org.springframework.aop.framework.ProxyFactory
作为织入器。
2.5.1 认识ProxyFactory
首先,ProxyFactory
并非Spring AOP中唯一可用的织入器,而是最基本的一个织入器实现。所以,我们就从这个最基本的织入器开始,了解一下织入过程到底是什么样子的。
使用ProxyFactory
进行织入的逻辑很简单,只要为它提供生产代理对象的原材料,它就会返回那个织入完成的代理对象。我们来看示例代码:
ProxyFactory weaver = new ProxyFactory(yourTargetObject);
Advisor advisor = ...;
weaver.addAdvisor(advisor);
Object proxyObject = weaver.getProxy();
我们知道,Spring AOP在使用代理模式实现AOP的过程中采用了动态代理和CGLIB两种机制,分别对某些接口的目标类和没有实现任何接口的目标类进行代理,所以在使用ProxyFactory
对目标类进行代理的时候,会通过ProxyFactory
的某些行为控制属性对这两种情况进行区分。我们来看具体的场景,首先我们有一个接口,以及它的一个实现类:
public interface ITask {
void execute(TaskExecutionContext ctx);
}
public class MockTask implements ITask {
public void execute(TaskExecutionContext ctx) {
System.out.println("task execute.");
}
}
另外,我们还需要一个织入到Jointpoint的一个横切逻辑,也就是Advice实现。假设是PerformanceMethodInterceptor
:
// 简单的检测系统某些方法的执行性能
public class PerformanceMethodInterceptor implements MethodInterceptor {
private final Log logger = LogFactory.getLog(this.getClass());
public Object invoke(MethodInvocation invocation) throws Throwable {
StopWatch watch = new StopWatch();
try {
watch.start();
return invocation.proceed();
} catch (Exception e) {
//TODO: handle exception
} finally {
watch.stop();
if (logger.isInfoEnabled()) {
logger.info(watch.toString());
}
}
}
}
- 基于接口的代理:
MockTask
实现了ITask
接口,要对这种实现了某些接口的目标类进行代理,我们使用setInterfaces(new Class[]{ITask.class})
来明确告知ProxyFactory
我们要对ITask
接口类型进行代理。
ProxyFactory weaver = new ProxyFactory(new MockTask);
weaver.setInterfaces(new Class[]{ITask.class});
- 基于类的代理:如果目标类没有实现任何接口,
ProxyFactory
会对目标类型进行基于类的代理,即使用CGLIB。假设我们现在有一个对象,定义如下:
public class Executable {
public void execute() {
System.out.println("Executable without any Interfaces");
}
}
织入的过程如下所示:
ProxyFactory weaver = new ProxyFactory(new Executable());
weaver.addAdvisor(advisor);
Executable proxyObject = (Executable)weaver.getProxy();
proxyObject.execute();
但是,即使目标对象类实现了至少一个接口,我们也可以通过proxyTargetClass
属性强制ProxyFactory
采用基于类的代理。除此之外,如果将ProxyFactory
的optimize
属性设为true的话,也会采用基于类的代理机制。
2.5.2 看清ProxyFactory的本质
我们不仅要知晓怎么使用ProxyFactory
,并且还需要了解它其中的内部实现,这可以帮我们更好地使用它。我们先从它的根说起:
public interface AopProxy {
Object getProxy();
Object getProxy(ClassLoader classLoader)
}
这个接口对Spring AOP框架内的不同代理实现机制做了适度的抽象,目前,Spring提供了基于JDK动态代理和CGLIB两种机制的AopProxy
实现。
首先,我们来看工厂类AopProxyFactory
的定义:
public interface AopProxyFactory {
AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException;
}
AopProxyFactory
的实现类就一个,DefaultAopProxyFactory
,它会根据传入的AdvisedSupport
示例提供的相关信息,来决定生成什么类型的AopProxy
,实现逻辑很简单,伪代码如下:
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
// 创建Cglib2AopProxy实例,并返回
} else {
// 创建JdkDynamicAopProxy实例,并返回
}
可以发现,生成的AopProxy
类型是由AdvisedSupport
实例来决定的,我们来看一下这个类到底是何方神圣。
AdvisedSupport
继承了ProxyConfig
类并实现了Advised
接口。我们先来看ProxyConfig
类,它其实就是个普通的JavaBean,它定义了5个boolean类型的属性,分别为proxyTargetClass
(指定是否使用CGLIB代理)、optimize
(告知代理对象是否要进行进一步优化,若为true,则使用CGLIB,默认为false)、opaque
(控制代理对象是否可以强制转为Advised
类型)、exposeProxy
、frozen
。
要生成代理对象,光有ProxyConfig
提供的控制信息还不够,我们还需要生成代理对象的一些具体信息,比如Jointpoint和Advice,这些信息可以通过实现Advised
接口来设置或者查询(addAdvisor()/removeAdvisor()
)。
那么,AopProxy
、AdvisedSupport
与ProxyFactory
是什么关系呢?
ProxyFactory
集AopProxy
和AdvisedSupport
于一身,所以可以通过它设置生成对象所需要的相关信息,也可以通过它取得最终生成的代理对象。前者是AdvisedSupport
的职责,后者是AopProxy
的职责。
至此,我们已经了解了ProxyFactory
这个最基本的织入器实现,它还有几个兄弟,比如AspectJProxyFactory
和ProxyFactoryBean
,它们的关系如下所示,在此不作进一步说明,有兴趣的读者可以查阅《Spring揭秘》P179。
参考资料:《Spring揭秘》王福强
Spring中的AOP(二)的更多相关文章
- spring中的AOP 以及各种通知 配置
理解了前面动态代理对象的原理之后,其实还是有很多不足之处,因为如果在项目中有20多个类,每个类有100多个方法都需要判断是不是要开事务,那么方法调用那里会相当麻烦. spring中的AOP很好地解决了 ...
- Spring学习笔记(四)—— Spring中的AOP
一.AOP概述 AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善.O ...
- 2018.12.24 Spring中的aop演示(也就是运用aop技术实现代理模式)
Aop的最大意义是:在不改变原来代码的前提下,也不对源代码做任何协议接口要求.而实现了类似插件的方式,来修改源代码,给源代码插入新的执行代码. 1.spring中的aop演示 aop:面向方面编程.不 ...
- (五)Spring 中的 aop
目录 文章目录 AOP概念 AOP原理 AOP术语 **`Spring`** 中的 **`aop`** 的操作 使用 `AspectJ` 实现 `aop` 的两种方式 AOP概念 浅理解 aop :面 ...
- Spring中的AOP
什么是AOP? (以下内容来自百度百科) 面向切面编程(也叫面向方面编程):Aspect Oriented Programming(AOP),通过预编译方式和运行期动态代理实现程序功能的统一维护的一种 ...
- Spring中关于AOP的实践之概念
一.什么是AOP AOP:也称作面向切面编程 在分享几个概念执行我想先举个栗子(可能例子举得并不是特别恰当): 1.假如路人A走在大街上,被一群坏人绑架了: 2.警察叔叔接到报警迅速展开行动:收集情报 ...
- Spring中的AOP 专题
Caused by: java.lang.IllegalArgumentException: ProceedingJoinPoint is only supported for around advi ...
- JavaWeb_(Spring框架)认识Spring中的aop
1.aop思想介绍(面向切面编程):将纵向重复代码,横向抽取解决,简称:横切 2.Spring中的aop:无需我们自己写动态代理的代码,spring可以将容器中管理对象生成动态代理对象,前提是我们对他 ...
- Spring 中基于 AOP 的 @AspectJ
Spring 中基于 AOP 的 @AspectJ @AspectJ 作为通过 Java 5 注释注释的普通的 Java 类,它指的是声明 aspects 的一种风格. 通过在你的基于架构的 XML ...
- Spring 中基于 AOP 的 XML架构
Spring 中基于 AOP 的 XML架构 为了使用 aop 命名空间标签,你需要导入 spring-aop j架构,如下所述: <?xml version="1.0" e ...
随机推荐
- 读Pyqt4教程,带你入门Pyqt4 _005
对话框窗体或对话框是现代GUI应用不可或缺的一部分.dialog定义为两个或多个人之间的交谈.在计算机程序中dialog是一个窗体,用来和程序“交谈”.对话框用来输入数据.修改数据.改变程序设置等等. ...
- 慕零的黑夜-头条-第一期(必问)[导读:]1.CSDN必问赏金流向何方 2.CSDN必问偷偷做的手脚 3.CSDN必问靠谱吗 4.关于钱于回答的平衡问题:一美元拍卖骗局 作者:qq3461896724
本期是关于CSDN 必问 (biwen.csdn.net)的内容,欢迎评论 文末,文中插入有 小姐姐 img(附py代码,1.49G) + coding资料 哟~~~ 你看到这篇很可能是在提问.推荐加 ...
- Activity组件暴露导致本地拒绝服务
这几天团队打算一起学习Android App漏洞挖掘方面的知识,于是乎拿了一个app当测试例子,争取在上面找到漏洞.在学习过程中发现Android四大组件的安全性还是占有较大的比重,另外比较关心的是数 ...
- Rocket - tilelink - Bundles
https://mp.weixin.qq.com/s/jrqBg2AIpQogBrpwNXjmwg 简单介绍Bundles文件中对TileLink规范(1.7.1)的定义. 参考链接:https: ...
- Java实现 LeetCode 811 子域名访问计数 (暴力)
811. 子域名访问计数 一个网站域名,如"discuss.leetcode.com",包含了多个子域名.作为顶级域名,常用的有"com",下一级则有" ...
- 第十届蓝桥杯JavaC组省赛真题
试题 A: 求和 本题总分:5 分 [问题描述] 小明对数位中含有 2.0.1.9 的数字很感兴趣,在 1 到 40 中这样的数包 括 1.2.9.10 至 32.39 和 40,共 28 个,他们的 ...
- Java实现 LeetCode 54 螺旋矩阵
54. 螺旋矩阵 给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素. 示例 1: 输入: [ [ 1, 2, 3 ], [ 4, 5, 6 ], ...
- java关键字static用法详解
java中有53个关键字,其中包含2个保留字,这篇文章主要介绍一下static这个关键字. static在java中算是一个比较常见的关键字,有着多种用法,因此很有必要好好地了解一番. 一.定义 st ...
- Linux系统命令详解
目录 1. su 1.1. su命令中passwd的自动输入 2. sshpass 3. locate/mlocate 4. top/htop 5. lftp 6. kill/killall 1. s ...
- (五)连接查询(SQL99标准)、子查询、分页查询、联合查询
一.连接查询(SQL99标准) 1.含义:当要查询的数据来自多张表时要使用连接查询 2.语法: select 查询列表 from 表1 别名 [连接类型] join 表2 别名 on 连接条件 [wh ...