博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring aop 前置通知、后置通知、返回通知、 异常通知 、后置通知
阅读量:6676 次
发布时间:2019-06-25

本文共 6389 字,大约阅读时间需要 21 分钟。

hot3.png

                                                            Spring AOP定义切面

Ⅰ 首先介绍一下写Spring Aop思路

一、首先在项目中加入aop所需要的jar

aopalliance-1.0.jar

aspectjweaver-1.6.11.jar
commons-logging-1.1.1.jar
spring-aop-3.0.5.RELEASE.jar
spring-aspects-3.0.5.RELEASE.jar
spring-beans-3.0.5.RELEASE.jar
spring-context-3.0.5.RELEASE.jar
spring-context-support-3.0.5.RELEASE.jar
spring-core-3.0.5.RELEASE.jar
spring-expression-3.0.5.RELEASE.jar

二、在spring 项目核心配置文件中加入aop的命名空间

<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"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
三、声明一个切面类

1、首先要将这个类放入容器中,基于注解,在类头信息加入@Component

2、将这个类声明成切面类,在头信息加入@Aspect注解

3、可以基于切面中的方法,比如前置通知,后置通知,返回通知,异常通知,以及环绕通知写自己的业务逻辑,定义切点"execution(* com.liyi.service.*.*(..))",即那些方法需要执行这些方法。如果想获取到方法的名字和参数,可以在方法中加入JoinPoint参数,可以获取到进入切面的方法细节。

    3.1 前置通知:执行目标方法前拦截到的方法。没有特殊注意的地方,只需要一个连接点,JoinPoint,即可获取拦截目标方             法以及请求参数。

    3.2 后置通知: 切面的后置通知,不管方法是否抛出异常,都会走这个方法。只需要一个连接点,JoinPoint,即可获取当               前结束的方法名称。

    3.3 返回通知:  在方法正常执行通过之后执行的通知叫做返回通知。此时注意,不仅仅使用JoinPoint获取连接                          点信息,同时要在返回通知注解里写入,resut="result"。在切面方法参数中加入Object result,用于接受返回通知              的返回结果。如果目标方法方法是void返回类型则返回NULL

    3.4 异常通知: 在执行目标方法过程中,如果方法抛出异常则会走此方法。和返回通知很相似,在注解中                                  加入,throwing="ex",在切面方法中加入Exection ex用于接受异常信息

    3.5 环绕通知:环绕通知需要携带ProceedingJoinPoint 这个类型的参数,环绕通知类似于动态代理的全过程                              ProceedingJoinPoint类型的参数可以决定是否执行目标函数环绕通知必须有返回值。其实就是包含了所有通知的全              过程

四、最后别忘了在applicationContent.xml中声明aspect的代理对象,即初始化spring 容器的时候,spring自动对切点生成代理对象

<!-- 配置aspect 自动为匹配的类 产生代理对象 -->

<aop:aspectj-autoproxy>

Ⅱ 接下来 直接粘贴代码,很直观。

       1、aspect切面类

        

package com.liyi.aop;import java.text.SimpleDateFormat;import java.util.Arrays;import java.util.Date;import java.util.List;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.AfterThrowing;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.springframework.stereotype.Component;@Component@Aspectpublic class LoggingAspect {    /**     * 切面的前置方法 即方法执行前拦截到的方法 记录并输出     * 在目标方法执行之前的通知     * @param joinPoint     */        @Before("execution(* com.liyi.service.*.*(..))")//第一个星号是否方法的返回值 第二个星是只service的所有子包 另一个是任意方法    public void beforeMethod(JoinPoint joinPoint){        System.out.println("======================方法开始======================");        Object object = joinPoint.getSignature();        String methodName = joinPoint.getSignature().getName();        List list = Arrays.asList(joinPoint.getArgs());        Date date = new Date();        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");        String rightnow=sdf.format(date);        System.out.println(rightnow+"执行了【"+object+"方法开始执行......】");         System.out.println("******参数"+list+"******");    }    /**     * 切面的后置方法,不管抛不抛异常都会走此方法     * 在目标方法执行之后的通知     * @param joinPoint     */    @After("execution(* com.liyi.service.*.*(..))")    public void afterMethod(JoinPoint joinPoint){        Object object = joinPoint.getSignature();        Date date = new Date();        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");        String rightnow=sdf.format(date);        System.out.println(rightnow+"执行了【"+object+"方法结束......】");     }        /**     * 在方法正常执行通过之后执行的通知叫做返回通知     * 可以返回到方法的返回值 在注解后加入returning     * @param joinPoint     */    @AfterReturning(value="execution(* com.liyi.service.*.*(..))",returning="result")    public void afterReturn(JoinPoint joinPoint,Object result ){        Object object = joinPoint.getSignature();        Date date = new Date();        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");        String rightnow=sdf.format(date);        System.out.println(rightnow+"执行了【"+object+"方法正常执行结束......】"+"【返回结果:"+result+"】");         System.out.println("√√√√√√√√√√√√√√√√√√√√√√方法结束√√√√√√√√√√√√√√√√√√√√√√");    }        /**     * 在目标方法非正常执行完成 发生异常 抛出异常的时候会走此方法     * 获得异常可以用throwing     * @param joinPoint     * @param ex     */    @AfterThrowing(value="execution(* com.liyi.service.*.*(..))",throwing="ex")    public void afterThrowing(JoinPoint joinPoint,Exception ex ){        Object object = joinPoint.getSignature();        Date date = new Date();        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");        String rightnow=sdf.format(date);        System.out.println(rightnow+"执行了【"+object+"方法发生异常......】"+"【异常报告:"+ex+"】");         System.out.println("xxxxxxxxxxxxxxxxxx方法发生异常结束xxxxxxxxxxxxxxxxxx");    }    /**     * 环绕通知需要携带ProceedingJoinPoint 这个类型的参数     * 环绕通知类似于动态代理的全过程 ProceedingJoinPoint类型的参数可以决定是否执行目标函数     * 环绕通知必须有返回值     * @param proceedingJoinPoint     * @return     *///    @Around(value="execution(* com.liyi.service.*.*(..))")//    public Object aroundMethod(ProceedingJoinPoint proceedingJoinPoint){//        Object result=null;//        Object classMethod=proceedingJoinPoint.getSignature();//        Date date = new Date();//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");//        String rightnow=sdf.format(date);//        try {//            //前置通知//            System.out.println(rightnow+"环绕通知执行了【"+classMethod+"方法开始执行......】"); //            //执行目标方法//            result = proceedingJoinPoint.proceed(); //            //返回通知//            System.out.println(rightnow+"环绕通知正常执行【"+classMethod+"方法完毕......】"+"【返回结果:】"+result);//        } catch (Throwable e) {//            // TODO Auto-generated catch block//            e.printStackTrace();//            //异常通知//            System.out.println(rightnow+"环绕通知非正常执行【"+classMethod+"方法完毕,抛出异常......】"+"【返回异常:】"+e);//        }//            //后置通知//        System.out.println(rightnow+"环绕通知执行【"+classMethod+"方法完毕】");//        return result;//    }}

转载于:https://my.oschina.net/u/1998885/blog/483884

你可能感兴趣的文章
网页截图工具CutyCapt
查看>>
Android Jni Android.mk经常使用语句
查看>>
《影响力》6个使人顺从的武器之一互惠原理深入剖析
查看>>
Guava学习之Preconditions
查看>>
移动电力猫HG260GT pon实现路由拨号
查看>>
linux 系统获得当前文件夹下存在的所有文件 scandir函数和struct dirent **namelist结构体[转]...
查看>>
iOS 11开发教程(十四)iOS11应用代码添加视图
查看>>
sql server 2014登录账号
查看>>
Solr6 Suggest(智能提示)
查看>>
关于inodes占用100%的问题及解决方法
查看>>
nvidia驱动安装
查看>>
git 版本历史
查看>>
XHTML 教程(摘录自 W3C School)
查看>>
Directx11教程(50) 输出depth/stencil buffer的内容
查看>>
笔者亲自测试通过的修改SharePoint 2013的Topology脚本记录
查看>>
搜索引擎首页
查看>>
YARN - Yet Another Resource Negotiator
查看>>
[ASP.NET MVC 小牛之路]03 - Razor语法(转)
查看>>
linux系统下make & make install
查看>>
053医疗项目-模块五:权限设置-将用户操作权限写入Session
查看>>