 gitsilence 的个人博客
                gitsilence 的个人博客
            
基于注解方式实现AOP以及例子
切入点表达式: execution (返回值类型 全限定方法名 方法是否含参数)
<aop:after-returning method="afterReturning" pointcut-ref="mycut" returning="res"/>
public void afterReturning(Object res){
    System.out.println("这是目标方法执行后的返回值" + res);
}
修改目标方法的返回值 - -环绕通知
public Object around(ProceedingJoinPoint pjp) throw Throwable{
    // 执行目标方法 并获取返回值proceed
    Object proceed = pjp.proceed();
    // 修改返回结果
    if (proceed != null){
         return proceed + "测试"
    }
}






‘value = ‘ 可以省略

MyAspect.java
package cn.lacknb.aspect;
/*
* 切面类
* 在此类中编写各种类型的通知
* */
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Aspect
// 这里的 Component如果不写, 增强方法会不执行
@Component
public class MyAspect {
    /*
    * 前置通知
    * 使用JoinPoint接口作为参数获得目标对象信息
    * */
    @Before(value = "execution(* cn.lacknb.dao.TestDaoImpl.save())")
    public void before(JoinPoint jp){
        System.out.println("前置通知: 执行保存");
        System.out.println("目标对象: " + jp.getTarget()
        + "被增强处理的方法:" + jp.getSignature().getName());
    }
    /*
    * 后置返回通知
    * */
    // 引用 切入点表达式
    @AfterReturning("doAll()")
    public void afterReturning(JoinPoint jp){
        System.out.println("后置返回通知:" + " 模拟删除临时文件");
        System.out.println("被增强处理的方法: " + jp.getSignature().getName());
    }
    // 这里的value要与 接收的参数名保持一致
    @AfterReturning(value = "doAll()", returning = "value")
    public void afterReturning2(Object value){
        System.out.println("获取的值为: " + value);
    }
    // 配置 切入点表达式
    @Pointcut("execution(* cn.lacknb.dao.TestDaoImpl.*())")
    public void doAll(){}
    /*
    * 环绕通知
    * */
    @Around("execution(* cn.lacknb.dao.TestDaoImpl.modifyValue())")
    public Object around(ProceedingJoinPoint pjp) throws Throwable{
        System.out.println("环绕开始: 执行目标方法之前");
        // 执行目标方法, 获取返回值
        Object obj = pjp.proceed();
        System.out.println("环绕结束: 执行目标方法之后");
        if (obj != null){
            obj = obj.toString().toUpperCase();
        }
        return obj;
    }
    /*
    * 异常通知
    * */
    @AfterThrowing(value = "doAll()", throwing = "e")
    public void except(Throwable e){
        System.out.println("异常通知: " + "程序执行异常" + e.getMessage());
    }
    /*
    * 后置最终通知
    * */
    @After("doAll()")
    public void after(){
        System.out.println("(无论是否异常,都会执行这个方法)最终通知: 模拟释放资源");
    }
}
TestDao.java
package cn.lacknb.dao;
public interface TestDao {
    public void save();
    public void modify();
    public void delete();
    String returnValue();
    String modifyValue();
    void except() throws Exception;
}
TestDaoImpl.java
package cn.lacknb.dao;
import org.springframework.stereotype.Component;
@Component("testDao")
public class TestDaoImpl implements TestDao {
    public void save() {
        System.out.println("保存");
    }
    public void modify() {
        System.out.println("修改");
    }
    public void delete() {
        System.out.println("删除");
    }
    public String returnValue() {
        return "截取目标方法的返回值";
    }
    public String modifyValue(){
        return "lowcasetouppercase";
    }
    public void except() throws Exception{
        int num = 1;
//        num = 4 / 0;
        System.out.println("except方法执行: " + num);
    }
}
applicationContext.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"
       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">
<!--       扫描指定包下的所有的类 -->
    <context:component-scan base-package="cn.lacknb"/>
<!--设置切面自动扫描代理-->
    <aop:aspectj-autoproxy/>
</beans>
MyTest.java
package cn.lacknb.test;
import cn.lacknb.dao.TestDao;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
    ApplicationContext context = null;
    @Before
    public void before(){
        context = new ClassPathXmlApplicationContext("applicationContext.xml");
    }
    @Test
    public void test01() throws Throwable {
        TestDao test = (TestDao) context.getBean("testDao");
        test.save();
        test.delete();
        test.modify();
        System.out.println(test.returnValue());
        System.out.println(test.modifyValue());
        test.except();
    }
}