深入解析静态代理模式的不足与改进思考

上篇讲述了代理模式出现的缘由,也阐述了它的实现方式,还说明了它与其他相似设计模式的差异。传送门@_@

深入解析静态代理模式的不足与改进思考

1.静态代理的不足

设计模式中的代理模式,其代理类需要通过手动的方式来编写。然而,手写代理存在着诸多问题。

如果不同类型的目标对象需执行相同一套代理的逻辑,比如在方法调用前后打印参数和结果,那么依然需要为每一个类型撰写一个代理类,这样就会产生大量的样板代码,书写过程非常枯燥。

一个类中存在多个方法。对于那些不需要拦截的方法,我们依然需要手动去调用目标对象所对应的方法。即便这仅仅只有一行代码,但写得多了,还是会让人觉得有些蠢蠢的。

还有,手写的代理类属于静态代理。这种代理类在编译之后,其代码就固定下来了,无法实现动态的变化,缺少一些灵活性。

2.对现存问题的思考

回想我们使用代理类的最初目的,只是为了拦截某个方法的调用。在这个方法调用前后,会执行一些额外逻辑。这些额外逻辑与目标方法没有强关联。方法调用会形成一个调用栈,我们可以把代理想象成是在这个栈上切了一刀,而在切口处做的逻辑,我们称之为切面逻辑。

聪明的程序员想到,把纯净的切面逻辑抽取出来,接着定义一套切入规则,之后让工具自动生成代理类,这样做是很美妙的。

所以说代理通常是天生用于做切面的,代理和切面之间存在着紧密且复杂的关系

从分析得知,AOP 只需关注 3 个方面:要切谁;在什么时间切;在切口处做什么。

非常讨厌那些有着一长串复杂名称的理论性东西,像 Joinpoint、Pointcut、Advice 以及 Before/After/Around Advice 等。这些名字一点都不形象,故意弄得高深莫测,只会误导普通大众。哼,我要把你的小板凳掀翻 (╯—﹏—)╯(┷━━━┷

3.如何自动生成代理

我们知晓,一个类从开始编写起,到在运行时被调用时,中间大概会经历以下这些步骤。

所以生成代理存在三个思路。其一,在编译期对源代码进行修改;其二,在字节码加载之前对字节码进行修改;其三,在字节码加载之后动态创建代理类的字节码。

类别

机制

原理

优点

缺点

技术

静态AOP

静态织入

在编译期,切面直接以字节码的形式编译到目标字节码文件中

对系统无性能影响

灵活性不够

AspectJ

动态AOP

动态代理

在运行期间,目标类完成加载之后,会为接口动态地生成代理类,并且把切面植入到这个代理类里面。

相对于静态AOP更加灵活

切入的关注点需要实现接口。对系统有一点性能影响

JDK dynamic proxy

动态字节码生成

在运行期,目标类被加载之后,会动态构建字节码文件,以此来生成目标类的子类,并且把切面逻辑添加到这个子类当中。

没有接口也可以织入

扩展类的实例方法为final时,则无法进行织入

cglib

自定义类加载器

在运行期,目标加载前,将切面逻辑加到目标字节码里

可以对绝大部分类进行织入

代码中如果使用了其他类加载器,则这些类将不会被织入

字节码转换

在运行期,所有类加载器加载字节码前,前进行拦截

可以对所有类进行织入

4.AspectJ生成静态代理

AspectJ 是 Java 语言的一种 AOP 实现。它主要包含两个部分:其一,定义了如何表达和定义 AOP 编程中的语法规范,借助这套规范,我们能够便捷地运用 AOP 去解决 Java 语言中存在的交叉关注点问题;其二,是工具部分,包含编译器、调试工具等。

下载 AspectJ 较为简单。读者登录 AspectJ 官网()后,能够下载到一个可执行的 JAR 包。接着,通过使用 java -jar aspectj-1.x.x.jar 命令,并且多次单击“Next”按钮,就可以成功安装 AspectJ。

AspectJ 的用法较为简单。就如同我们运用 JDK 来编译以及运行 Java 程序那样。以下是一个较为简单的示例。

编写一个POJO业务类

public class HelloAspectJ {
    public void sayHello() {
        System.out.println("Hello

你可能想看:
« 上一篇
下一篇 »

相关推荐

java中什么是冒泡,冒泡算法

2026年09月06日

27阅读

java中冒号,java双冒号

2026年09月06日

26阅读

java中的->,java中的是什么意思

2026年09月06日

24阅读

java中的super用法,Java中super的说明

2026年09月06日

28阅读

java中反射的应用,java中反射的应用场景

2026年09月06日

26阅读

java中开关的定义,Java关键字有哪些

2026年09月06日

26阅读