Spring中的Advice类型及其应用
http://blog.csdn.net/myyate/article/details/1822150
在Spring中,Advice都是通过Interceptor来实现的,主要有以下几种:
1. 环绕Advice:
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
void before(Method m, Object[] args, Object target) throws Throwable;
}
一个更简单的通知类型是before 通知。它不需要 MethodInvocation
对象,因为它只是在进入方法之前被调用。before advice的一个主要优点是它不需要调用proceed()
方法,因此就不会发生 无意间运行拦截器链失败的情况。
3. After advice
void afterReturning(Object returnValue, Method m, Object[] args, Object target) throws Throwable;
}
一个After advice可以访问返回值(但不能进行修改),被调用方法,方法参数以及目标对象。
4.Throws Advice
public interface ThrowsAdvice extends Advice {
}
//所给对象必须实现一个或者多个针对特定类型的异常通知方法,格式如下
afterThrowing([Method], [args], [target], subclassOfThrowable)
//只有最后一个参数是必须的。因此异常通知方法对方法及参数的需求,方法的签名将从一到四个参数之间变化。
最后还有一个是introduction advice,这个我想什么时候自己单独做个例子理解一下。
做了个例子如下,想像一个用户登录场景:在登录之前,我们对其输入的用户名进行有效性检查;登录成功后,我们记上用户登录次数;如果登录失败,则进行异常处理。实现代码如下:
//登录的业务代码
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 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 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());
}
}
配置文件如下:
<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 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");
}
}
输出结果:
myyate passed check....
myyate is logining system...
Counting the login counts of myyate
Spring中的Advice类型及其应用相关推荐
- Spring 中的Advice类型介绍
Spring 中的 Advice 类型介绍 翻译原文链接 Introduction to Advice Types in Spring 1. 概述 在本文中,我们将讨论可以在 Spring 中创建的不 ...
- spring中tx:advice/tx:advice是什么意思?作用是什么?谁能简单说下
spring中<tx:advice></tx:advice>是什么意思?作用是什么?谁能简单说下 2013-03-26 17:15暴力娃娃123 | 浏览 13763 次 &l ...
- spring中tx:advice中的tx是什么的缩写?
spring中tx:advice中的tx是什么的缩写? transaction的缩写,即是跟事务相关的配置 tx 根据transaction的发音来缩写出来的
- 【Spring源码】Spring中的AOP底层原理分析
AOP中的几个概念 Advisor 和 Advice Advice,我们通常都会把他翻译为通知,其实很不好理解,其实他还有另外一个意思,就是"建议",我觉得把Advice理解为&q ...
- Spring中的AOP(8)
Spring的传统AOP AOP:不是由Spring定义.AOP联盟的组织定义. Spring中的通知:(增强代码) 前置通知 org.springframework.aop.MethodBefore ...
- Spring→面向切面编程AOP、相关概念、通知Advice类型、配置切面切入点通知、AOP相关API、AOP代理类ProxyFactoryBean、AOP注解@AspectJ
面向切面编程AOP CGLib AOP相关概念 Advice类型 Spring实现AOP Spring配置切面aspect 配置切入点pointcut 配置通知advice 配置通知参数 调用新的父类 ...
- Spring关于AOP中关于advice的执行顺序
AOP的核心概念 要完全理解Spring AOP首先要理解AOP的核心概念和术语,这些术语并不是Spring指定的,而且很不幸,这些术语并不能直观理解,但是,如果Spring使用自己的术语,那将更加令 ...
- Spring 中的AOP的通知类型的示例(xml)
个人博客:https://suveng.github.io/blog/ Spring 中的AOP的通知类型的示例 AOP中的通知类型(advice)一共有五中: around advic ...
- spring中的依赖注入——构造函数注入、set方法注入( 更常用的方式)、复杂类型的注入/集合类型的注入
spring中的依赖注入 依赖注入: Dependency Injection IOC的作用:降低程序间的耦合(依赖关系) 依赖关系的管理:以后都交给spring来维护.在当前类需要用到其他类的对象, ...
最新文章
- Android 程序自动更新功能模块实现
- mysql 存储 结构,mysql目录与存储结构(一)
- 装python对电脑有什么影响-你知道:重装系统对电脑有什么影响吗?会损坏电脑吗?...
- react组件设计原则_React组件设计规则
- 为什么grpc不支持php,带入gRPC:让你的服务同时提供 HTTP 接口
- 小李飞刀:用python刷题ing....
- 深圳南山区法院受理11人集体诉腾讯案
- 约会软件上的小姐姐,其实是StyleGAN生成的假人
- 跳跃回溯____寻找最长平台
- 线程、同步异步、队列
- 基于启英泰伦语音芯片的语音AIoT应用方案,可实现家居联控
- 关于STM8S003F3P6开发的笔记v
- 【转】什么是Online Learning
- 如何给Layout文件夹分类
- PS教程新手入门(三)--PS实用的技巧教程
- java list 取第一个,从Java LinkedList获取第一个和最后一个元素
- 实验 3 熟悉常用的 HDFS 操作
- 汽车电子之功能安全产品设计过程
- 利用指针访问opencv Mat类型的矩阵,以及求椭圆方程的函数
- 常用的16个Java实用工具类,Java开发人员请收藏!
热门文章
- RxSwift之UI控件UISlider与UIStepper扩展的使用
- 2019\Province_C_C++_B\试题G-完全二叉树的权值
- 《数据库原理与应用》(第三版)第9章 事务与并发控制 基础 习题参考答案
- 数据库开发——MySQL——多表查询
- 2019年第十届蓝桥杯 - 省赛 - C/C++大学B组 - A. 组队
- 第十届 蓝桥杯样题 ——结果填空
- 【C++】 C++标准模板库(八) MultiMaps
- android 约束布局的坑,android - 使用android约束布局2.0.0 Flow将项目放置一行 - 堆栈内存溢出...
- python 面试题 2020_2020年最全python面试题
- keepalived(8)——http、tcp检测