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]
The method addends with 3
3
The method sub begins with[3, 2]
The method subends with 1
1

动态代理实现前置通知 , 后置通知 , 返回通知 , 异常通知:

 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入门动态代理的更多相关文章

  1. 浅谈Spring的AOP实现-动态代理

    说起Spring的AOP(Aspect-Oriented Programming)面向切面编程大家都很熟悉(Spring不是这次博文的重点),但是我先提出几个问题,看看同学们是否了解,如果了解的话可以 ...

  2. 【Java EE 学习 51】【Spring学习第三天】【cglib动态代理】【AOP和动态代理】【切入点表达式】

    一.cglib动态代理 1.简介 (1)CGlib是一个强大的,高性能,高质量的Code生成类库.它可以在运行期扩展Java类与实现Java接口. (2) 用CGlib生成代理类是目标类的子类. (3 ...

  3. Spring中的cglib动态代理

    Spring中的cglib动态代理 cglib:Code Generation library, 基于ASM(java字节码操作码)的高性能代码生成包 被许多AOP框架使用 区别于JDK动态代理,cg ...

  4. Spring中的JDK动态代理

    Spring中的JDK动态代理 在JDK1.3以后提供了动态代理的技术,允许开发者在运行期创建接口的代理实例.在Sun刚推出动态代理时,还很难想象它有多大的实际用途,现在动态代理是实现AOP的绝好底层 ...

  5. Spring事务Transactional和动态代理(二)-cglib动态代理

    系列文章索引: Spring事务Transactional和动态代理(一)-JDK代理实现 Spring事务Transactional和动态代理(二)-cglib动态代理 Spring事务Transa ...

  6. Spring事务Transactional和动态代理(三)-事务失效的场景

    系列文章索引: Spring事务Transactional和动态代理(一)-JDK代理实现 Spring事务Transactional和动态代理(二)-cglib动态代理 Spring事务Transa ...

  7. AOP与动态代理有什么联系

    曾遇到“AOP与动态代理有什么联系”的问题,现把个人观点整理如下: 我觉得,动态代理是AOP的主要实现手段之一,AOP是动态代理的一种应用深化 AOP是一种思想,或者是方法论,类似OOP,是OOP的有 ...

  8. Spring事务Transactional和动态代理(一)-JDK代理实现

    系列文章索引: Spring事务Transactional和动态代理(一)-JDK代理实现 Spring事务Transactional和动态代理(二)-cglib动态代理 Spring事务Transa ...

  9. [原创]java WEB学习笔记104:Spring学习---AOP 前奏,通过一个问题引入动态代理

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

随机推荐

  1. ABAP CDS - 字符串函数

    下表显示了ABAP CDS中CDS视图中字符串的潜在SQL函数,以及对参数的要求.函数的含义可以在字符串的SQL函数下找到. 函数 参数类型 返回类型 CONCAT(arg1, arg2) See b ...

  2. P1509 找啊找啊找GF

    P1509 找啊找啊找GF 题目背景 "找啊找啊找GF,找到一个好GF,吃顿饭啊拉拉手,你是我的好GF.再见." "诶,别再见啊..." 七夕...七夕...七 ...

  3. [网站公告]18:07-18:20阿里云SLB故障造成网站不能正常访问

    (注:由于阿里云SLB管理控制台监控数据不准,实际故障时间是18:07-18:20.) 17:55-18:2018:07-18:20,我们使用的阿里云SLB(负载均衡)中有3台出现突发故障,造成全站无 ...

  4. windows 无法上网问题解决一例

    dhcp获取ip地址,网卡驱动和ip地址获取正常,ping www.baidu.com可以ping通,但是打开浏览器或者qq上网不行,而且系统有提示腾讯管家出错的信息,初步怀疑360和腾讯管家打架导致 ...

  5. 护网杯 three hit 复现(is_numeric引发的二次注入)

    1.题目源码 https://github.com/ZhangAiQiang/three-hit 题目并不真的是当时源码,是我根据做法自己写的,虽然代码烂,但是还好能达到复现的目的 ,兄弟们star一 ...

  6. 第一篇 Python安装与环境变量的配置

    开发语言有很多种,为什么选Python? 先对各种开发语言做个初识和分类如下:高级语言:Python Java.PHP C# Go ruby C++... ---> 字节码低级语言:C.汇编 - ...

  7. docker简单命令

    查看镜像 docker images 查看正在使用的容器 docker ps -a 进入容器控制台 docker exec -it 容器ID bash 启动镜像 docker run -it -d.. ...

  8. (Python爬虫01)-本想给随笔加个序号才发现这么不方便

    本想给随机加个序号,才发现还得去返回看看文章的序号.好在cnblog能断点自动保存. 作为一个小程序员,点赞的同时还在想,谁知道咋实现这种实时保存呢?有知道的给个参考文档呗.太感激了! 重点在这里 有 ...

  9. spring boot 过滤器实现接收 压缩数据 并解压

    1.新加类GzipRequestWrapper 继承HttpServletRequestWrapper类 public class GzipRequestWrapper extends HttpSer ...

  10. c# 对List<T> 某字段排序,取TOP条数据

    //排序的对象里的字段数据准备 try { cmr.v4 = Double.Parse(cmr.v3) - Double.Parse(cmr.v2); } catch (Exception e) { ...