zoukankan      html  css  js  c++  java
  • Spring 实战-第四章-4.3 使用注解引入新方法 Introductions&@DeclareParents

    @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);
                }
            }
        }
    
        @Override
        public 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 {
        @Override
        public 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/aop
                http://www.springframework.org/schema/aop/spring-aop.xsd
                http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.springframework.org/schema/context
                http://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("
    cast to Printer
    ");
            ((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 Hole
    
    cast to Printer
    
    print CD cover...null
  • 相关阅读:
    js遍历Object所有属性
    使用JAVA开发微信公众平台(一)——环境搭建与开发接入
    使用Vue.js实现列表选中效果
    c#以POST方式模拟提交表单
    vue项目里的日期格式化
    Hadoop概念学习系列之Hadoop、Spark学习路线(很值得推荐)
    CentOS下的Mysql的安装和使用
    CentOS中zip压缩和unzip解压缩命令详解
    vue路由跳转传参数
    Linux上安装Hadoop集群(CentOS7+hadoop-2.8.0)
  • 原文地址:https://www.cnblogs.com/lvjianwei/p/7729207.html
Copyright © 2011-2022 走看看