淺談java切面

一芭逝、切面定義

切面 = 切點(diǎn)+通知

  • 切點(diǎn)(pointcut): 定義執(zhí)行切面的入口點(diǎn) ,這里切入點(diǎn)指示符

  • 通知:interceptor實(shí)現(xiàn)切面邏輯

二巍棱、切入點(diǎn)指示符的含義及使用(execution遗契、within、this行剂、target等)

  • execution:用于匹配方法執(zhí)行的連接點(diǎn) execution(* com.test.method.des...(..))
  • execution() 表達(dá)式的主體
  • 第一個(gè)“*”符號(hào) 表示返回值的類型任意
  • com.test.method.des AOP所切的服務(wù)的包名秕噪,即,需要進(jìn)行橫切的業(yè)務(wù)類
  • 包名后面的“..” 表示當(dāng)前包及子包
  • 第二個(gè)“” 表示類名厚宰,即所有類
  • .*(..) 表示任何方法名腌巾,括號(hào)表示參數(shù),兩個(gè)點(diǎn)表示任何參數(shù)類型
  • within:用于匹配指定類型內(nèi)的方法執(zhí)行,within比較嚴(yán)格铲觉,它是嚴(yán)格匹配被代理對(duì)象類型的澈蝙,不會(huì)理會(huì)繼承關(guān)系,例如A繼承了接口B撵幽,則within("B")不會(huì)匹配到A灯荧,但是within("B+")可以匹配到A
  • within(cn.java..*) . cn.java包及子包下的任何方法執(zhí)行
  • within(java..IPointcutService+) . java包或所有子包下IPointcutService類型及子類型的任何方法
  • within(@cn..Secure *) 持有cn..Secure注解的任何類型的任何方法
  • target:用于匹配當(dāng)前目標(biāo)對(duì)象類型的執(zhí)行方法;注意是目標(biāo)對(duì)象的類型匹配 盐杂, 例如A繼承了B接口逗载,則使用target("B"),target("A")均可以匹配到A链烈, 我們pointcut 所選取的Join point 的所有者厉斟,直白點(diǎn)說就是: 指明攔截的方法屬于那個(gè)類。
  • this:用于匹配當(dāng)前AOP代理對(duì)象類型的執(zhí)行方法测垛,注意是AOP代理對(duì)象的類型匹配捏膨, 我們pointcut 所選取的Join point 的調(diào)用的所有者,就是說:方法是在那個(gè)類中被調(diào)食侮。

三号涯、切面應(yīng)用實(shí)例

/**
 * 定義日志注解
 */

package test.anotation;

import java.lang.annotation.*;

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface Log {
    String desc() default "打印日志";
}


/**
 * 定義日志切面
 */


package test.aspect;


import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import test.anotation.Log;

import java.lang.reflect.Method;

import java.util.Arrays;
import java.util.List;

@Aspect
@Component
public class LogAspect {

    /**
     * 標(biāo)注該方法體為后置通知,當(dāng)目標(biāo)方法執(zhí)行成功后執(zhí)行該方法體
     */
    @AfterReturning("within(test..*) && @annotation(rl)")
    public void addLogSuccess(JoinPoint jp, Log rl){
        Object[] parames = jp.getArgs();//獲取目標(biāo)方法體參數(shù)
        for (int i = 0; i < parames.length; i++) {
            System.out.println(parames[i]);
        }
        System.out.println(jp.getSignature().getName());
        String className = jp.getTarget().getClass().toString();//獲取目標(biāo)類名
        System.out.println("className:" + className);
        className = className.substring(className.indexOf("test"));
        String signature = jp.getSignature().toString();//獲取目標(biāo)方法簽名
        System.out.println("signature:" + signature);
        System.out.println(rl.desc());
    }

    @Pointcut("@annotation(test.anotation.Log)")
    public void serviceMethodPointcut() {
       //切點(diǎn)
    }

    /**
     * 前置通知方法, 匹配test包下所有類的方法
     * 方法的返回值 和 test包下所有的類和方法锯七,以及方法的形參 都抽象了
     * @param point
     * @return
     * @throws Throwable
     */
    @Before("execution(* test..*(..))")
    public void beforeAdvice(JoinPoint point){
        String methodName = point.getSignature().getName();
        List<Object> args = Arrays.asList(point.getArgs());
        System.out.println("@Before 前置通知 : 方法名 【 " + methodName + " 】and args are " + args);

    }

    /**
     * 環(huán)繞通知链快, 注解切點(diǎn)匹配
     * @param pjp
     * @return
     * @throws Throwable
     */
    @Around("serviceMethodPointcut()")
    public Object interceptor(ProceedingJoinPoint pjp) throws Throwable {
        //通知方法
        String className = pjp.getTarget().getClass().toString();//獲取目標(biāo)類名
        System.out.println("className:" + className);

        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        String methodName = method.getName();

        System.out.println("methodName:" + methodName);

        return pjp.proceed();
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市眉尸,隨后出現(xiàn)的幾起案子域蜗,更是在濱河造成了極大的恐慌巨双,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件霉祸,死亡現(xiàn)場(chǎng)離奇詭異筑累,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)丝蹭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門慢宗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人奔穿,你說我怎么就攤上這事镜沽。” “怎么了贱田?”我有些...
    開封第一講書人閱讀 164,704評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵缅茉,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我男摧,道長(zhǎng)蔬墩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,702評(píng)論 1 294
  • 正文 為了忘掉前任彩倚,我火速辦了婚禮筹我,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘帆离。我一直安慰自己,他們只是感情好结澄,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評(píng)論 6 392
  • 文/花漫 我一把揭開白布哥谷。 她就那樣靜靜地躺著,像睡著了一般麻献。 火紅的嫁衣襯著肌膚如雪们妥。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,573評(píng)論 1 305
  • 那天勉吻,我揣著相機(jī)與錄音监婶,去河邊找鬼。 笑死齿桃,一個(gè)胖子當(dāng)著我的面吹牛惑惶,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播短纵,決...
    沈念sama閱讀 40,314評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼带污,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了香到?” 一聲冷哼從身側(cè)響起鱼冀,我...
    開封第一講書人閱讀 39,230評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤报破,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后千绪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體充易,經(jīng)...
    沈念sama閱讀 45,680評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評(píng)論 3 336
  • 正文 我和宋清朗相戀三年荸型,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盹靴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,991評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡帆疟,死狀恐怖鹉究,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情踪宠,我是刑警寧澤自赔,帶...
    沈念sama閱讀 35,706評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站柳琢,受9級(jí)特大地震影響绍妨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜柬脸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評(píng)論 3 330
  • 文/蒙蒙 一他去、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧倒堕,春花似錦灾测、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至骤宣,卻和暖如春秦爆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背憔披。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評(píng)論 1 270
  • 我被黑心中介騙來泰國打工等限, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人芬膝。 一個(gè)月前我還...
    沈念sama閱讀 48,158評(píng)論 3 370
  • 正文 我出身青樓望门,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親蔗候。 傳聞我的和親對(duì)象是個(gè)殘疾皇子怒允,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評(píng)論 2 355