IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Spring in Acton 4读书笔记之使用AOP为类动态添加方法 -> 正文阅读

[Java知识库]Spring in Acton 4读书笔记之使用AOP为类动态添加方法

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

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

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

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

工作原理如下图:
在这里插入图片描述

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

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

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

  public interface Encoreable {
      void performEncore();
  }

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

@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方法。

@Autowired
public void performEncore(Encoreable encoreable){
  encoreable.performEncore();
}

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

装配aspect的bean

  <bean class="concert.EncoreableIntroducer" />

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

欢迎扫描下方二维码关注微信公众号【谈谈IT】,第一时间获取最新文章。
欢迎关注同名公众号

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-09-05 10:40:31  更:2021-09-05 10:42:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 13:19:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码