Spring in Acton 4 读书笔记之使用 AOP 为类动态添加方法

字数891 大约花费3分钟

目录

  1. 1. 定义包含要引入的方法的接口
  2. 2. 定义 aspect,将方法引入到实例
  3. 3. 装配 aspect 的 bean

我计划完成 50 到 100 篇有关 Spring 的文章,这是第十三篇。本文对应 Spring in Action(Spring 实战)第四版第四章中(4.3.4 Annotating introductions)的内容,将讲解如何使用标签为类动态添加方法。

一些像 Ruby 和 Groovy 这样的语言,有开放类(open classes)的概念,可以在不改变类和对象的定义的情况下,增加新的方法。不幸的是,Java 没有那么动态,一旦一个类编译好之后,很难再为这个类增加功能了。

但是仔细想想,使用 AOP 的时候,难道不是在动态增加功能吗?虽然没有为类增加方法,但是为这些类执行时增加了一些功能性。进而,使用 AOP 的 introduction 的概念,可以给 Spring 的 bean 添加方法。

在 Spring 中,aspect 对目标对象进行代理,并且和目标对象有相同接口。试想一下,如果不仅具有目标对象的接口,还添加了一些目标对象没有的接口,那么通过调用这个代理,就可以实现目标对象没有实现的接口了。这样,尽管没有改变目标对象的代码,却在功能上添加了方法。

工作原理如下图:
使用 AOP 为类动态添加方法

举个例子,假设 Performance 是一个接口,现在想为这个接口的所有实现,动态添加一个 performEncore()方法。首先我们要定义一个包含 performEncore()方法的接口,再定义一个 aspect 将这个接口与 Performance 的实例关联。

定义包含要引入的方法的接口

定义包含要引入的 performEncore()方法的接口:

1
2
3
public interface Encoreable {
void performEncore();
}

定义 aspect,将方法引入到实例

1
2
3
4
5
6
@Aspect
public class EncoreableIntroducer {
@DeclareParents(value="concert.Performance+",
defaultImpl=DefaultEncoreable.class)
public static Encoreable encoreable;
}

在这个 aspect 中,没有使用常用的 @Before,@After,@Around 等标签,而是使用了 @DeclareParents 标签。它的 value 属性指定了哪些实例要引入方法,defaultImpl 属性则指定了引入的接口(这个例子中是指 Encoreable 接口)的默认实现类,而在这个类(DefaultEncoreable)中有引入的方法的具体实现。此外,被引入的接口,使用 static 修饰。上面的语句中,concert.Performance+ 表示 Performance 的任何具体实现类,不包含 Performance 接口本身。在这个例子中,Performance 接口的所有实现类都默认实现了 Encoreable 接口。所以,在使用 Encoreable 接口时,可以做到:既使用 Performance 的实现类的方法,又使用新添加的 performEncore 方法。至于 Encoreable 接口代表 Performance 的哪个具体实现类的实例,则可以在注入 bean 时决定,而注入的 bean 则自动有了新增加的 performEncore 方法,当然,从语法上看,是在使用 Encoreable 接口的方法。

下面的例子中,注入的 bean(Performance 接口的某个具体实现类的实例)执行了 DefaultEncoreable 的 performEncore 方法。

1
2
3
4
@Autowired
public void performEncore(Encoreable encoreable){
encoreable.performEncore();
}

最后,别忘了 aspect 自身需要生成实例,才能起作用:

装配 aspect 的 bean

1
<bean class="concert.EncoreableIntroducer" />

装配 bean 的方法有很多种,这里是使用 xml 配置的方式。也可以使用 java 配置,装配 bean,详见《Spring in Acton》第四版第二章《装配 bean》读书笔记

谈谈 IT的文章均为原创或翻译(翻译会注明外文来源),转载请以链接形式标明本文地址: http://tantanit.com/springinacton4-du-shu-bi-ji-zhi-shi-yong-aop-wei-lei-dong-tai-tian-jia-fang-fa/

谈谈IT

欢迎关注官方微信公众号获取最新原创文章