1. 程式人生 > >Spring-AOP @AspectJ進階之命名切點

Spring-AOP @AspectJ進階之命名切點

概述

在前面所舉的例子中,比如

@Before("within(com.xgj.aop.spring.advisor.aspectJAdvance.pointcutComplex.*)"
            + " && execution(* greetTo(..))")
    public void matchGreetTo() {
        System.out.println("matchGreetTo executed,some logic is here ");
    }

切點直接宣告在增強方法處,這種切點宣告方式稱為匿名切點,匿名切點只能在宣告處使用。

如果希望在其它地方重用一個切點,我們可以通過@Pointcut註解以及切面類方法對切點進行命名

示例

package com.xgj.aop.spring.advisor.aspectJAdvance.namePoint;

import org.aspectj.lang.annotation.Pointcut;

/**
 * 
 * 
 * @ClassName: NamePoint
 * 
 * @Description: 如果希望在其它地方重用一個切點,我們可以通過@Pointcut註解以及切面類方法對切點進行命名
 * 
 * @author: Mr.Yang
 * 
 * @date
: 2017年9月10日 下午11:13:45 */
public class NamePoint{ /** * * * @Title: inPackage * * @Description: 通過註解方法inPackage()對該切點進行命名,方法可視域 * 修飾符為private,表明該命名切點只能在本切面類中使用。 * * * @return: void */ @Pointcut("within(com.xgj.aop.spring.advisor.aspectJAdvance.namePoint)"
) private void inPackage() { }; /** * * * @Title: greetTo * * @Description: 通過註解方法greetTo()對該切點進行命名,方法可視域 * 修飾符為protected,表明該命名切點可以在當前包中的切面 類、子切面類中中使用。 * * * @return: void */ @Pointcut("execution(* greetTo(..))") protected void greetTo() { } /** * * * @Title: inPkgGreetTo * * @Description: 引用命名切點定義的切點,本切點也是命名切點, 它對應的可視域為public * * * @return: void */ @Pointcut("inPackage() and greetTo()") public void inPkgGreetTo() { } }

上面上述示例中定義了3個命名切點,命名切點的使用類方法作為切點的名稱,此外方法的訪問修飾符還控制了切點的可引用性,這種可引用性和類方法的可訪問性相同,如private的切點只能在本類中引用,public的切點可以在任何類中引用。

命名切點僅利用方法名及訪問修飾符的資訊,所以習慣上,方法的返回型別為void,並且方法體為空。

我們可以通過下圖更直觀地瞭解命名切點的結構:

這裡寫圖片描述

inPkgGreetTo()的切點引用了同類中的greetTo()切點,而inPkgGreetTo()切點可以被任何類引用。

你還可以擴充套件NamePoint類,通過類的繼承關係定義更多的切點。 命名切點定義好後,就可以在定義切面時通過名稱引用切點.

來看個示例

這裡寫圖片描述

假設有兩個業務類

package com.xgj.aop.spring.advisor.aspectJAdvance.namePoint;

import org.springframework.stereotype.Component;

/**
 * 
 * 
 * @ClassName: NaiveWaiter
 * 
 * @Description: @Component註解標註的bean
 * 
 * @author: Mr.Yang
 * 
 * @date: 2017年9月10日 下午11:55:00
 */

@Component
public class NaiveWaiter {

    public void greetTo(String clientName) {
        System.out.println("NaiveWaiter greetTo " + clientName);
    }

    public void serverTo(String clientName) {
        System.out.println("NaiveWaiter serverTo " + clientName);
    }
}
package com.xgj.aop.spring.advisor.aspectJAdvance.namePoint;

import org.springframework.stereotype.Component;

@Component
public class CuteWaiter {
    public void greetTo(String clientName) {
        System.out.println("CuteWaiter greetTo " + clientName);
    }

    public void serverTo(String clientName) {
        System.out.println("CuteWaiter serverTo " + clientName);
    }
}

切點命名複用上面那個切點,然後編寫切面NamePointAspect

package com.xgj.aop.spring.advisor.aspectJAdvance.namePoint;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;

/**
 * 
 * 
 * @ClassName: NamePointTest
 * 
 * @Description: 使用@Aspect註解標註的切面,演示命名切點的使用
 * 
 * @author: Mr.Yang
 * 
 * @date: 2017年9月10日 下午11:42:39
 */

@Aspect
public class NamePointAspect {
    /**
     * 
     * 
     * @Title: pkgGreetTo
     * 
     * @Description: 引用了NamePoint.inPkgGreetTo()切點
     * 
     * 
     * @return: void
     */
    @AfterReturning("NamePoint.inPkgGreetTo()")
    public void pkgGreetTo() {
        System.out.println("pkgGreetTo exectued ,some logic is here ");
    }

    /**
     * 
     * 
     * @Title: pkgGreetToNotNaiveWaiter
     * 
     * @Description: 在複合運算中使用了命名切點
     * 
     * 
     * @return: void
     */
    @AfterReturning("!target(com.xgj.aop.spring.advisor.aspectJAdvance.namePoint.NaiveWaiter) && NamePoint.inPkgGreetTo()")
    public void pkgGreetToNotNaiveWaiter() {
        System.out
                .println("pkgGreetToNotNaiveWaiter() executed,some logic is here");
    }
}

配置檔案如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    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
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd">

<!-- (1)宣告Context名稱空間以及Schema檔案   (2)掃描類包以及應用註解定義的bean -->
<context:component-scan base-package="com.xgj.aop.spring.advisor.aspectJAdvance.namePoint"/>

<!-- 基於@AspectJ切面的驅動器 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>

<!-- 使用了@AspectJ註解的切面類 -->
<bean class="com.xgj.aop.spring.advisor.aspectJAdvance.namePoint.NamePointAspect"/>

</beans>

測試類

package com.xgj.aop.spring.advisor.aspectJAdvance.namePoint;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 
 * 
 * @ClassName: NamePointAspectTest
 * 
 * @Description: 命名切點測試類
 * 
 * @author: Mr.Yang
 * 
 * @date: 2017年9月10日 下午11:56:50
 */

public class NamePointAspectTest {

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext(
                "classpath:com/xgj/aop/spring/advisor/aspectJAdvance/namePoint/conf-namePoint.xml");

        CuteWaiter cuteWaiter = ctx.getBean("cuteWaiter", CuteWaiter.class);
        NaiveWaiter naiveWaiter = ctx.getBean("naiveWaiter", NaiveWaiter.class);

        naiveWaiter.greetTo("XiaoGongJiang");
        System.out.println("================");

        cuteWaiter.greetTo("XiaoGongJiang");
        System.out.println("================");

        naiveWaiter.serverTo("XiaoGongJiang");
        System.out.println("================");

        cuteWaiter.serverTo("XiaoGongJiang");
    }
}

執行結果

2017-09-11 00:58:34,752  INFO [main] (AbstractApplicationContext.java:583) - Refreshing org[email protected]4888884e: startup date [Mon Sep 11 00:58:34 BOT 2017]; root of context hierarchy
2017-09-11 00:58:34,821  INFO [main] (XmlBeanDefinitionReader.java:317) - Loading XML bean definitions from class path resource [com/xgj/aop/spring/advisor/aspectJAdvance/namePoint/conf-namePoint.xml]
NaiveWaiter greetTo XiaoGongJiang
pkgGreetTo exectued ,some logic is here 
================
CuteWaiter greetTo XiaoGongJiang
pkgGreetTo exectued ,some logic is here 
pkgGreetToNotNaiveWaiter() executed,some logic is here
================
NaiveWaiter serverTo XiaoGongJiang
pkgGreetTo exectued ,some logic is here 
================
CuteWaiter serverTo XiaoGongJiang
pkgGreetTo exectued ,some logic is here 
pkgGreetToNotNaiveWaiter() executed,some logic is here

可以看到NaiveWaiter greetTo 方法 沒有織入第二個增強。

相關推薦

Spring-AOP @AspectJ命名切點

概述 示例 概述 在前面所舉的例子中,比如 @Before("within(com.xgj.aop.spring.advisor.aspectJAdvance.pointcutComplex.*)" + " &a

Spring-AOP @AspectJ繫結類註解物件

概述 例項 概述 @within()和@target()函式可以將目標類的註解物件繫結到增強方法中。 我們通過@within()演示註解繫結的操作 例項 註

Spring-AOP @AspectJ繫結丟擲的異常

概述 例項 總結 概述 和通過切點函式繫結連線點資訊不同,連線點丟擲的異常必須使用AfterThrowing註解的throwing成員進行繫結 例項 業務類 p

Spring-AOP @AspectJ繫結連線點方法入參

概述 例項 概述 我們前面的博文在講解切點函式時說過args()、this()、target()、@args()、@within()、@target()和@annotation()這

Spring-AOP @AspectJ增強織入的順序

概述 示例 概述 一個連線點可以同時匹配多個切點,切點對應的增強在連線點上的織入順序到底是如何安排呢?這個問題需要分三種情況討論: 如果增強在同一個切面類中宣告,則依照增強在切

spring ioc---DI雜項(idref標籤;複合屬性;懶載入)

雜項 說明 idref標籤 注入的是容器中例項bean的id值,型別是java.lang.String,而非bean例項! attr1.attr2.attr3 採用巢狀屬性的方式,可直接設

spring ioc---DI方法的注入和替換

方法注入解決的需求: 若bean A依賴bean B,在兩者生命週期不同的情況下,若bean A每次使用bean B的例項的時候,都需要擁有不同狀態的bean B的例項的話,就需要使用方法注入的功能,來實現此需求.(需要使用cglib技術)

spring ioc---DI自動裝配

模式 說明 no/default (Default) No autowiring. Bean references must be defined via a ref element. Changing the default

spring ioc---DI引入依賴關係不明顯的bean

1,需要在bean標籤中使用屬性`depends-on`. 簡言之,在使用bean之前,被標註的依賴bean要先於初始化.雖然兩個bean之間的依賴關係不是清晰明顯且直接的. 官方xsd中關於depends-on的說明 文件地址:http://www.springframework.

spring ioc---DI引入其他bean

官方xsd文件中關於ref的參考說明 原文連結:http://www.springframework.org/schema/beans/spring-beans.xsd 1.標籤ref: Defines a reference to another bean in this fact

spring ioc---DI集合和特殊值的處理

DI進階之集合的使用 集合 使用 list連結串列容器 使用list和value標籤 set無序容器 使用set和value標籤 map鍵值對

Spring入門(十一):Spring AOP使用

在上篇部落格中,我們瞭解了什麼是AOP以及在Spring中如何使用AOP,本篇部落格繼續深入講解下AOP的高階用法。 1. 宣告帶引數的切點 假設我們有一個介面CompactDisc和它的實現類BlankDisc: package chapter04.soundsystem; /** * 光碟 */ p

Spring AOP AspectJ切入點語法詳解 @AspectJ

AspectJ切入點語法詳解 此文章來源於網路,版權不歸本人所有。本人結合起來 1.Spring AOP @Before @Around @After 等 advice 的執行順序    @Around/**ProceedingJo

Spring-AOP @AspectJ切點函式args()和@args()

概述 args args 例項 args args 概述 args函式的入參是類名, 而 @args()的入參必須是註解類的類名。 雖然args()允許在類名後使用“+”萬用字元,但該萬用字元在此處沒有意義,新增和不新增的效果都一樣。

Spring-AOP @AspectJ切點函式@annotation()

@annotation()概述 @annotation表示標註了某個註解的所有方法。 下面通過一個例項說明@annotation()的用法。 AnnotationTestAspect

Spring路(10)-Advice簡介以及通過cglib生成AOP代理物件

Advice簡介 1. Before:在目標方法執行之前執行織入,如果Before的處理中沒有進行特殊的處理,那麼目標方法最終會執行,但是如果想要阻止目標方法執行時,可以通過丟擲一個異常來實現,Be

【SSH路】Struts + Spring + Hibernate 開端(一)

height 一段 ioc 效率 陽光大道 面向對象的思想 text ase 們的 Long Long ago。就聽說過SSH。起初還以為是一個東東,詳細內容更是不詳,總認為高端大氣上檔次,經過學習之後才發現,不不過高大上,更是低調奢華有內涵,經過一段時間的

C#AOP

com aop uid spa amp ace 進階 c# php http://pic.cnhubei.com/space.php?uid=4614&do=album&id=1349648http://pic.cnhubei.com/space.php?u

Spring Boot Web 學習 - 單元測試

自動生成 添加 學習 one 類文件 dma AC mock ring 可在類文件中,右鍵->GO TO->Test 自動生成測試文件 1.添加測試註解 簡單方法測試 @RunWith(SpringRunner.class)@SpringBootTes

Spring Cloud 路 -- 訊息匯流排 Spring Cloud Bus 配置手動重新整理和動態自動重新整理

Spring Cloud Bus 配置步驟: 1、Spring Cloud Config 專案引入依賴,新增配置,配置暴露 endpoints 2、啟動Config 專案,註冊到Eureka,自動新增RabbitMQ佇列 3、客戶端的order應用引入依賴及配置,啟動Con