1. 程式人生 > >Spring 實戰-第四章-4.4 使用xml中聲明切面及引入新方法

Spring 實戰-第四章-4.4 使用xml中聲明切面及引入新方法

cati sys epp proc oca cover tor ring tex

當不能直接接觸源碼時,同樣的不能給源碼增加註解,這時可以使用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中聲明切面及引入新方法