文档章节

Spring aop 前置通知、后置通知、返回通知、 异常通知 、后置通知

薄暮凉年
 薄暮凉年
发布于 2015/07/26 17:01
字数 1420
阅读 6656
收藏 21

                                                            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
@Aspect
public 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<Object> 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;
//    }
}




© 著作权归作者所有

上一篇: PageUtil 分页
薄暮凉年
粉丝 32
博文 29
码字总数 15951
作品 0
朝阳
私信 提问
Spring 的 AOP 的支持

面向切面编程(Aspect-oriented Programming,AOP)通过提供另一种思考程序结构的方法来补充面向对象编程(Object-oriented Programming,OOP)。OOP中模块化的关键单元是类,而AOP中模块化的单元是...

非摩尔根
2018/12/18
0
0
Spring AOP(3)基于XML配置实现的示例

使用注解的方式配置切面类在程序出问题的时候不方便查找问题,尤其是AOP这种tricky的功能,因此在spring配置文件中配置aop是一个相对好的选择(个人感觉): aop:config </aop:config> <bean...

mushui
2013/09/13
0
0
SPring AOP(面向切面编程)

AOP(面向切面编程) AOP是OOP(面向对象编程)的延续,但是它和面向对象的纵向编程不同,它是一个横向的切面式的编程。可以理解为oop就是一根柱子,如果需要就继续往上加长,而aop则是在需要...

MrBoyce
02/20
0
0
Spring.NET学习笔记14——AOP的通知类型(基础篇) Level 300

上篇我们学习了 AOP的基本概念,我们回顾一下上篇提到的 Advice( 通知):所谓通知是指拦截到 joinpoint( 连接点)之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,环绕通知。...

长平狐
2012/06/11
515
0
学习Spring(九) -- Spring使用AOP

AOP通知 Spring中常用的AOP通知有五种: 前置通知:在某方法调用之前执行; 后置通知:在后方法调用之后执行; 异常通知:在某方法发生异常时执行; 返回通知:在某方法进行返回时执行; 环绕...

杰克鹏仔
2016/05/01
99
0

没有更多内容

加载失败,请刷新页面

加载更多

“旧城改造”的背后——银泰新零售阿里云解决方案(上)

相关免费课程《银泰新零售上云解决方案精讲》上线中 立足实战 讲透经典案例 助你快速理解新零售 第一节学习地址 第二节学习地址 传统线下商业体上云的案例 与其说银泰上云,倒不如说银泰“旧...

阿里云官方博客
8分钟前
0
0
记一次升级Oracle驱动引发的死锁

问题描述 近期项目需要从虚拟机环境迁移到容器环境,其中有一个项目在迁移到容器环境之后的两天之内出现了2次“死锁(deadlock)”的问题,部分关键日志如下: Found one Java-level deadlock:...

ksfzhaohui
9分钟前
2
0
MySQL 中的 information_schema 数据库

欢迎查看原文 - 本博客仅记录 https://blog.csdn.net/kikajack/article/details/80065753 -- 是否开启bin_log日志: off为关闭-- show variables like 'log_%'; show variables like '......

莫库什勒
17分钟前
0
0
Random在高并发下的缺陷以及JUC对其的优化

Random可以说是每个开发都知道,而且都用的很6的类,如果你说,你没有用过Random,也不知道Random是什么鬼,那么你也不会来到这个技术类型的社区,也看不到我的博客了。但并不是每个人都知道...

编程SHA
22分钟前
0
0
T5大牛带你解析:如何实现分布式技术

1.分布式事务 2. 分布式锁 Java 原生 API 虽然有并发锁,但并没有提供分布式锁的能力,所以针对分布式场景中的锁需要解决的方案。 分布式锁的解决方案大致有以下几种: 基于数据库实现 基于缓...

李红欧巴
34分钟前
32
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部