Spring AOP学习笔记(一)-AOP相关概念和基于注解方式实现AOP的规则

一、 Spring AOP 概念

其实AOP就是要将我们Aspect中的Pointcut和Target Object中的JointPoint动态的连接起来,同时我们通过Advice指明Pointcut执行的一个时机。这是个人理解
AOP相关名词解释

名词解释
Ascpect横跨多个类的模块化关注点
Pointcut指明Aspect和哪个连接点进行连接
AdviceAdvice是单一横切关注点的逻辑的载体,他代表将会织入到JointPoint的横切逻辑;也可以说是Aspect的具体的方法
Target ObjectAspect关注的对象
Joint Point表示目标对象执行的方法

Advice 的分类

Adice种类解释
Before Advice在Joint Point(执行方法)之前执行Pointcut方法)
After return Advice在 Joint Point(执行方法)正常退出时执行Pointcut
After throwing Advice在Joint Point(执行方法)抛出异常退出时执行Pointcut
After Advice在Joint Point(执行方法)退出(不管是正常退出还是抛异常退出)时执行Pointcut
Around Advice在Joint Point(执行方法)被调用之前和之后都会执行Pointcut

二、注解的方式声明一个切面

2.1、切面中涉及的注解
注解声明地点使用方式
@Aspect声明在类上表明这时一个Aspect
@Pointcut声明在Pointcut(Aspect的方法)上指明和哪个Target Object 的Joint Point进行连接
@Before声明注解在Aspect的方法上表明在Joint Point(执行方法)之前执行Aspect的方法
@AfterReturning声明注解在Aspect的方法上表明在 Joint Point(执行方法)正常退出时执行Aspect的方法
@AfterThrowing声明注解在Aspect的方法上表明在Joint Point(执行方法)抛出异常退出时执行执行Aspect的方法
@After声明注解在Aspect的方法上表明在Joint Point(执行方法)被调用之前和之后都会执行执行Aspect的方法
2.2、声明一个Aspect
package com.zbt.day03;

import org.aspectj.lang.annotation.*;

@Aspect
public class AfterThrowingAspect {
}

在Spring上下文中配置Bean注入,因为Aspect也是一个类,需要使用注入的方式让Spring管理一个Bean

<aop:aspectj-autoproxy/>//开启Spring AOP自动代理功能
<bean id="audience" class="com.zbt.day01.Audience"></bean>

因为使用@AspectJ表示我们已经放弃了自动代理(auto-proxy)的方式,因此我们需要使用注解的方式@Component或者在Spring上下文中配置自动代理。

2.3、切点表达式
方法描述
execution(public * *(..))执行那些方法为public的Joint Point
execution(* set*(..))执行那些方法名为set的Joint Point
execution(* com.xyz.service.AccountService.*(..))执行com.xyz.service.AccountService中所有的JointPoint(方法)
execution(* com.xyz.service.* . *(..)执行com.xyz.service包中任何的JointPoint(方法)
execution(* com.xyz.service..* . *(..))执行com.xyz.service..* . *(..))包和其子包下面所有的JointPoint(方法)
within(com.xyz.service.*)执行所有在com.xyz.service包中所有的JointPoint(方法)
this(com.xyz.service.AccountService)
target(com.xyz.service.AccoutnService)执行实现了com.xyz.service.AccoutnService接口的所有的类的JointPoint(方法)
args(java.io.Serializable)执行任何链接点参数只有一个,且指定参数类型为运行时Serializable(我们可以指定任意参数类型,只要是我们需要的)
@target(org.springframework.transaction.annotation.Transactional)执行目标对象注解了@Transaction注解的方法
bean(tradeService)
bean(*Service)
2.4、声明一个Advice

@Before

    @Before("execution(* com.zbt.day03.ThrowExceptionApp.division(..))")
    public void beforeJointPoint(){
        System.out.println("在Joint Point执行前执行此方法");
    }

@AfterThrowing

    @AfterThrowing("execution(* com.zbt.day03.ThrowExceptionApp.division(..))")
    public void printAbonormal(){
        System.out.println("在Joint Point抛出异常后执行此方法");
    }

@AfterReturning

    @AfterReturning("execution(* com.zbt.day03.ThrowExceptionApp.division(..))")
    public void printNormal(){
        System.out.println("在Joint Point正常退出执行此方法");
    }

@After

    @After("execution(* com.zbt.day03.ThrowExceptionApp.division(..))")
    public void print(){
        System.out.println("不管Joint Point是正常退出还是异常退出都执行此方法");
    }

@Round

示例
编写Aspect和Advice

package com.zbt.day03;

import org.aspectj.lang.annotation.*;

@Aspect
public class AfterThrowingAspect {
    @Before("execution(* com.zbt.day03.ThrowExceptionApp.division(..))")
    public void beforeJointPoint(){
        System.out.println("在Joint Point执行前执行此方法");
    }
    @AfterThrowing("execution(* com.zbt.day03.ThrowExceptionApp.division(..))")
    public void printAbonormal(){
        System.out.println("在Joint Point抛出异常后执行此方法");
    }
    @AfterReturning("execution(* com.zbt.day03.ThrowExceptionApp.division(..))")
    public void printNormal(){
        System.out.println("在Joint Point正常退出执行此方法");
    }
    @After("execution(* com.zbt.day03.ThrowExceptionApp.division(..))")
    public void print(){
        System.out.println("不管Joint Point是正常退出还是异常退出都执行此方法");
    }
}

编写Target Object和Joint Point(Target 中的方法)

package com.zbt.day03;

/**
 * Created by luckyboy on 2018/8/15.
 */
public class ThrowExceptionApp {
    public int division(int a,int b){
        int i = 0;
        try{
           i =  a/b;
        }catch (Exception e){
            throw e;
        }
        return i;
    }
}

代码测试

package com.zbt.day03;

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

public class TestAdvice {
    @Test
    public void testPerformance(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationConfig.xml");
        ThrowExceptionApp throwExceptionApp = context.getBean("throwExceptionApp",ThrowExceptionApp.class);
        throwExceptionApp.division(1,1);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值