利用Spring AOP的通知类型以及创建通知
写在最前端
- 1.SpringAOP中共有六种通知类型,只要我们自定义一个类实现对应的接口,它们全都是
org.springframework.aop包中的。 - 2.AOP的连接点可以是方法调用、方法调用本身、类初始化、对象实例化时,但是SpringAOP中全是方法调用,更简单,也最实用
| 通知名称 | 接口 |
|---|---|
| 前置通知 | org.springframework.aop.MethodBeforeAdvice |
| 后置返回通知 | org.springframework.aop.AfterReturningAdvice |
| 后置通知 | org.springframework.aop.AfterAdvice |
| 环绕通知 | org.springframework.aop.MethodInterceptor |
| 异常通知 | org.springframework.aop.ThrowsAdvice |
| 引入通知 | org.springframework.aop.IntroductionInterceptor |
写一个公共类,用于目标对象
public class Person {
private String name;
public boolean saySomething(String something){
System.out.println("Pereson类中说了一句:"+something);
return true;//默认返回true
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
一、创建前置通知(也就是目标方法调用前执行)
- 前置通知可以修改传递给方法的参数,并且可以通过抛出异常来阻止方法的执行,可以用前置通知实现用户登录的验证,SpringSecurity就是这么做的
1.例子:在一个方法执行前将包含方法名称的消息写入到控制台中,并且将传入的参数修改下。(文章中写的内容比较小,大多数在代码中有注释,大家可以下载代码查看)
/**
* 前置通知类
*/
public class BeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] objects, @Nullable Object o) throws Throwable {
//第一个参数是目标方法对象,第二个是参数,第三个是做为调用目标的object(这是personr实例)
//打印方法名
System.out.println("要执行的方法是:"+method.getName());
//修改参数为lyn4ever
objects[0]="lyn4ever";//我们修改成为了lyn4ever,所以打印出来的就是lyn4ever,而不是zhangsan
}
public static void main(String[] args) {
Person person = new Person();
ProxyFactory pf =new ProxyFactory();
pf.addAdvice(new BeforeAdvice());
pf.setTarget(person);
Person proxy = (Person) pf.getProxy();
//我这里传的参数是zhangsan,理论上它应该打印出来zhangsan
proxy.saySomething("zhangsan");
}
}

没毛病,本来我输入的是zhangsan,在aop中将参数改为了lyn4ever,这样就完美的替换了。
二、后置返回通知
是在连接点(方法调用)返回后执行,这显然不能像上边那样修改参数,也不能修改返回值。但是可以抛出可以发送到堆栈的异常,同样也可以调用其他方法。
/**
* 后置返回通知
*/
public class AfterReturnAdvice implements AfterReturningAdvice {
@Override
public void afterReturning(@Nullable Object o, Method method, Object[] objects, @Nullable Object o1) throws Throwable {
/*
参数和前置通知是一样的
这个是在返回之后调用,因此,person中的saySomething会先打印,我们在这里修改的参数不起作任何作用
*/
System.out.println("调用的方法是:"+method.getName()+"这句是在saySomething之后");//这句是在saySomething之后
objects[0]="lyn4ever";//这句可以修参数,但是之前的方法已经执行过了,所以不起任何作用
System.out.println("我们修改了参数为:"+objects[0]+"但是没有任何用");//这时候这个参数并不会传到person.saysomething(),因为已经调用过了
}
public static void main(String[] args) {
Person person = new Person();
ProxyFactory pf = new ProxyFactory();
pf.addAdvice(new AfterReturnAdvice());//注意修改这个为当前类中的通知类
pf.setTarget(person);
Person proxy = (Person) pf.getProxy();
proxy.saySomething("zhangsan");
}
}

三、环绕通知
这人最好理解了,就是在方法调用前后都可以执行代码。看起来像是前置后后置的集合,但是它可以修改方法的返回值,因为它实现的invoke方法的返回值是Object,所以我们就可以修改,而前置通知的返回是void,所以没法修改的。甚至以至于我们可以不调用目标对象中的连接点方法,我们完全修改这个方法的全部代码。
public class MyMethodInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
return null;
}
}
虽然这个invoke()方法中并没有提供像之前的那些参数,但是这一个invocation实例可以得到


代码示例
/**
* 环绕通知
*/
public class MyMethodInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
//在这个invoation中有一切我们想要的方法相关
System.out.println("类名是:"+invocation.getThis().getClass().getName());
System.out.println("目标方法是:"+invocation.getMethod().getName());
Object[] arguments = invocation.getArguments();//这个就是参数
System.out.println("第一个参数 是:"+arguments[0]);
//我们修改第一个参数为lyn4ever
arguments[0]="lyn4ever";
invocation.proceed();//执行目标方法
System.out.println("这个是在之后执行的");
return false;//修改返回值
}
public static void main(String[] args) {
Person person = new Person();
ProxyFactory pf = new ProxyFactory();
pf.addAdvice(new MyMethodInterceptor());//注意修改这个为当前类中的通知类
pf.setTarget(person);
Person proxy = (Person) pf.getProxy();
boolean flag = proxy.saySomething("zhangsan");
System.out.println(flag);//方法本来是要返回true的
}
}
可以看到,我们修改了目标方法返回的值。
利用Spring AOP的通知类型以及创建通知的更多相关文章
- 化繁就简,如何利用Spring AOP快速实现系统日志
1.引言 有关Spring AOP的概念就不细讲了,网上这样的文章一大堆,要讲我也不会比别人讲得更好,所以就不啰嗦了. 为什么要用Spring AOP呢?少写代码.专注自身业务逻辑实现(关注本身的业务 ...
- 利用Spring AOP自定义注解解决日志和签名校验
转载:http://www.cnblogs.com/shipengzhi/articles/2716004.html 一.需解决的问题 部分API有签名参数(signature),Passport首先 ...
- (转)利用Spring AOP自定义注解解决日志和签名校验
一.需解决的问题 部分API有签名参数(signature),Passport首先对签名进行校验,校验通过才会执行实现方法. 第一种实现方式(Origin):在需要签名校验的接口里写校验的代码,例如: ...
- 利用Spring AOP和自定义注解实现日志功能
Spring AOP的主要功能相信大家都知道,日志记录.权限校验等等. 用法就是定义一个切入点(Pointcut),定义一个通知(Advice),然后设置通知在该切入点上执行的方式(前置.后置.环绕等 ...
- 利用Spring AOP切面对用户访问进行监控
开发系统时往往需要考虑记录用户访问系统查询了那些数据.进行了什么操作,尤其是访问重要的数据和执行重要的操作的时候将数记录下来尤显的有意义.有了这些用户行为数据,事后可以以用户为条件对用户在系统的访问和 ...
- 利用spring AOP 和注解实现方法中查cache-我们到底能走多远系列(46)
主题:这份代码是开发中常见的代码,查询数据库某个主表的数据,为了提高性能,做一次缓存,每次调用时先拿缓存数据,有则直接返回,没有才向数据库查数据,降低数据库压力. public Merchant lo ...
- Spring Aop(十三)——ProxyFactoryBean创建代理对象
转发地址:https://www.iteye.com/blog/elim-2398673 ProxyFactoryBean创建代理对象 ProxyFactoryBean实现了Spring的Factor ...
- 通知类型 重点: 环绕通知 (XML配置)
前置通知:在切入点方法执行之前执行 <aop:before method="" pointcut-ref="" ></aop:before&g ...
- 利用spring AOP 实现统一校验
开发环境 JDK: 1.7 spring: 4.0.6 aspect: 1.7.4 应用背景 在APP与后台通讯的过程中,我们一般都会有个authToken的字符串校验,判断那些请求是需要校验用户 ...
随机推荐
- 使用 Nginx 搭建静态资源 web 服务器
在搭建网站的时候,往往会加载很多的图片,如果都从 Tomcat 服务器来获取静态资源,这样会增加服务器的负载,使得服务器运行 速度非常慢,这时可以使用 Nginx 服务器来加载这些静态资源,这样就可以 ...
- Excel在线预览(通过poi转html,含里面的图片)
支持03和07excel转html,直接上代码 测试类 /** * 主方法 * @author asus * */ public class App2 { public static void mai ...
- 大家都说好用的 Python 命令行库:click
作者:HelloGitHub-Prodesire HelloGitHub 的<讲解开源项目>系列,项目地址:https://github.com/HelloGitHub-Team/Arti ...
- Mycat分布式数据库架构解决方案--Linux安装运行Mycat
echo编辑整理,欢迎转载,转载请声明文章来源.欢迎添加echo微信(微信号:t2421499075)交流学习. 百战不败,依不自称常胜,百败不颓,依能奋力前行.--这才是真正的堪称强大!!! Myc ...
- Python+requests+unittest+excel实现接口自动化测试框架(转
一.框架结构:工程目录 二.Case文件设计三.基础包 base 3.1 封装get/post请求(runmethon.py) import requests import json class Ru ...
- Flask:网页路由及请求方式的设定
1.Flask路由的实现 Flask的路由是由route装饰器来实现的 @app.route("/index/") def index(): return "hello ...
- Redis集群--Redis集群之哨兵模式
echo编辑整理,欢迎转载,转载请声明文章来源.欢迎添加echo微信(微信号:t2421499075)交流学习. 百战不败,依不自称常胜,百败不颓,依能奋力前行.--这才是真正的堪称强大!!! 搭建R ...
- 1000m交叉网线最简单做法
1-3,2-6,3-1,4-7,5-8,6-2,7-4,8-5 1,2,3,4,5,6,7,8即为网线内部8跟线编号,两头颜色和数字要对应.
- 在VMware环境下安装Windows2008
1.软硬件安装 软件:推荐使用VMware,这里我使用的是VMware15 镜像:Windows 2008 如果没有镜像可以到这里 链接:https://pan.baidu.com/s/1r_7K-U ...
- 创建OData Service(基于ASP.NET 4.6.1, EF 6),Part I:Project initialize
由于ASP.NET Core 1处于RC阶段,加上OData WebAPI 对ASP.NET Core 1的跟进不是很积极,基于ASP.NET Core 1的Alpha 1版本已经N月没有check ...