【框架】[Spring]纯Java方式实现AOP拦截-详解ThrowsAdvice异常通知

转载请注明出处:http://blog.csdn.net/qq_26525215

本文源自大学之旅_谙忆的博客

这篇博客讲了AOP代理-通知的3种方式:
1、MethodBeforeAdvice-前置通知
2、AfterReturningAdvice-正常返回后通知
3、MethodInterceptor-环绕通知
【框架】[Spring]纯Java的方式实现AOP切面(拦截)技术

现在本篇博客再详细讲解一下ThrowsAdvice-异常通知。

顾明思议,就是被代理的原型对象出异常了,就会运行到实现此接口中的一个方法。
这个和AfterReturningAdvice互补哦。

被代理的类:

package cn.hncu.javaImpl;

public class Person {
    public void run(){
        System.out.println("我在run...");
    }

    public void run(int i){
        System.out.println("我在run"+i+"...");
        throw  new  IllegalArgumentException();
    }

    public void say(){
        System.out.println("我在say...");
    }

}

实现ThrowsAdvice的方法:

package cn.hncu.javaImpl;

import org.springframework.aop.ThrowsAdvice;

public class ThrowException implements ThrowsAdvice{
    public  void  afterThrowing(Exception e)  throws  Throwable{
        System.out.println("出异常了..."+e);
    }
}

运行的方法:

@Test
    public void demo3(){
        ProxyFactoryBean factory = new ProxyFactoryBean();
        factory.setTarget(new Person());//给代理工厂一个原型对象

        //切面 = 切点 + 通知
        //切点
        JdkRegexpMethodPointcut cut = new JdkRegexpMethodPointcut();
        cut.setPatterns(new String[]{".*run.*",".*say.*"});//可以配置多个正则表达式

        Advice throwsAdvice = new ThrowException();

        //切面 = 切点 + 通知
        Advisor throwsAdviceAdvisor = new DefaultPointcutAdvisor(cut, throwsAdvice);

        factory.addAdvisors(throwsAdviceAdvisor);

        Person p2 = (Person) factory.getObject();//从代理工厂中获取一个代理后的对象

        p2.run();
        p2.run(2222);
    }

运行结果:

有几个需要注意的地方:
1、就是原型对象的异常不能抓!一旦抓取就无法运行afterThrowing。
也就是只有出异常了,且没被抓,才会运行这个方法。
2、不能在运行的方法中直接new ThrowsAdvice然后实现afterThrowing方法,这样因为出异常,线程挂了,也会无法运行这个afterThrowing方法。
也就是不能在测试的方法中直接:

Advice throwsAdvice = new ThrowsAdvice() {
            public  void  afterThrowing(Exception e)  throws  Throwable{
                System.out.println("出异常了..."+e);
            }
        };

这样也无法实现原型对象处异常拦截。

ThrowsAdvice源代码分析:

直接看ThrowsAdvice接口的源代码:

/*
 * Copyright 2002-2008 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.aop;

/**
 * Tag interface for throws advice.
 *
 * <p>There are not any methods on this interface, as methods are invoked by
 * reflection. Implementing classes must implement methods of the form:
 *
 * <pre class="code">void afterThrowing([Method, args, target], ThrowableSubclass);</pre>
 *
 * <p>Some examples of valid methods would be:
 *
 * <pre class="code">public void afterThrowing(Exception ex)</pre>
 * <pre class="code">public void afterThrowing(RemoteException)</pre>
 * <pre class="code">public void afterThrowing(Method method, Object[] args, Object target, Exception ex)</pre>
 * <pre class="code">public void afterThrowing(Method method, Object[] args, Object target, ServletException ex)</pre>
 *
 * The first three arguments are optional, and only useful if we want further
 * information about the joinpoint, as in AspectJ <b>after-throwing</b> advice.
 *
 * <p><b>Note:</b> If a throws-advice method throws an exception itself, it will
 * override the original exception (i.e. change the exception thrown to the user).
 * The overriding exception will typically be a RuntimeException; this is compatible
 * with any method signature. However, if a throws-advice method throws a checked
 * exception, it will have to match the declared exceptions of the target method
 * and is hence to some degree coupled to specific target method signatures.
 * <b>Do not throw an undeclared checked exception that is incompatible with
 * the target method's signature!</b>
 *
 * @author Rod Johnson
 * @author Juergen Hoeller
 * @see AfterReturningAdvice
 * @see MethodBeforeAdvice
 */
public interface ThrowsAdvice extends AfterAdvice {

}

你会发现里面并没有一个抽象方法!也行会有小伙伴迷茫,那为什么我们要实现那个方法啊。
没办法,因为我们是用Spring的框架,Spring内部用类反射来匹配了的,实现这个接口必须要实现这4个方法中的一个:

public void afterThrowing(Exception ex)
public void afterThrowing(RemoteException)
public void afterThrowing(Method method, Object[] args, Object target, Exception ex)
public void afterThrowing(Method method, Object[] args, Object target, ServletException ex)

它的源代码有解释的,英文好一点就能看懂啦。

至于为什么不直接在这个接口中写这4个抽象类,可能怕代码太冗余吧。
毕竟,我们实现这个接口,我们用到的方法只会有一个,而如果都被声明成抽象方法了,那么,用户实现接口也必须实现这4个方法,显得冗余了。
所以估计Spring就干脆定义成标识接口了吧。

本文章由[谙忆]编写, 所有权利保留。

转载请注明出处:http://blog.csdn.net/qq_26525215

本文源自大学之旅_谙忆的博客

时间: 2024-09-29 20:28:21

【框架】[Spring]纯Java方式实现AOP拦截-详解ThrowsAdvice异常通知的相关文章

Java Comparable 和 Comparator 的详解及区别_java

Java Comparable 和 Comparator 的详解及区别 Java 中为我们提供了两种比较机制:Comparable 和 Comparator,他们之间有什么区别呢?今天来了解一下. Comparable 自然排序 Comparable 在 java.lang 包下,是一个接口,内部只有一个方法 compareTo(): public interface Comparable<T> { public int compareTo(T o); } Comparable 可以让实现它的

Java 配置加载机制详解及实例_java

前言 现如今几乎大多数Java应用,例如我们耳熟能详的tomcat, struts2, netty-等等数都数不过来的软件,要满足通用性,都会提供配置文件供使用者定制功能. 甚至有一些例如Netty这样的网络框架,几乎完全就是由配置驱动,这样的软件我们也通常称之为"微内核架构"的软件.你把它配置成什么,它就是什么. It is what you configure it to be. 最常见的配置文件格式是XML, Properties等等文件. 本文探讨加载配置中最通用也是最常见的场

Android AOP 注解详解及简单使用实例(三)

Android  注解 相关文章: Android AOP注解Annotation详解(一) Android AOP之注解处理解释器详解(二) Android AOP 注解详解及简单使用实例(三) 一.简介 在Android 里面 注解主要用来干这么几件事: 和编译器一起给你一些提示警告信息. 配合一些ide 可以更加方便快捷 安全有效的编写Java代码.谷歌出的support-annotations这个库 就是主要干这个的. 和反射一起 提供一些类似于spring 可配置的功能,方便简洁. 二

《Java和Android开发实战详解》——1.1节编程语言基础知识

1.1编程语言基础知识 Java和Android开发实战详解 "编程语言"(Programming Language)是人类告诉计算机如何工作的一款语言,如同人与人之间沟通使用自然语言,编程语言被设计用于人类与计算机之间进行沟通.从技术角度来说,编程语言就是一款将执行指令传达给计算机的标准通信技术. 1.1.1 程序.软件与应用程序 在说明编程语言之前,我们需要了解什么是程序.软件与应用程序.简单地说来,编程语言提供了语法,可以让我们编写程序代码来建立程序,程序经编译建立成应用程序后,

在docker中部署tomcat并且部署java应用程序的步骤详解_docker

先给大家简单说下Docker的概念 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互之间不会有任何接口. 1.先说如何在docker中部署tomcat 第一步:root用户登录在系统根目录下创建文件夹tomcat7,命令如:mkdir tomcat7,并且切换到该目录下:cd tomcat7: 第二步:创建Dockerfile,命令如:touch Docker

《Java和Android开发实战详解》——1.4节搭建Java开发环境

1.4 搭建Java开发环境 Java和Android开发实战详解 在开发Java应用程序前需要搭建Java的开发环境,首先需要安装JDK,然后即可配合编辑工具或集成开发环境来创建Java应用程序.本书主要介绍如何使用Eclipse集成开发环境来创建Java和Android应用程序. 1.4.1 安装与设置JDK 一般来说,有些集成开发环境会一并安装JDK,例如JBuilder,不过,大部分集成开发环境需要用户自行安装JDK.本书使用的JDK版本是JDK 7(Java SE Developmen

Java I/O : Java中的进制详解

作者:李强强 上一篇,泥瓦匠基础地讲了下Java I/O : Bit Operation 位运算.这一讲,泥瓦匠带你走进Java中的进制详解. 一.引子 在Java世界里,99%的工作都是处理这高层.那么二进制,字节码这些会在哪里用到呢? 自问自答:在跨平台的时候,就凸显神功了.比如说文件读写,数据通信,还有Java编译后的字节码文件.下面会有个数据通信的例子哦. Java对对象实现Serializablle接口,就可以将其转化为一系列字节,而在通信中,不必要关系数据如何在不同机器表示和字节的顺

《Java和Android开发实战详解》——2.1节如何构建应用程序

2.1 如何构建应用程序 Java和Android开发实战详解 一般来说,我们使用Java程序语言的目的,就是编写程序代码构建应用程序,以期让计算机执行来解决问题. 2.1.1 如何编写程序代码 程序设计(Programming)很困难吗?事实上,如果你可以引导问路人到达目的地.走迷宫或开车到你家,一步一步详细列出活动流程,就表示你一定可以编写程序代码.不过,在列流程时请注意!计算机一点都不聪明,也不会举一反三,所以,我们需要告诉计算机详细的步骤和信息,不能只有模棱两可的内容. 例如,在北京开车

《Java和Android开发实战详解》——1.2节Java基础知识

1.2 Java基础知识 Java和Android开发实战详解 Java语言类似于C++是一种编译型语言,不过两者并不完全相同,严格说来,Java是结合编译和解释优点的一种编程语言. 1.2.1 Java平台 "平台"(Platform)是一种结合硬件和软件的执行环境.Java既是一种高级的面向对象的编程语言,也是一个平台.Java平台是一种纯软件平台,它可以在各种基于硬件的平台上运行,与硬件无关,主要是由JVM和Java API两个部分组成. 1.JVM虚拟机 JVM(Java Vi