Spring学习-- AOP入门动态代理
AOP 的拦截功能是由 java 中的动态代理来实现的。说白了,就是在目标类的基础上增加切面逻辑,生成增强的目标类(该切面逻辑或者在目标类函数执行之前,或者目标类函数执行之后,或者在目标类函数抛出异常时候执行。不同的切入时机对应不同的Interceptor的种类,如BeforeAdviseInterceptor,AfterAdviseInterceptor以及ThrowsAdviseInterceptor等)。
package com.itdoc.spring.aop.proxy; /**
* http://www.cnblogs.com/goodcheap
*
* @author: Wáng Chéng Dá
* @create: 2017-03-03 19:34
*/
public interface Arithmetic { int add(int i, int j); int sub(int i, int j); int mul(int i, int j); int div(int i, int j); }
package com.itdoc.spring.aop.proxy; /**
* http://www.cnblogs.com/goodcheap
*
* @author: Wáng Chéng Dá
* @create: 2017-03-03 19:35
*/
public class ArithmeticProxyImpl implements Arithmetic {
@Override
public int add(int i, int j) {
int result = i + j;
return result;
} @Override
public int sub(int i, int j) {
int result = i - j;
return result;
} @Override
public int mul(int i, int j) {
int result = i * j;
return result;
} @Override
public int div(int i, int j) {
int result = i / j;
return result;
}
}
package com.itdoc.spring.aop.proxy; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays; /**
* http://www.cnblogs.com/goodcheap
*
* @author: Wáng Chéng Dá
* @create: 2017-03-03 19:45
*/
public class ArithmeticProxyHandle { //要代理的对象
private Arithmetic target; public ArithmeticProxyHandle(Arithmetic target) {
this.target = target;
} public ArithmeticProxyHandle() {
} public Arithmetic getLoggingProxy() {
Arithmetic proxy = null;
//代理对象由哪个类加载器负责加载
ClassLoader loader = target.getClass().getClassLoader();
//代理对象的类型, 即其中有哪些方法
Class [] interfaces = new Class[]{Arithmetic.class};
//当调用代理对象中的方法时, 执行该代码
InvocationHandler h = new InvocationHandler() {
/**
*
* @param proxy 正在返回的那个代理对象, 一般情况下, 在 invoke 方法中都不使用该对象。
* @param method 正在被调用的方法。
* @param args 调用方法时, 传入的参数。
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String name = method.getName();
System.out.println("The method " + name + " begins with" + Arrays.asList(args));
Object result = method.invoke(target, args);
System.out.println("The method " + name + "ends with " + result);
return result;
}
};
proxy = (Arithmetic) Proxy.newProxyInstance(loader, interfaces, h);
return proxy;
}
}
package com.itdoc.spring.aop.proxy; /**
* http://www.cnblogs.com/goodcheap
*
* @author: Wáng Chéng Dá
* @create: 2017-03-03 19:42
*/
public class Main { public static void main(String[] args) {
Arithmetic arithmetic = new ArithmeticProxyImpl();
arithmetic = new ArithmeticProxyHandle(arithmetic).getLoggingProxy(); int result = arithmetic.add(1, 2);
System.out.println(result);
result = arithmetic.sub(3, 2);
System.out.println(result); }
}
控制台输出:
The method add begins with[1, 2] |
动态代理实现前置通知 , 后置通知 , 返回通知 , 异常通知:
package com.itdoc.spring.aop.proxy; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays; /**
* http://www.cnblogs.com/goodcheap
*
* @author: Wáng Chéng Dá
* @create: 2017-03-03 19:45
*/
public class ArithmeticProxyHandle { //要代理的对象
private Arithmetic target; public ArithmeticProxyHandle(Arithmetic target) {
this.target = target;
} public ArithmeticProxyHandle() {
} public Arithmetic getLoggingProxy() {
Arithmetic proxy = null;
//代理对象由哪个类加载器负责加载
ClassLoader loader = target.getClass().getClassLoader();
//代理对象的类型, 即其中有哪些方法
Class [] interfaces = new Class[]{Arithmetic.class};
//当调用代理对象中的方法时, 执行该代码
InvocationHandler h = new InvocationHandler() {
/**
*
* @param proxy 正在返回的那个代理对象, 一般情况下, 在 invoke 方法中都不使用该对象。
* @param method 正在被调用的方法。
* @param args 调用方法时, 传入的参数。
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String name = method.getName();
Object result = null;
try {
//前置通知
System.out.println("The method " + name + " begins with" + Arrays.asList(args));
//执行方法
result = method.invoke(target, args);
//返回通知
System.out.println("The method " + name + " ends with " + result);
} catch (Exception e) {
Throwable ex = new Throwable("出现异常", e);
//异常通知
System.out.println("The method " + name + " exception with " + ex);
} finally {
//后置通知
System.out.println("The method " + name + " ends");
}
return result;
}
};
proxy = (Arithmetic) Proxy.newProxyInstance(loader, interfaces, h);
return proxy;
}
}
Spring学习-- AOP入门动态代理的更多相关文章
- 浅谈Spring的AOP实现-动态代理
说起Spring的AOP(Aspect-Oriented Programming)面向切面编程大家都很熟悉(Spring不是这次博文的重点),但是我先提出几个问题,看看同学们是否了解,如果了解的话可以 ...
- 【Java EE 学习 51】【Spring学习第三天】【cglib动态代理】【AOP和动态代理】【切入点表达式】
一.cglib动态代理 1.简介 (1)CGlib是一个强大的,高性能,高质量的Code生成类库.它可以在运行期扩展Java类与实现Java接口. (2) 用CGlib生成代理类是目标类的子类. (3 ...
- Spring中的cglib动态代理
Spring中的cglib动态代理 cglib:Code Generation library, 基于ASM(java字节码操作码)的高性能代码生成包 被许多AOP框架使用 区别于JDK动态代理,cg ...
- Spring中的JDK动态代理
Spring中的JDK动态代理 在JDK1.3以后提供了动态代理的技术,允许开发者在运行期创建接口的代理实例.在Sun刚推出动态代理时,还很难想象它有多大的实际用途,现在动态代理是实现AOP的绝好底层 ...
- Spring事务Transactional和动态代理(二)-cglib动态代理
系列文章索引: Spring事务Transactional和动态代理(一)-JDK代理实现 Spring事务Transactional和动态代理(二)-cglib动态代理 Spring事务Transa ...
- Spring事务Transactional和动态代理(三)-事务失效的场景
系列文章索引: Spring事务Transactional和动态代理(一)-JDK代理实现 Spring事务Transactional和动态代理(二)-cglib动态代理 Spring事务Transa ...
- AOP与动态代理有什么联系
曾遇到“AOP与动态代理有什么联系”的问题,现把个人观点整理如下: 我觉得,动态代理是AOP的主要实现手段之一,AOP是动态代理的一种应用深化 AOP是一种思想,或者是方法论,类似OOP,是OOP的有 ...
- Spring事务Transactional和动态代理(一)-JDK代理实现
系列文章索引: Spring事务Transactional和动态代理(一)-JDK代理实现 Spring事务Transactional和动态代理(二)-cglib动态代理 Spring事务Transa ...
- [原创]java WEB学习笔记104:Spring学习---AOP 前奏,通过一个问题引入动态代理
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
随机推荐
- js分类多选全选
效果如图: HTML代码: <div class="form-group quanxian-wrap"> <label>项目</label> & ...
- JAVA中堆栈和内存分配详解(摘抄)
在Java中,有六个不同的地方可以存储数据: 1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制. 2. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存 ...
- cf987f AND Graph
#include <iostream> #include <cstdio> using namespace std; int n, uu, m; bool a[4500005] ...
- Lambda方式左连接有Linq方式左连接
网上查到的直接使用Join+DefaultIfEmpty的方式是错误的,实际生成SQL是两表先内联接,然后再LEFT JOIN.经过查证,参考资料,最终得到如下两种方式的左连接写法: public v ...
- Python 3 学习笔记之——错误和异常
1. 语法错误 Python 的语法错误被称为解析错,语法分析器会指出出错的代码行,并且在最先找到的错误的位置标记一个小小的箭头. >>> while True File " ...
- 软工实践Beta冲刺(6/7)
队名:起床一起肝活队 组长博客:博客链接 作业博客:班级博客本次作业的链接 组员情况 组员1(队长):白晨曦 过去两天完成了哪些任务 描述: 1.界面的修改与完善 展示GitHub当日代码/文档签入记 ...
- To Chromium之版本管理
Git. 1.由于想直接submit到Chromium的官方Branch需要申请权限,目前拿不到,所以打算snapshot一个chromium版本. 本地搭建一个git的server/client,方 ...
- Runnable、Callable、Future和CompletableFuture
一.Runnable Runnable非常简单,只需要实现一个run方法即可,没有参数,也没有返回值.可以以new Thread的方式去运行,当然更好的方式在放到excutorPool中去运行. 二. ...
- Android 实现异步加载图片
麦洛开通博客以来,有一段时间没有更新博文了.主要是麦洛这段时间因项目开发实在太忙了.今天周六还在公司加班,苦逼程序猿都是这样生活的. 今天在做项目的时候,有一个实现异步加载图片的功能,虽然比较简单但还 ...
- ThreadLocal 验明正身
一.前言 之前ThreadLocal使用不多,有个细节也就注意不到了:ThreadLocal在多线程中到底起什么作用?用它保存的变量在每个线程中,是每个线程都保存一份变量的拷贝吗?带着这些问题,我查了 ...