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 前奏,通过一个问题引入动态代理
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
随机推荐
- 前端技术Jquery与Ajax使用总结
前端技术Jquery与Ajax使用总结 虽然主要是做的后端,但是由于有些时候也要写写前台的界面,因此也就学习了下Jquery和Ajax的一些知识,虽说此次写的这些对于前端大神来说有些班门弄斧的感觉,但 ...
- 玩转VIM之将Vim全副武装
玩转VIM之将Vim全副武装 懒癌末期的我貌似很久没有写博客了,已经欠了多少篇在计划中的博客我已然不好意思说了.好了,言归正传,在前三篇介绍了Vim作为代码编辑器之后可能会有人说,要学习那么多指令真的 ...
- PyQt的QString和python的string的区别
转载于http://blog.chinaunix.net/uid-200142-id-4018863.html python的string和PyQt的QString的区别 python string和 ...
- python学习总结----内置函数及数据持久化
抽象基类(了解) - 说明: - 抽象基类就是为了统一接口而存在的 - 它不能进行实例化 - 继承自抽象类的子类必须实现抽象基类的抽象方法 - 示例: from abc import ABC, abs ...
- 安装配置hadoop
在master中安装并且配置hadoop (1).将hadoop-2.6.4.tar.gz安装包复制到hadoop文件目录下(直接赋值进去就行) (2).解压安装包haoddp-2.6.4.tar.g ...
- 参加2018之江杯全球人工智能大赛 :视频识别&问答(四)
很遗憾没有在规定的时间点(2018-9-25 12:00:00)完成所有的功能并上传数据,只做到写了模型代码并只跑了一轮迭代,现将代码部分贴出. import keras from keras.lay ...
- 九度OJ--Q1166
import java.text.DecimalFormat;import java.util.Scanner; /* * 题目描述: * 立方根的逼近迭代方程是 y(n+1) = y(n)*2/3 ...
- 时间动态协同过滤(TimeSVD++)
原作者 原论文地址 http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.379.1951&rep=rep1&type=pd ...
- [leetcode-640-Solve the Equation]
Solve a given equation and return the value of x in the form of string "x=#value". The equ ...
- C++STL——堆栈
一.相关定义 原理:stack队列是一个线性存储表,插入和删除只在栈顶进行,从而构成了一个后进先出LIFO表. 入栈&出栈:元素的插入称为入栈,元素的删除称为出栈. stack是一种关联容器, ...