@DeclareParents非常有意思,单独拿出来,这个可以给实现相同接口的类增加新的共同接口,

这样在不侵入原有代码的情况下,转换成其他类型并拥有新的方法。

这个功能在Spring AOP文档中叫做Introductions:

Introductions (known as inter-type declarations in AspectJ) enable an aspect to declare that advised objects implement a given interface, and to provide an implementation of that interface on behalf of those objects.
An introduction is made using the @DeclareParents annotation. This annotation is used to declare that matching types have a new parent (hence the name). For example, given an interface UsageTracked, and an implementation of that interface DefaultUsageTracked, the following aspect declares that all implementors of service interfaces also implement the UsageTracked interface.

The interface to be implemented is determined by the type of the annotated field. The value attribute of the @DeclareParents annotation is an AspectJ type pattern :- any bean of a matching type will implement the UsageTracked interface. Note that in the before advice of the above example, service beans can be directly used as implementations of the UsageTracked interface.

继续使用CompactDisc和其实现BlankDisc

CompactDisc

package main.java.soundsystem;
public interface CompactDisc {void play();void playTrack(Integer trackNumber);
}

BlankDisc

package main.java.soundsystem;import java.util.List;public class BlankDisc implements  CompactDisc{private  String title;private  String artist;private List<String> tracks;public BlankDisc setTitle(String title) {this.title = title;return this;}public BlankDisc setArtist(String artist) {this.artist = artist;return this;}public String getTitle() {return title;}public String getArtist() {return artist;}public void setTracks(List<String> tracks) {this.tracks = tracks;}public void play() {System.out.println("Playing " + title + " by " + artist);if(tracks!=null) {for (String track : tracks) {System.out.println("-Track: " + track);}}}@Overridepublic void playTrack(Integer trackNumber) {System.out.println("Playing "+tracks.get(trackNumber-1));}}

定义一个新的Printer接口及其实现CDPrinter

package main.java.soundsystem;public interface Printer {void printCover();
}

package main.java.soundsystem;public class CDPrinter implements Printer {@Overridepublic void printCover() {System.out.println("print CD cover..."+Time);}public String getTime() {return Time;}public CDPrinter setTime(String time) {Time = time;return this;}private String Time;
}

那么如何在不修改CompactDisc及其实现的情况下,增加新的方法呢?使用@DeclareParent,使用Java代码配置。

@DeclareParents有两个参数value,defaultImpl,

value表示要为哪些类增加新的父类接口,最后的“+”表示对所有实现CompactDisc接口的类增加接口,

defaultImpl表示新增接口的默认实现,这里新增接口就是被增加标签的Printer接口,

这样所有实现CompactDisc接口的类,都引入了Printer接口,并且拥有了Printer中的方法。

package main.java.soundsystem;import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareParents;
import org.springframework.stereotype.Component;@Component
@Aspect
public class CDPrinterAspect {@DeclareParents(value = "main.java.soundsystem.CompactDisc+",defaultImpl =CDPrinter.class)public static Printer printer;
}

增加xml配置,注意配置中并没有声明Printer对应的Bean。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="main.java.soundsystem"/><aop:aspectj-autoproxy/><bean id="blankDisc"  class="main.java.soundsystem.BlankDisc"><property name="title" value="Sgt. Pepper's Lonely Heart Club Band"/><property name="artist" value="the Beatles"/><property name="tracks"><list><value>Sgt. Pepper's Lonely Hearts Club Band</value><value>With a Little Help from My Friends</value><value>Lucy in the Sky with Diamonds</value><value>Getting Better</value><value>Fixing a Hole</value></list></property></bean>
</beans>

具体使用,通过上下文使用BlankDisc生成了了一个CompactDisc的实例,然后显式转换为Printer对象,并且使用其中由CDPrinter实现的方法,

package main.java.soundsystem;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class main {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("TrackCounterConfig.xml");CompactDisc cd=(CompactDisc)context.getBean("blankDisc");cd.play();System.out.println("\ncast to Printer\n");((Printer)cd).printCover();}
}

结果:

Playing Sgt. Pepper's Lonely Heart Club Band by the Beatles
-Track: Sgt. Pepper's Lonely Hearts Club Band
-Track: With a Little Help from My Friends
-Track: Lucy in the Sky with Diamonds
-Track: Getting Better
-Track: Fixing a Holecast to Printerprint CD cover...null

转载于:https://www.cnblogs.com/lvjianwei/p/7729207.html

Spring 实战-第四章-4.3 使用注解引入新方法 Introductions@DeclareParents相关推荐

  1. 《spring实战第四版》的读书笔记

    <spring实战第四版>的读书笔记 1 概述 <Spring实战第四版>描述了Spring4架构的设计,看完了以后,最大感觉是Spring的IOC与aop理念实在是太强大了, ...

  2. Spring实战(第四版)

    Spring实战(第四版) 链接:https://pan.baidu.com/s/1PhnJqOsQPz5hqe-zxkqPOg 提取码:eu15 复制这段内容后打开百度网盘手机App,操作更方便哦

  3. 尚学堂java实战第四章课后习题

    尚学堂java实战第四章课后习题 文章中的题目答案仅供参考 选择题答案: 1.B 解析:一个java类必然存在构造器,即使没有定义构造器,也会存在一个默认的无参构造器. 2.D 3.AC 解析: A( ...

  4. 机器学习实战——第四章(分类):朴素贝叶斯

    前言 首先感谢博主:Jack-Cui 主页:http://blog.csdn.net/c406495762 朴素贝叶斯博文地址: https://blog.csdn.net/c406495762/ar ...

  5. 零基础学Python课后实战第四章

    零基础学Python课后实战第四章 实战一:输出王者荣耀的游戏角色 实战二:模拟火车订票系统 实战三:电视剧的收视率排行榜 tips 实战一:输出王者荣耀的游戏角色 列表的创建.遍历列表 代码 pri ...

  6. Spring Cloud第四章:熔断器Hystrix

    在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign来调用.为了保证其高可用,单个服务 ...

  7. android movie 资源释放,Android 资讯类App项目实战 第四章 电影模块

    前言: 正在做一个资讯类app,打算一边做一边整理,供自己学习与巩固.用到的知识复杂度不高,仅适于新手.经验不多,如果写出来的代码有不好的地方欢迎讨论. 以往的内容 第四章 电影模块 本章内容最终效果 ...

  8. Spring实战第七章

    一.SpringMVC配置代替方案 1自定DispatcherServlet 按照AbstractAnnotationConfigDispatcherServletInitializer的定义,它会创 ...

  9. Spring实战 第1章 Spring之旅

    本章内容: Spring的bean容器 介绍Spring的核心模块 Spring的新功能 本章目录: 1.1 简化Java开发 1.1.1 激发POJO的潜能 1.1.2 依赖注入(DI) 1.1.3 ...

  10. 合同在线修改 java_Java并发编程实战-第四章

    序文: 如果你没有时间阅读这本,那你就来对地方了.小编会将每一章刨去废话,取其精华.分享给大家.如果觉得可以请不要忘了关注小编.我会定期跟新java 中的经典书籍. 正文: 第四章:对象的组合(更加适 ...

最新文章

  1. 自媒体敏感词大全_让新媒体小编头疼的敏感词与错别字
  2. python中字符串格式化
  3. python fileinput_python fileinput模块
  4. performance and scalability
  5. 基于android的水稻叶片特征测量系统,基于Android的水稻叶片特征参数测量系统
  6. linux ndk编译so,有的APP NDK 编译的SO文件 无法调用 PackageManager
  7. linux QT 结束当前进程_Qt编写控件属性设计器7-串口采集
  8. css 背景图怎么设置自动填充满_CSS属性设置 -- 背景样式
  9. LeetCode 2134. 最少交换次数来组合所有的 1 II(数组*2 + 滑动窗口)
  10. Flink 1.9 实战:使用 SQL 读取 Kafka 并写入 MySQL
  11. 智慧园区-楼宇建模技巧之【建楼篇】
  12. Linux RHEL6 x64 命令行静默安装 Oracle 12c - 2
  13. abaqus分析用户手册单元卷_ABAQUS与你我的约定
  14. WinFrm程序使用的图片展示控件.带删除的
  15. FreeTextBox 3.1.6 的实践总结和几个问题
  16. 冰冰讲数学鸿蒙团队4年级,冰冰也曾是水肿星人?3分钟急救方案教你甩掉晨间浮肿脸!...
  17. 软件详细设计说明书_软件测试的基本理论 笔记
  18. 《众妙之门——用户体验设计的秘密》一1.4 良性的问题解决案例
  19. 用ESP32打造一个物联网红外测温打卡机/春节结束急着上班?哒咩,再努力奋斗也要先测体温
  20. AndroidStudio高级计算器三角函数对数

热门文章

  1. Navicat 将 psc备份文件还原
  2. python 多线程爬虫下载中图分类号
  3. android椭圆形形框_什么是计算机硬件上的椭圆形Kong?
  4. Java中IO流的理解
  5. 2018-2019-1 20165320 《信息安全系统设计基础》 缓冲区溢出漏洞实验
  6. Python——基础语法
  7. Processing编写熊猫
  8. stata基础使用教程(操作版)
  9. 怎么在字符串中加加号python_python加号连接字符串
  10. 进入显示器工厂模式的方法! 【95种品牌,维修珍藏资料】