切面可以为Spring bean添加新方法。 在Spring中,切面只是实现了它们所包装bean相同接口的 代理。如果除了实现这些接口,代理也能暴露新接口的话,会怎么样 呢?那样的话,切面所通知的bean看起来像是实现了新的接口,即便 底层实现类并没有实现这些接口也无所谓。

使用Spring AOP,我们可以为bean引入新的方法。 代理拦截调用并委托给实现该方法的其他对象

需要注意的是,当引入接口的方法被调用时,代理会把此调用委 托给实现了新接口的某个其他对象。实际上,一个bean的实现被拆分 到了多个类中。

场景描述:

    在一场音乐会中,添加川剧变脸的环节,但在原来的古典音乐表演类(Classcial.java)中没有这个方法,所以需要为这个表演类再新加一个方法。

1.创建一个新的接口Encoreable.java

 package concert2;

 public interface Encoreable {
void performEncore();
}

2.实现这个接口DefaultEncoreable.java

 package concert2;

 public class DefaultEncoreable implements Encoreable {

     @Override
public void performEncore() {
// TODO Auto-generated method stub
System.out.println("川剧变脸");
} }

3.创建一个用于注入新方法的切面EncoreableIntroducer.java

 package concert2;

 import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareParents;
import org.springframework.stereotype.Component; @Aspect
@Component
public class EncoreableIntroducer {
@DeclareParents(value = "concert2.Performance+", defaultImpl = DefaultEncoreable.class)
public static Encoreable encoreable;
}

EncoreableIntroducer是一个切面,同时声明它是一个bean。但是,它与我们 之前所创建的切面不同,它并没有提供前置、后置或环绕通知,而是 通过@DeclareParents注解,将Encoreable接口引入 到Performance bean中。 @DeclareParents注解由三部分组成:

  • value属性指定了哪种类型的bean要引入该接口。在本例中,也 就是所有实现Performance的类型。(标记符后面的加号表示 是Performance的所有子类型,而不是Performance本 身。)
  • defaultImpl属性指定了为引入功能提供实现的类。在这里, 我们指定的是DefaultEncoreable提供实现。
  • @DeclareParents注解所标注的静态属性指明了要引入了接 口。在这里,我们所引入的是Encoreable接口。

而且在将EncoreableIntroducer声明为一个bean后,Encoreable也就成为了一个bean。

3.采用java装配bean  ConcertConfig.java

 package concert2;

 import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy; @Configuration
@EnableAspectJAutoProxy // 启用AspectJ自动代理
@ComponentScan
public class ConcertConfig { }

4.测试

在此做了对比,因为Encoreable已经声明为bean,所以也可以直接加载,然后调用其方法。其次,因为Encoreable的方法已经添加到Performance中,所以也可以通过Performance的对象进行调用,但需要注意的是,在调用新加入的方法时要进行“伪装”,即将Performance的对象强制转换为Encoreable,然后再调用新加入的方法,以逃过编译器的检查。如果不进行引入的话,强行改变Performance对象的类型,然后调用“新方法”,则会报错。

 package concert2;

 import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = concert.ConcertConfig.class)
public class ConcertTest {
@Autowired
public Performance p;
@Autowired
public Encoreable en;
@Test
public void test() {
p.perform();
System.out.println("-----------------------------");
System.out.println("自己创建对象调用");
en.performEncore();
System.out.println("-----------------------------");
System.out.println("通过Performance对象调用“新方法”");
Encoreable e = (Encoreable) p;
e.performEncore();
}
}

5.结果

省略的部分请参照笔记7

笔记9 AOP练习3(通过注解引入新功能 )的更多相关文章

  1. Spring实战(十)Spring AOP应用——为方法引入新功能、为对象引入新方法

    切面最基本的元素是通知和切点,切点用于准确定位应该在什么地方应用切面的通知. 1.Spring借助AspectJ的切点表达式语言来定义Spring切面 在Spring中,要使用AspectJ的切点表达 ...

  2. 【Spring实战】—— 11 通过AOP为特定的类引入新的功能

    如果有这样一个需求,为一个已知的API添加一个新的功能. 由于是已知的API,我们不能修改其类,只能通过外部包装.但是如果通过之前的AOP前置或后置通知,又不太合理,最简单的办法就是实现某个我们自定义 ...

  3. Kinect开发笔记之二Kinect for Windows 2.0新功能

    这是本博客翻译文档的第一篇文章.笔者已经苦逼的竭尽全力的在翻译了.但无奈英语水平也是非常有限.不正确或者不妥当不准确的地方必定会有,还恳请大家留言或者邮件我以批评指正.我会虚心接受. 谢谢大家.   ...

  4. [置顶] Unity2d引入新功能SpriteAtlas,Sprite新的图集方式

    孙广东  2017.8.3 http://blog.csdn.NET/u010019717 在Unity 2017.1.0f3中引入了 SpriteAtlas 官方文档:  https://docs. ...

  5. Spring总结 4.AOP之为对象添加新功能

    Spring除了提供增强原有功能的方法外,还提供了为一个对象引入新功能的方法.如下: package cn.powerfully.service; public interface IService ...

  6. Spring学习笔记之aop动态代理(3)

    Spring学习笔记之aop动态代理(3) 1.0 静态代理模式的缺点: 1.在该系统中有多少的dao就的写多少的proxy,麻烦 2.如果目标接口有方法的改动,则proxy也需要改动. Person ...

  7. Spring的AOP基于AspectJ的注解方式开发2

    参考自黑马培训机构 上一篇博客提到了在配置文件中开启aop的注解开发,以及简单使用了@Before,@Aspect 这是为了告诉spring为前置通知和切面类 接下来介绍aop的注解的通知类型,和切入 ...

  8. Spring的AOP基于AspectJ的注解方式开发1

    参考自黑马培训机构 创建项目,引入jar包 编写目标类,切面类并完成配置 package spring.day2_aop2; /* * 编写目标类 */ public class OrderDao { ...

  9. Spring学习笔记2—AOP

    1.AOP概念 AOP(Aspect Oriented Programming):面向切面编程,AOP能够将那些与业务无关,却为业务模块所共同调用的应用(例如事务处理.日志管理.权限控制等)封装起来, ...

随机推荐

  1. ThreadLocal就是这么简单

    前言 今天要研究的是ThreadLocal,这个我在一年前学习JavaWeb基础的时候接触过一次,当时在baidu搜出来的第一篇博文ThreadLocal,在评论下很多开发者认为那博主理解错误,给出了 ...

  2. nyoj水池数目

    水池数目 时间限制:3000 ms  |  内存限制:65535 KB 难度:4   描述 南阳理工学院校园里有一些小河和一些湖泊,现在,我们把它们通一看成水池,假设有一张我们学校的某处的地图,这个地 ...

  3. jQuery 文档操作之prepend() 和prependTo()方法.

    //prepend() $("#btnpre").click(function(){ //该方法在被选元素的开头(仍位于内部)插入指定内容. $("div"). ...

  4. it's a big trick

    今天,正式的登上了我注册已久的博客园,最初注册园子得出发点是记录生活点滴和学习工作的心得的,那就不忘初心,从头开始吧. 从校园到工作,从东北到南方 我们毕业啦 谁说毕业遥遥无期,转眼就要各奔东西. 是 ...

  5. 初学者如何查阅自然语言处理(NLP)领域学术资料

    1. 国际学术组织.学术会议与学术论文 自然语言处理(natural language processing,NLP)在很大程度上与计算语言学(computational linguistics,CL ...

  6. egg.js 的优缺点

    egg.js 的优缺点 优点 所有的 web开发的点都考虑到了 agent 很有特色 文件夹规划到位 扩展能力优秀 缺点 最大的问题在于: 使用 loader 加载之后,失去了代码提示的能力 监控和运 ...

  7. Python内置函数(8)——bool

    英文文档: class bool([x]) Return a Boolean value, i.e. one of True or False. x is converted using the st ...

  8. iot前台开发环境:前后台访问映射

    一.前端映射- java代码 二.路由设置 -前台代码 三.访问应用

  9. python实现排序算法 时间复杂度、稳定性分析 冒泡排序、选择排序、插入排序、希尔排序

    说到排序算法,就不得不提时间复杂度和稳定性! 其实一直对稳定性不是很理解,今天研究python实现排序算法的时候突然有了新的体会,一定要记录下来 稳定性: 稳定性指的是 当排序碰到两个相等数的时候,他 ...

  10. https://segmentfault.com/a/1190000004518374#articleHeader3

    https://segmentfault.com/a/1190000004518374#articleHeader3 https://segmentfault.com/q/10100000049065 ...