笔记9 AOP练习3(通过注解引入新功能 )
切面可以为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(通过注解引入新功能 )的更多相关文章
- Spring实战(十)Spring AOP应用——为方法引入新功能、为对象引入新方法
切面最基本的元素是通知和切点,切点用于准确定位应该在什么地方应用切面的通知. 1.Spring借助AspectJ的切点表达式语言来定义Spring切面 在Spring中,要使用AspectJ的切点表达 ...
- 【Spring实战】—— 11 通过AOP为特定的类引入新的功能
如果有这样一个需求,为一个已知的API添加一个新的功能. 由于是已知的API,我们不能修改其类,只能通过外部包装.但是如果通过之前的AOP前置或后置通知,又不太合理,最简单的办法就是实现某个我们自定义 ...
- Kinect开发笔记之二Kinect for Windows 2.0新功能
这是本博客翻译文档的第一篇文章.笔者已经苦逼的竭尽全力的在翻译了.但无奈英语水平也是非常有限.不正确或者不妥当不准确的地方必定会有,还恳请大家留言或者邮件我以批评指正.我会虚心接受. 谢谢大家. ...
- [置顶]
Unity2d引入新功能SpriteAtlas,Sprite新的图集方式
孙广东 2017.8.3 http://blog.csdn.NET/u010019717 在Unity 2017.1.0f3中引入了 SpriteAtlas 官方文档: https://docs. ...
- Spring总结 4.AOP之为对象添加新功能
Spring除了提供增强原有功能的方法外,还提供了为一个对象引入新功能的方法.如下: package cn.powerfully.service; public interface IService ...
- Spring学习笔记之aop动态代理(3)
Spring学习笔记之aop动态代理(3) 1.0 静态代理模式的缺点: 1.在该系统中有多少的dao就的写多少的proxy,麻烦 2.如果目标接口有方法的改动,则proxy也需要改动. Person ...
- Spring的AOP基于AspectJ的注解方式开发2
参考自黑马培训机构 上一篇博客提到了在配置文件中开启aop的注解开发,以及简单使用了@Before,@Aspect 这是为了告诉spring为前置通知和切面类 接下来介绍aop的注解的通知类型,和切入 ...
- Spring的AOP基于AspectJ的注解方式开发1
参考自黑马培训机构 创建项目,引入jar包 编写目标类,切面类并完成配置 package spring.day2_aop2; /* * 编写目标类 */ public class OrderDao { ...
- Spring学习笔记2—AOP
1.AOP概念 AOP(Aspect Oriented Programming):面向切面编程,AOP能够将那些与业务无关,却为业务模块所共同调用的应用(例如事务处理.日志管理.权限控制等)封装起来, ...
随机推荐
- Windows Powershell脚本执行
在cmd下执行powershell进入shell模式: 变量定义:$i = 10 $a = ifconfig | findstr "192" Windows下的命令都可以执行如: ...
- ( 转 ) 聊一聊C#的Equals()和GetHashCode()方法
聊一聊C#的Equals()和GetHashCode()方法 博客创建一年多,还是第一次写博文,有什么不对的地方还请多多指教. 关于这次写的内容可以说是老生长谈,百度一搜一大堆.大神可自行绕路. ...
- SpringBoot入门:新一代Java模板引擎Thymeleaf(理论)
Spring Boot 提供了spring-boot-starter-web来为Web开发予以支持,spring-boot-starter-web为我们提供了嵌入的Tomcat以及SpringMVC的 ...
- IntelliJ IDEA开发Scala代码,与java集成,maven打包编译
今天尝试了一下在IntelliJ IDEA里面写Scala代码,并且做到和Java代码相互调用,折腾了一下把过程记录下来. 首先需要给IntelliJ IDEA安装一下Scala的插件,在IDEA的启 ...
- logback中批量插入数据库的参考代码
protected void insertProperties(Map<String, String> mergedMap, Connection connection, long eve ...
- SpringBoot(四):banner的控制
banner在springboot中是一个支持可配(banner的样式,banner的颜色,banner的内容).是否显示. 1)banner显示内容配置: 默认springboot如果在src/re ...
- 收藏:视频网站(JavaEE+FFmpeg)/Nginx+ffmpeg实现流媒体直播点播系统
FFmpeg安装(windows环境)http://www.cnblogs.com/xiezhidong/p/6924775.html 最简单的视频网站(JavaEE+FFmpeg)http://bl ...
- Struts(二十一):类型转换与复杂属性、集合属性配合使用
背景: 本章节主要以复杂属性.集合属性类型转化为例,来学习这两种情况下怎么使用. 复杂对象属性转换场景: 1.新建struts_04 web.xml <?xml version="1. ...
- Struts(十):OGNL表达式(一)
Struts2 用s:porperty标签和OGNL表达式来读取值栈中的属性值: I.值栈中的属性值: 1.对象栈:读取对象栈中的某一个对象的属性值: 2.Map栈 :request,session, ...
- 类相关的BIF
1.>>> issubclass(C,A)#判断c是A的子类,返回真假 2.>>> isinstance(b1,B) #判断c1是B类的实例化对象,返回真假 3.& ...