@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. 从mysqldump整库备份文件中恢复单表
  2. 【已解决】applicationContext.xml cannot be opened because it does not exist
  3. 6.22打包建立ISS虚拟目录,安装完运行你想运行的程序
  4. SQL Server 2000/2005 数据库分页
  5. Servlet异步处理性能优化的过程
  6. VB6获取本机所有IP地址公用函数
  7. [转]文件的操作方式
  8. 学完 Fluent 官方基础教程,你离一名合格Fluent 流体工程师还有多远?
  9. 『Others』WPS广告关闭
  10. vivado simulation仿真(38译码器实现)
  11. 远程控制计算机开关机
  12. 如何创建一个基本的魔兽全图外挂 HowTo create a basic Maphack by Chaotic
  13. 弧长积分公式的证明_20160414
  14. 互联网大佬打脸啪啪啪啪史
  15. IP地址 网关是什么?网络概念
  16. C语言编程:三(n)子棋游戏
  17. [ASP.NET MVC 小牛之路]02 - C#知识点提要
  18. registry拉取dockerhub私有镜像
  19. 2012年中国各省市区GDP排行榜 附各主要城市GDP排行榜
  20. 肿瘤免疫新抗原鉴定(一)OptiType安装与运行

热门文章

  1. powershell ip_如何使用PowerShell更改IP地址
  2. GIS应用水平考试2009年度第一次全国统一考试
  3. 6款CSS特效边框样式
  4. Amesim学习——弹球仿真
  5. Typora插入图片问题
  6. 三维管型ybc预览以及动态成型仿真控件
  7. uni.navigateTo失效
  8. 去马赛克 Demosaic
  9. qduoj 分辣条2
  10. java blockingqueue_Java BlockingQueue take()用法及代码示例