笔记9 AOP练习3(通过注解引入新功能 )

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

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

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

场景描述:

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

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

1 package concert2;
2
3 public interface Encoreable {
4     void performEncore();
5 }

2.实现这个接口DefaultEncoreable.java

 1 package concert2;
 2
 3 public class DefaultEncoreable implements Encoreable {
 4
 5     @Override
 6     public void performEncore() {
 7         // TODO Auto-generated method stub
 8         System.out.println("川剧变脸");
 9     }
10
11 }

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

 1 package concert2;
 2
 3 import org.aspectj.lang.annotation.Aspect;
 4 import org.aspectj.lang.annotation.DeclareParents;
 5 import org.springframework.stereotype.Component;
 6
 7 @Aspect
 8 @Component
 9 public class EncoreableIntroducer {
10     @DeclareParents(value = "concert2.Performance+", defaultImpl = DefaultEncoreable.class)
11     public static Encoreable encoreable;
12 }

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

 1 package concert2;
 2
 3 import org.springframework.context.annotation.ComponentScan;
 4 import org.springframework.context.annotation.Configuration;
 5 import org.springframework.context.annotation.EnableAspectJAutoProxy;
 6
 7 @Configuration
 8 @EnableAspectJAutoProxy // 启用AspectJ自动代理
 9 @ComponentScan
10 public class ConcertConfig {
11
12 }

4.测试

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

 1 package concert2;
 2
 3 import org.junit.Test;
 4 import org.junit.runner.RunWith;
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.test.context.ContextConfiguration;
 7 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 8
 9 @RunWith(SpringJUnit4ClassRunner.class)
10 @ContextConfiguration(classes = concert.ConcertConfig.class)
11 public class ConcertTest {
12     @Autowired
13     public Performance p;
14     @Autowired
15     public Encoreable en;
16     @Test
17     public void test() {
18         p.perform();
19         System.out.println("-----------------------------");
20         System.out.println("自己创建对象调用");
21         en.performEncore();
22         System.out.println("-----------------------------");
23         System.out.println("通过Performance对象调用“新方法”");
24         Encoreable e = (Encoreable) p;
25         e.performEncore();
26     }
27 }

5.结果

省略的部分请参照笔记7

原文地址:https://www.cnblogs.com/lyj-gyq/p/8886259.html

时间: 2024-10-28 19:15:37

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

Spring_使用注解引入新功能

人行犹可复,岁月难可追. Java并不是动态语言,类编译完成后,很难在为该类添加新的功能,但是利用被称为引入的AOP概念,我们可以利用切面为Spring Bean添加新的方法. 使用@DeclareParents注解,将接口引入到Spring Bean中. @DeclareParents注解由三部分组成: 1)value属性指定了哪种类型的bean要引入该接口.加号(+)表示是该类型的所有子类型,而不是该类型本身. 2)defaultImpl属性指定了为引入功能提供实现的类. 3)@Declar

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

如果有这样一个需求,为一个已知的API添加一个新的功能. 由于是已知的API,我们不能修改其类,只能通过外部包装.但是如果通过之前的AOP前置或后置通知,又不太合理,最简单的办法就是实现某个我们自定义的接口,这个接口包含了想要添加的方法. 但是JAVA不是一门动态的语言,无法再编译后动态添加新的功能,这个时候就可以使用 aop:declare-parents 来做了. 如果是可以改写的类,直接实现自定义的接口就行了,下面看看AOP是如何做的! 最开始使用的类和接口: package com.sp

【Spring】AOP之基于AspectJ注解总结与案例

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka Spring除了支持Schema方式配置AOP,还支持注解方式:使用@AspectJ风格的切面声明.导入需要的包:aspectjweaver.jar.aopalliance-1.0.jar 一.基本使用方法 1.1.启用对@AspectJ的支持 Spring默认不支持@AspectJ风格的切面声明,为了支持需要使用如下配置: <!-- 启动@AspectJ支持 --> <!-- pr

(转)Spring使用AspectJ进行AOP的开发:注解方式

http://blog.csdn.net/yerenyuan_pku/article/details/69790950 Spring使用AspectJ进行AOP的开发:注解方式 之前我已讲过Spring使用AspectJ通过配置文件的方式来进行AOP的开发,现在就来讲怎样使用注解方式进行AOP的开发. 创建一个Web项目, 引入相关的jar包.所要导入的jar包如下:  引入Spring的配置文件.主要引入AOP的约束: <?xml version="1.0" encoding=

aop 拦截含有特定注解的类

1.功能点:使用aop拦截含有自定义注解的类 1.自定义注解 package com.zhuanche.common.dingdingsync; import java.lang.annotation.*; /** * @Author fanht * @Description 含有该注解的controller方法存储到mq * @Date 2019/2/28 上午11:26 * @Version 1.0 */ @Retention(RetentionPolicy.RUNTIME) @Target

Spring_在XML中通过切面引入新的功能

没有不会做的事,只有不想做的事. 在Java配置中我们借助AspectJde @DeclareParents注解为被通知的方法引入新的方法,在XML中我们可以使用Spring aop命名空间的 <aop:declare-parents>元素. <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/be

Android群英传笔记——第十二章:Android5.X 新特性详解,Material Design UI的新体验

Android群英传笔记--第十二章:Android5.X 新特性详解,Material Design UI的新体验 第十一章为什么不写,因为我很早之前就已经写过了,有需要的可以去看 Android高效率编码-第三方SDK详解系列(二)--Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能 这一章很多,但是很有趣,也是这书的最后一章知识点了,我现在还在考虑要不要写这个拼图和2048的案例,在此之前,我们先来玩玩Android5.X的新特性吧!

quick-cocos2d-x学习笔记【2】——项目结构分析、创建新场景

创建完一个新项目之后,我们可以简单的看一看这个项目的文件组成,有这么一个文件层次结构 几个proj.*文件夹就不用说了,是对应的平台的解决方案,res专门存放我们的游戏资源,scripts存放我们的lua代码,sources中有我们熟悉的AppDelegate类,我们主要常用的就两个文件夹,res和scripts(我这不是废话吗) 好吧,还是再打开scripts文件夹看下, 该文件下有main.lua,它是程序lua脚本的启动文件 function __G__TRACKBACK__(errorM

vs2012引入新lib-----附cocos2dx3.2 http通信lib库添加

先说说普通的两种方法(请直接只用方法3来添加): 方法1:  通过设置工程配置来添加lib库. 转自网上: A.添加工程的头文件目录:工程---属性---配置属性---c/c++---常规---附加包含目录:加上头文件存放目录. B.添加文件引用的lib静态库路径:工程---属性---配置属性---链接器---常规---附加库目录:加上lib文件存放目录. C  然后添加工程引用的lib文件名:工程---属性---配置属性---链接器---输入---附加依赖项:加上lib文件名. 这种方法比较繁