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. hdu畅通工程(并查集)

    Problem Description 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道 ...

  2. Java检测端口的占用情况

    突然间想到这个问题,在网上搜了一下 http://blog.csdn.net/danieluk/article/details/18518175 网上有很多文章都是用上面那个方法来解决这个问题的,总感 ...

  3. APP功能性测试-4

    弱网络测试 使用fiddler模拟低速环境 使用fiddler抓取手机上某个应用的包 手机连接fiddler fiddler 代理地址127.0.0.1默认端口8888 只抓http协议(https, ...

  4. 九度OJ--Q1164

    import java.util.Scanner; /* * 题目描述: * 任意输入两个9阶以下矩阵,要求判断第二个是否是第一个的旋转矩阵,如果是,输出旋转角度(0.90.180.270),如果不是 ...

  5. 数据结构-排序-shell排序

    shell排序 首先,希尔排序适用于待排序列关键有序. 接下来一步步图解SHELL排序 我为了方便理解内部操作.我先把代码输出整理下. #include<iostream> #includ ...

  6. PHP Fatal error: Undefined class constant 'MYSQL_ATTR_INIT_COMMAND'

    最近用ThinkPHP,给公司布置线上的网站的时候,遇到的一个问题,记录一下. 打开IE浏览器的设置,Internet选项里的高级,将”显示友好的HTTP错误消息“前都勾去掉! 再次刷新,看到的错误是 ...

  7. Java项目启动时候报Neither the JAVA_HOME nor the JRE_HOME environment variable is defined 解决办法

    今天在发布Java项目的时候又遇到    Neither the JAVA_HOME nor the JRE_HOME environment variable is defined  At leas ...

  8. Week1 Team Homework #1 from Z.XML-项目选择思路--基于对曾经大作业项目的思考

    这两天试玩了一下去年学长的满分工程<shield star>游戏,再结合了一下他们团队的博客记录,有一种非常牛逼的感觉.具体对于这款游戏的一些思考和看法,毛大神已经说的很好了.因此,这里主 ...

  9. Java 8手动实现一个Collector

    我们看一下Stream中的collect的方法. collect(toList())方法由Stream里的值生成一个列表,是一个及早求值的操作. Stream的of方法使用一个初始值生成新的Strea ...

  10. c#和html方法互调

    具体见连接:https://www.cnblogs.com/zeroLove/p/3912460.html