Spring 实战-第四章-4.4 使用xml中声明切面及引入新方法

Posted Lv Jianwei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring 实战-第四章-4.4 使用xml中声明切面及引入新方法相关的知识,希望对你有一定的参考价值。

当不能直接接触源码时,同样的不能给源码增加注解,这时可以使用xml的方式声明切面并引入新方法

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));
    }


}

TrackCounter方法(无注解)

package main.java.soundsystem;

import java.util.HashMap;
import java.util.Map;

public class TrackCounter {
    private Map<Integer, Integer> trackCounts =
            new HashMap<Integer, Integer>();

    public void trackPlayed(int trackNumber) {

    }

    public void countTrack(int trackNumber) {
        int currentCount = getPlayCount(trackNumber);
        System.out.println("Track:" + trackNumber);
        trackCounts.put(trackNumber, currentCount + 1);
    }

    public void PrintMap() {
        trackCounts.forEach((k, v) -> System.out.println("Key:" + k + ",Value:" + v));
    }

    public int getPlayCount(int trackNumber) {
        return trackCounts.containsKey(trackNumber) ? trackCounts.get(trackNumber) : 0;
    }
}

xml配置文件声明切面

<?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="trackCounter|" class="main.java.soundsystem.TrackCounter"/>
    <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>

    <aop:config>
        <aop:aspect ref="trackCounter|">
            <aop:pointcut id="trackPlayed" expression=
                    "execution(* main.java.soundsystem.CompactDisc.playTrack(Integer))
                        and args(trackNumber)" />
            <aop:before pointcut-ref="trackPlayed" method="countTrack"/>
        </aop:aspect>
        
</beans>

测试:

package main.java.soundsystem;
import org.springframework.beans.factory.annotation.Autowired;

import static org.junit.Assert.*;

import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath*:/TrackCounterConfig.xml")

public class TrackCounterTest {

    @Autowired
    private CompactDisc cd;

    @Autowired
    private TrackCounter counter;

    @Test
    public void testTrackCounter(){

        cd.playTrack(1);
        cd.playTrack(1);
        cd.playTrack(3);
        cd.playTrack(4);
        cd.playTrack(4);
        cd.playTrack(4);

        assertEquals(2,counter.getPlayCount(1));
        assertEquals(1,counter.getPlayCount(3));
        assertEquals(3,counter.getPlayCount(4));
    }
}

测试输出:

Track:1
Playing Sgt. Pepper‘s Lonely Hearts Club Band
Track:1
Playing Sgt. Pepper‘s Lonely Hearts Club Band
Track:3
Playing Lucy in the Sky with Diamonds
Track:4
Playing Getting Better
Track:4
Playing Getting Better
Track:4
Playing Getting Better

Process finished with exit code 0

 

Printer接口

package main.java.soundsystem;

public interface Printer {
    void printCover();
}

CDPrinter类实现Printer接口

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;
}

xml配置中增加配置,为CompactDisc接口的类引入新的父类,在aop:config配置节中增加一个切面

其中

 types-matching:要给哪个接口增加新的父类,

implement-interface:新增父类

default-impl:新增父类的默认实现

<aop:aspect>
  <aop:declare-parents
    types-matching="main.java.soundsystem.CompactDisc"
    implement-interface="main.java.soundsystem.Printer"
    default-impl="main.java.soundsystem.CDPrinter"/>
</aop:aspect>

增加测试方法:

@Test
    public void testPrinter()
    {
        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 Hole

cast to Printer

print CD cover...null

Process finished with exit code 0

 

以上是关于Spring 实战-第四章-4.4 使用xml中声明切面及引入新方法的主要内容,如果未能解决你的问题,请参考以下文章

Spring实战

报错spring实战(第四版)示例代码 ,使用 @DeclareParents 实现aop出错

SPRING IN ACTION 第4版笔记-第四章ASPECT-ORIENTED SPRING-006-定义切面使用xml

Spring实战第四章

Spring 实战-第四章-4.3 Introductions&@DeclareParents

4类Storage方案(AS开发实战第四章学习笔记)