http://blog.csdn.net/myyate/article/details/1822150

在Spring中,Advice都是通过Interceptor来实现的,主要有以下几种:

1. 环绕Advice:

//例子摘自Spring reference
public interface MethodInterceptor extends Interceptor {
      Object invoke(MethodInvocation invocation) throws Throwable;
}
public class DebugInterceptor implements MethodInterceptor {

public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("Before: invocation=[" + invocation + "]");  //(1)
        Object rval = invocation.proceed();
        System.out.println("Invocation returned");  //(2)
        return rval;
    }
}

环绕advice类似一个拦截器链,这个拦截器链的中心就是被拦截的方法。在程序(1)(2)我们可以加入我们自己的代码,以表示在方法执行前后我们需要干什么。invocation.proceed()方法运行指向连接点的拦截器链并返回proceed()的结果。

2. Before Advice

public interface MethodBeforeAdvice extends BeforeAdvice {
    void before(Method m, Object[] args, Object target) throws Throwable;
}

一个更简单的通知类型是before 通知。它不需要 MethodInvocation对象,因为它只是在进入方法之前被调用。before advice的一个主要优点是它不需要调用proceed()方法,因此就不会发生 无意间运行拦截器链失败的情况。

3. After advice

public interface AfterReturningAdvice extends Advice {
    void afterReturning(Object returnValue, Method m, Object[] args, Object target) throws Throwable;
}

一个After advice可以访问返回值(但不能进行修改),被调用方法,方法参数以及目标对象。

4.Throws Advice

//ThrowsAdvice 是一个空接口,起标识作用
public interface ThrowsAdvice extends Advice {

}
//所给对象必须实现一个或者多个针对特定类型的异常通知方法,格式如下
afterThrowing([Method], [args], [target], subclassOfThrowable)
//只有最后一个参数是必须的。因此异常通知方法对方法及参数的需求,方法的签名将从一到四个参数之间变化。

最后还有一个是introduction advice,这个我想什么时候自己单独做个例子理解一下。

做了个例子如下,想像一个用户登录场景:在登录之前,我们对其输入的用户名进行有效性检查;登录成功后,我们记上用户登录次数;如果登录失败,则进行异常处理。实现代码如下:

package com.learn.spring.test.advisor;
//登录的业务代码
public interface LoginService {
    void login(String name, String password) throws UnauthorityException;
}

public class LoginServiceImpl implements LoginService {

public void login(String name, String password) throws UnauthorityException {
            check(name, password);
            System.err.println(name + " is logining system...");
    }
    
    private void check(String name, String password) throws UnauthorityException {
            if("myyate".equals(name) && "pass".equals(password) ) {
                     System.err.println(name + " passed check....");
            } else {
                    throw new UnauthorityException("invalid password");
            }
    }
}

//用户名检查 拦截器
public class LoginNameCheckInterceptor implements MethodBeforeAdvice {

public void before(Method method, Object[] args, Object target) throws Throwable {
         System.err.println("check user's name is valid?");
         if(args[0] == null || "".equals(args[0].toString().trim())) {
               throw new IllegalArgumentException();
         }
    }
}

//用户登录次数统计拦截器
public class LoginCountInterceptor implements AfterReturningAdvice ...{

public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable ...{
    System.err.println("Counting the login counts of " + args[0]);
    }
}

//异常处理拦截器
public class ExceptionThrowInterceptor implements ThrowsAdvice {
    
    public void afterThrowing(Method m, Object[] args, Object target, IllegalArgumentException ex) throws Throwable {
    System.err.println("Login name is wrong, exception: " + ex);
    }
    
    public void afterThrowing(Method m, Object[] args, Object target, UnauthorityException ex) {
       System.err.println(target.getClass() + "." + m.getName() + 
           "() throw a exception: " + ex.getMessage());
    }
}

配置文件如下:

<?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:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">

    <bean id="loginServiceTarget"
        class="com.learn.spring.test.advisor.LoginServiceImpl"/>
        
    <bean id="loginNameCheckInterceptor"
        class="com.learn.spring.test.advisor.LoginNameCheckInterceptor"/>
        <!-- 
    <bean id="loginCheckInterceptor"
        class="com.learn.spring.test.advisor.LoginCheckInterceptor"/>
         -->
    <bean id="loginCountInterceptor"
        class="com.learn.spring.test.advisor.LoginCountInterceptor"/>
    <bean id="exceptionThrowInterceptor"
        class="com.learn.spring.test.advisor.ExceptionThrowInterceptor"/>
        
    <bean id="loginService" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target"><ref local="loginServiceTarget"/></property>
        <property name="proxyInterfaces">
            <list>
                <value>com.learn.spring.test.advisor.LoginService</value>
            </list>
        </property>
        <property name="interceptorNames">
            <list>
                <value>loginNameCheckInterceptor</value>
                <value>loginCountInterceptor</value>
                <value>exceptionThrowInterceptor</value>
            </list>
        </property>
    </bean>
</beans>

测试代码运行:

public class Test {

public static void main(String[] args) throws Exception {
        BeanFactory bf = 
            BeanFactoryFactory.getBeanFactory("beans.xml", Test.class);
        LoginService ls = (LoginService) bf.getBean("loginService");
        ls.login("myyate", "pass");
    }
}

输出结果:

check user's name is valid?
myyate passed check....
myyate is logining system...
Counting the login counts of myyate

Spring中的Advice类型及其应用相关推荐

  1. Spring 中的Advice类型介绍

    Spring 中的 Advice 类型介绍 翻译原文链接 Introduction to Advice Types in Spring 1. 概述 在本文中,我们将讨论可以在 Spring 中创建的不 ...

  2. spring中tx:advice/tx:advice是什么意思?作用是什么?谁能简单说下

    spring中<tx:advice></tx:advice>是什么意思?作用是什么?谁能简单说下 2013-03-26 17:15暴力娃娃123 | 浏览 13763 次 &l ...

  3. spring中tx:advice中的tx是什么的缩写?

    spring中tx:advice中的tx是什么的缩写? transaction的缩写,即是跟事务相关的配置 tx 根据transaction的发音来缩写出来的

  4. 【Spring源码】Spring中的AOP底层原理分析

    AOP中的几个概念 Advisor 和 Advice Advice,我们通常都会把他翻译为通知,其实很不好理解,其实他还有另外一个意思,就是"建议",我觉得把Advice理解为&q ...

  5. Spring中的AOP(8)

    Spring的传统AOP AOP:不是由Spring定义.AOP联盟的组织定义. Spring中的通知:(增强代码) 前置通知 org.springframework.aop.MethodBefore ...

  6. Spring→面向切面编程AOP、相关概念、通知Advice类型、配置切面切入点通知、AOP相关API、AOP代理类ProxyFactoryBean、AOP注解@AspectJ

    面向切面编程AOP CGLib AOP相关概念 Advice类型 Spring实现AOP Spring配置切面aspect 配置切入点pointcut 配置通知advice 配置通知参数 调用新的父类 ...

  7. Spring关于AOP中关于advice的执行顺序

    AOP的核心概念 要完全理解Spring AOP首先要理解AOP的核心概念和术语,这些术语并不是Spring指定的,而且很不幸,这些术语并不能直观理解,但是,如果Spring使用自己的术语,那将更加令 ...

  8. Spring 中的AOP的通知类型的示例(xml)

    个人博客:https://suveng.github.io/blog/​​​​​​​ Spring 中的AOP的通知类型的示例 AOP中的通知类型(advice)一共有五中: around advic ...

  9. spring中的依赖注入——构造函数注入、set方法注入( 更常用的方式)、复杂类型的注入/集合类型的注入

    spring中的依赖注入 依赖注入: Dependency Injection IOC的作用:降低程序间的耦合(依赖关系) 依赖关系的管理:以后都交给spring来维护.在当前类需要用到其他类的对象, ...

最新文章

  1. Android 程序自动更新功能模块实现
  2. mysql 存储 结构,mysql目录与存储结构(一)
  3. 装python对电脑有什么影响-你知道:重装系统对电脑有什么影响吗?会损坏电脑吗?...
  4. react组件设计原则_React组件设计规则
  5. 为什么grpc不支持php,带入gRPC:让你的服务同时提供 HTTP 接口
  6. 小李飞刀:用python刷题ing....
  7. 深圳南山区法院受理11人集体诉腾讯案
  8. 约会软件上的小姐姐,其实是StyleGAN生成的假人
  9. 跳跃回溯____寻找最长平台
  10. 线程、同步异步、队列
  11. 基于启英泰伦语音芯片的语音AIoT应用方案,可实现家居联控
  12. 关于STM8S003F3P6开发的笔记v
  13. 【转】什么是Online Learning
  14. 如何给Layout文件夹分类
  15. PS教程新手入门(三)--PS实用的技巧教程
  16. java list 取第一个,从Java LinkedList获取第一个和最后一个元素
  17. 实验 3 熟悉常用的 HDFS 操作
  18. 汽车电子之功能安全产品设计过程
  19. 利用指针访问opencv Mat类型的矩阵,以及求椭圆方程的函数
  20. 常用的16个Java实用工具类,Java开发人员请收藏!

热门文章

  1. RxSwift之UI控件UISlider与UIStepper扩展的使用
  2. 2019\Province_C_C++_B\试题G-完全二叉树的权值
  3. 《数据库原理与应用》(第三版)第9章 事务与并发控制 基础 习题参考答案
  4. 数据库开发——MySQL——多表查询
  5. 2019年第十届蓝桥杯 - 省赛 - C/C++大学B组 - A. 组队
  6. 第十届 蓝桥杯样题 ——结果填空
  7. 【C++】 C++标准模板库(八) MultiMaps
  8. android 约束布局的坑,android - 使用android约束布局2.0.0 Flow将项目放置一行 - 堆栈内存溢出...
  9. python 面试题 2020_2020年最全python面试题
  10. keepalived(8)——http、tcp检测