Spring實戰07——AOP切點表達式

  • Spring中通過切入點表達式定義具體切入點,其常用AOP切入點表達式定義 

指示符

作用

bean

用於匹配指定bean id的的方法執行

within

         

用於匹配指定包名下類型內的方法執行

@annotation

用於匹配指定註解修飾的方法執行

execution

用於進行細粒度方法匹配執行具體業務


 

  • bean

bean("userServiceImpl"))

指定一個類

bean("*ServiceImpl")

指定所有的後綴爲serviceImpl的類

 

  • within應用於類級別,實現粗粒度的切面表達式定義:

within("aop.service.UserServiceImpl")

指定類,只能指定一個類

within("aop.service.*")

只包括當前目錄下的類

within("aop.service..*")

指定當前目錄包含所有子目錄中的類

 

  •  execution方法級別,細粒度的控制:語法:execution(返回值類型 包名.類名.方法名(參數列表))

execution(void aop.service.UserServiceImpl.addUser())

匹配方法

execution(void aop.service.PersonServiceImpl.addUser(String))

方法參數必須爲字符串

execution(* aop.service..*.*(..))

萬能配置

 

  • @annotaion應用於方法級別,實現細粒度的控制:

@annotation(com..anno.RequestLog))

指定一個需要實現增強功能的方法


  •  execution 實例:專輯有多首歌,播放每首歌后會顯示這首歌的播放次數。

一.配置類實現

1.接口

package com.qhf.aop.example04;

public interface CD {
    void play(int i);
}

2.實現類:空白CD

package com.qhf.aop.example04;

import java.util.List;

public class BlankCD implements CD {
    private String title;//專輯名稱
    private String artist;//歌手
    private List<String> list;//歌曲

    public void setTitle(String title) {
        this.title = title;
    }

    public void setArtist(String artist) {
        this.artist = artist;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    @Override
    public void play(int i) {
        try {
            String song = list.get(i);
            System.out.print("Playing '" + song + "' by " + artist + "; ");
        } catch (Throwable e){
            System.out.print("拋異常; ");
            throw e;//必須拋出後纔會執行@AfterThrowing
        }
    }
}

3.配置類,bean實例化返回一個艾薇兒的專輯

package com.qhf.aop.example04;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

import java.util.ArrayList;
import java.util.List;

@Configuration
@EnableAspectJAutoProxy
public class AopConfig {

    @Bean
    public BlankCD avrilCD(){
        BlankCD b = new BlankCD();
        b.setArtist("avril");
        b.setTitle("Head above water");

        List<String> list = new ArrayList<>();
        list.add("Head above water");
        list.add("one");
        list.add("two");
        list.add("three");
        list.add("four");
        list.add("five");

        b.setList(list);

        return b;
    }

    @Bean
    public PlayTimes playTimes(){
        return new PlayTimes();
    }
}

4.切面類

@Pointcut("execution(* com.qhf.aop.example04.BlankCD.play(int)) && args(i)")

public void pointcut(int i){}

參數是int,故play(int)接受一個int 類型參數,&& args(i) 中指定參數名

package com.qhf.aop.example04;

import org.aspectj.lang.annotation.*;

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

@Aspect
public class PlayTimes {
    private Map<Integer, Integer> map = new HashMap<>();

    @Pointcut("execution(* com.qhf.aop.example04.BlankCD.play(int)) && args(i)")
    public void pointcut(int i){

    }
    /**
     * 這首歌播放次數
     * @param i
     */
    @AfterReturning("pointcut(i)")
    public void playTimes(int i){
        int count = getPlayCount(i) + 1;
        map.put(i, count);
        System.out.println("播放次數:" + count);
    }

    private int getPlayCount(int i){
        return map.containsKey(i)? map.get(i): 0;
    }

    @AfterThrowing("pointcut(i)")
    public void noSong(int i){
        System.out.println("沒有這首歌喲...");
    }
}

5.測試

package com.qhf.aop.example04;

import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AopConfig.class)
public class Test {

    @Autowired
    private CD avrilCD;

    @org.junit.Test
    public void test(){
        //只有6首歌,0號也有一首歌
        avrilCD.play(1);
        avrilCD.play(0);
        avrilCD.play(1);
        avrilCD.play(2);
        avrilCD.play(3);
        avrilCD.play(4);
        avrilCD.play(3);
        avrilCD.play(5);
        try {
            avrilCD.play(6);//沒有這首歌,暫時不知用什麼方法
        } catch (Throwable e){

        }
        avrilCD.play(1);
    }
}

6.運行結果

Playing 'one' by avril; 播放次數:1
Playing 'Head above water' by avril; 播放次數:1
Playing 'one' by avril; 播放次數:2
Playing 'two' by avril; 播放次數:1
Playing 'three' by avril; 播放次數:1
Playing 'four' by avril; 播放次數:1
Playing 'three' by avril; 播放次數:2
Playing 'five' by avril; 播放次數:1
拋異常; 沒有這首歌喲...
Playing 'one' by avril; 播放次數:3

 

二、xml配置實現

1.除了測試類和配置類,其他類全部除去註解

2.配置類

package com.qhf.aop.example05;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;

@Configuration
@ImportResource("classpath:aop/example05/aop.xml")
public class AopConfig {

}

3.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:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 啓動切面代理 -->
    <aop:aspectj-autoproxy/>

    <!-- 自動裝配bean -->
    <bean id="playTimes" class="com.qhf.aop.example05.PlayTimes"/>

    <bean id="blankCD" class="com.qhf.aop.example05.BlankCD">
        <property name="title" value="Head above water"></property>
        <property name="artist" value="avril"></property>
        <property name="list">
            <list>
                <value>Head above water</value>
                <value>one</value>
                <value>two</value>
                <value>three</value>
                <value>four</value>
                <value>five</value>
            </list>
        </property>
    </bean>

    <!-- 聲明切面 -->
    <aop:config>
        <aop:aspect ref="playTimes">

            <aop:pointcut id="point" expression="execution(* com.qhf.aop.example05.BlankCD.play(int)) and args(i)"/>
            <aop:after-returning method="playTimes" pointcut-ref="point"/>
            <aop:after-throwing method="noSong" pointcut-ref="point"/>

        </aop:aspect>
    </aop:config>

</beans>

4.測試結果相同

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章