目录
Spring-AOP学习之(二)
/    

Spring-AOP学习之(二)

基于注解方式实现AOP以及例子

基于xml实现

切入点表达式: 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 + "测试"
        }
    }
    

K5LulQ.png

K5LnSg.png

K5LVFf.png

基于注解实现

K5XMaq.png

  • 定义切入点表达式

K5Xdd1.png

  • 引用切入点表达式

‘value = ‘ 可以省略

K5X4FP.png

例子 -- xml + 注解

  • 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();
        }
    }
    
    

标题:Spring-AOP学习之(二)
作者:gitsilence
地址:https://blog.lacknb.cn/articles/2019/10/31/1577974159491.html