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 前奏,通过一个问题引入动态代理
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
随机推荐
- Hadoop2.5.2集群部署(完全分布式)
环境介绍 硬件环境 CPU 4 MEM 4G 磁盘 60G 软件环境 OS:centos6.5版本 64位 Hadoop:hadoop2.5.2 64位 JDK: JDK 1.8.0_91 主机配置 ...
- OpenCV实现SIFT图像拼接源代码
OpenCV实现SIFT和KDtree和RANSAC图像拼接源代码,此源代码由Opencv2.4.13.6和VC++实现,代码本人已经调试过,完美运行,效果如附图.Opencv2.4.13.6下载地址 ...
- 容器基础(三): 使用Cgroups进行资源限制
Linux Cgroups Linux Cgroups 是 Linux 内核中用来为进程设置资源限制的一个重要功能. Cgroups将进程进行分组, 然后对这一组进程进行统一的资源监控和限制.Cgro ...
- thinkPHP form表单提交参数无法获取
后台打印获取的数据为empty, 找了半天,是因为 input标签没有写name, 真是醉了!记一下,免得以后再犯错了.
- Linux pthread 线程池实现
基于pthread封装了一个简易的ThreadPool,具有以下特性: 1.具有优先级的任务队列 2.线程池大小可以二次调整,增加线程或者删除空闲线程 3.任务两种重写方式,重写run或者使用函数回调 ...
- mysql原理以及相关优化
说起MySQL的查询优化,相信大家积累一堆技巧:不能使用SELECT *.不使用NULL字段.合理创建索引.为字段选择合适的数据类型..... 你是否真的理解这些优化技巧?是否理解其背后的工作原理?在 ...
- Asp.Net生命周期系列一
Asp.Net生命周期对于初级甚至中级程序员来说,一直都是一个难题,很多程序员不了解生命周期,导致使用Asp.Net做开发感觉很不灵活,感觉太多东西被微软封装好了,我们不能改变,其实只要你稍微了解一下 ...
- chm文件空白如何解决
解决办法:http://jingyan.baidu.com/article/8275fc86b5fb6646a03cf6b0.html
- feof问题
feof()函数是我们C语言中操作文件常见的函数,也是我们最容易出错的函数 这个函数用来表示文件指针是否已经到了文件末尾的下一个位置.这个函数是通用的 可以用在文本文件和二进制文件 (EOF是文件结束 ...
- 算法(8)Maximum Product Subarray
题目:在一个数组中找到一个子数组,让子数组的乘积最大,比如[2,3,-2,4]返回6 思路:之前自己想到的思路是对于一个int类型的数组,只要负数的个数是偶数,那么乘积肯定是全局乘就可以了,然后对于负 ...