sping揭秘14@before @AfterThrowing

Posted cutter_point

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sping揭秘14@before @AfterThrowing相关的知识,希望对你有一定的参考价值。

 

@before

基础模式,我们先直接看一下就可以了,比较简单,网上一堆。。。

不是我装逼哈,我学了那么久spring,aop的皮毛也就是网上的那些blog内容,稍微高级点的我也不会,这里跳过基础部分

 

 

 

不过有一点很重要,必须了解一波:

 

1、 测试被拦截的方法里面调用另一个同类被拦截方法

注意了:这个就只会被拦截一次,并不会拦截方法里面再次调用的那个方法,当然你直接在外围调用一次另一个方法,还是会被拦截

 

2、 测试被拦截的方法里面调用另一个不同类被拦截方法

 

注意了:这个就会被拦截两次,你调用的这个方法会被拦截一次,你调用的这个方法里面调用的那个方法,还会被拦截一次

 

这两问有个大前提,所有提及的方法都是被拦截对象,也就是说切入点包含以上使用到的方法

 

OK,讲完上面,好,重点这就来了,

 

 

 

我们想要知道被拦截的方法的参数是个什么情况,我们要怎么处理呢?

 

这里提出问题,我们着手解决一下这个问题

 

这里我们介绍一下joinpoint和args,前者可以通过getArgs方法获取参数,还有其他的一堆其他方法使用。后者是作为注解里面的一个标志符,可以直接声明相应的参数

 

我们建立一个bean

 

 

package cn.cutter.start.bean;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Component;

@Component
public class BeofreTestBean {
    
    private static final Log logger = LogFactory.getLog(BeofreTestBean.class);

    public void method1() {
        logger.info("这里是方法 method1");
    }
    
    public void method2(String param1) {
        logger.info("这里是方法 method2 参数值是:param1-" + param1);
    }
    
}

创建拦截类,对这个bean进行拦截

 

package cn.cutter.start.aop;

import java.lang.reflect.Modifier;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class BeforeAspect {
    
    private static final Log logger = LogFactory.getLog(BeforeAspect.class);
    
    @Pointcut("execution(* cn.cutter.start.bean.BeofreTestBean.*(..))")
    private void beforePointCut() {}
    
    /**
     * 直接前置拦截
     */
    @Before("beforePointCut()")
    public void beforeOpertatorNoArg() {
        logger.info("前置拦截不带参数  beforeOpertatorNoArg");
    }
    
    @Before("beforePointCut()")
    public void beforeOpertatorWithJoinPoint(JoinPoint joinPoint) {
        logger.info("前置拦截带参数  beforeOpertatorWithJoinPoint");
        
        logger.info("目标方法名为:" + joinPoint.getSignature().getName());
        logger.info("目标方法所属类的简单类名:" + joinPoint.getSignature().getDeclaringType().getSimpleName());
        logger.info("目标方法所属类的类名:" + joinPoint.getSignature().getDeclaringTypeName());
        logger.info("目标方法声明类型:" + Modifier.toString(joinPoint.getSignature().getModifiers()));
        //获取传入目标方法的参数
        Object[] args = joinPoint.getArgs();
        for (int i = 0; i < args.length; i++) {
            logger.info("第" + (i+1) + "个参数为:" + args[i]);
        }
        logger.info("被代理的对象:" + joinPoint.getTarget());
        logger.info("代理对象自己:" + joinPoint.getThis());
        
    }
    
    @Before("beforePointCut() && args(param1)")
    public void beforeOpertatorWithArg(String param1) {
        logger.info("前置拦截带参数  beforeOpertatorWithArg 参数是param1:" + param1);
    }
    
    @Before("beforePointCut() && args(param1)")
    public void beforeOpertatorWithArgAndJoinPoint(JoinPoint joinPoint, String param1) {
        logger.info("------------------------------------------------------------------------");
        logger.info("前置拦截带参数  beforeOpertatorWithArgAndJoinPoint 参数是param1:" + param1);
        
        logger.info("目标方法名为:" + joinPoint.getSignature().getName());
        logger.info("目标方法所属类的简单类名:" + joinPoint.getSignature().getDeclaringType().getSimpleName());
        logger.info("目标方法所属类的类名:" + joinPoint.getSignature().getDeclaringTypeName());
        logger.info("目标方法声明类型:" + Modifier.toString(joinPoint.getSignature().getModifiers()));
        //获取传入目标方法的参数
        Object[] args = joinPoint.getArgs();
        for (int i = 0; i < args.length; i++) {
            logger.info("第" + (i+1) + "个参数为:" + args[i]);
        }
        logger.info("被代理的对象:" + joinPoint.getTarget());
        logger.info("代理对象自己:" + joinPoint.getThis());
        
        logger.info("------------------------------------------------------------------------");
    }
    
}

查看结果:

 

 

    @Test
    public void testAop2() {
        ApplicationContext ctx = this.before();
        
        BeofreTestBean btb = (BeofreTestBean) ctx.getBean("beofreTestBean");
        
//        btb.method1();
        btb.method2("测试aop before");
        
    }

结果截图:

 

 

 

 

 

 

 

 

@AfterThrowing

 

这个注解有个独特的属性,那就是throwing

 

 

设计一个类,执行一个方法之后,抛出异常

 

 

package cn.cutter.start.bean;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Component;

@Component
public class AfterThrowingTestBean {
    private static final Log logger = LogFactory.getLog(AfterThrowingTestBean.class);
    
    public void throwingException() throws Exception {
        throw new Exception("测试异常抛出");
    }
    
}

 

设计拦截类

 

package cn.cutter.start.aop;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class AfterThrowingAspect {
    
    private static final Log logger = LogFactory.getLog(AfterThrowingAspect.class);
    
    @AfterThrowing(pointcut="execution(* cn.cutter.start.bean.AfterThrowingTestBean.*(..))", throwing="e")
    public void testAfterThrowing(Exception e) {
        logger.info("testAfterThrowing: " + e.getMessage());
        
        e.printStackTrace();
        
    }
    
}

测试结果:

 

@Test
    public void testAop3() {
        ApplicationContext ctx = this.before();
        
        AfterThrowingTestBean att = (AfterThrowingTestBean) ctx.getBean("afterThrowingTestBean");
        
        try {
            att.throwingException();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            System.out.println("抛出异常捕获");
        }
        
    }

结果:

 

以上是关于sping揭秘14@before @AfterThrowing的主要内容,如果未能解决你的问题,请参考以下文章

sping揭秘8容器内部事件发布

sping揭秘12SpringAOP的实现机制

sping揭秘20spring的orm

sping揭秘25Spring远程方案

sping揭秘9容器内部事件发布

sping揭秘2关于spring配置文件