动态代理属于Java反射的一种。

当我们得到一个对象,想动态的为其一些方法每次被调用前后追加一些操作时,我们将会用到java动态代理。

下边上代码:

首先定义一个接口:

package com.liuyx;

public interface Itf {
public abstract void printMe(); public abstract void printSth(String me);
}

接着是它的实现:

package com.liuyx;

public class Cls implements Itf {

    @Override
public void printMe() {
System.out.println("I'm Cls!");
} @Override
public void printSth(String str) {
System.out.println(str);
} }

我们的目的就是通过动态代理技术,在Cls这个类的对象的两个方法执行前后,加上一些打印操作。

现在我们实现一个InvocationHandler,把我们想要通过代理者被代理者追加的操作都写在invoke方法里面:

package com.liuyx;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class StandardInvocation implements InvocationHandler { private Object obj; StandardInvocation(Object obj){
this.obj=obj;
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before method excute!");
Object result = method.invoke(obj, args);
System.out.println("after method excute!");
return result;
} }

首先、这里面有一个obj,这个obj是必须的,我们既然要做代理,我们必须知道我们是给谁做代理,这里的obj就是被代理者。

动态代理说到底也是代理,代理模式里就要求有一个被代理者。

然后是invoke的三个参数、第一个参数就是代理者,如果你想对代理者做一些操作可以使用这个参数;第二个就是被执行的方法,第三个是执行该方法所需的参数。

当你执行代理者的某个方法的时候,最后跑的都是invoke方法。

然后是用法:

    public static void main(String[] args) {
//创建一个被代理者
Cls c = new Cls();
//创建一个InvocationHandler,描述我们希望代理者执行哪些操作
InvocationHandler i = new StandardInvocation(c);
//通过刚才创建的InvocationHandler,创建真正的代理者。第一个参数是类加载器,第二个参数是这个代理者实现哪些接口
Itf pxy = (Itf) Proxy.newProxyInstance(Cls.class.getClassLoader(), new Class[] { Itf.class }, i);
pxy.printSth("Hi");
}

pxy就是c的代理者。

最后来一个稍微改进的写法:

package com.liuyx;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class InvocationHandlerTest implements InvocationHandler { private Object target; Object bind(Object i) {
target = i;
Object warpedItf;
warpedItf = Proxy.newProxyInstance(target.getClass().getClassLoader(), i.getClass().getInterfaces(), this);
return warpedItf;
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before method excute!");
method.invoke(target, args);
System.out.println("after method excute!");
return null;
} public static void main(String[] args) {
Cls c = new Cls();
InvocationHandlerTest pxy = new InvocationHandlerTest();
Itf itf = (Itf)pxy.bind(c);
itf.printSth("Hello");
} }

java动态代理有一定局限性,需要定义至少一个接口,使用cglib则不必如此。

java 动态代理(模式) InvocationHandler(为类中方法执行前或后添加内容)的更多相关文章

  1. java 动态代理范例 InvocationHandler与Proxy

    java 动态代理范例 InvocationHandler与Proxy,拦截与代理 java.lang.reflect.Proxy,Proxy 提供用于创建动态代理类和实例的静态方法.newProxy ...

  2. JAVA动态代理模式(从现实生活角度理解代码原理)

    所谓动态代理,即通过代理类:Proxy的代理,接口和实现类之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联. java动态代理主要是使用java.lang.reflect包中的两个 ...

  3. Java动态代理之InvocationHandler最简单的入门教程

    网上关于Java的动态代理,Proxy和InvocationHandler这些概念有讲解得非常高深的文章.其实这些概念没有那么复杂.现在咱们通过一个最简单的例子认识什么是InvocationHandl ...

  4. 关于java动态代理模式

    1. 动态代理 动态代理就是通过代理类是代理类与相关接口不直接发生联系,而在运行期(Runtime)实现动态关联. 动态代理主要用到java.lang.reflect包中的两个类,Invocation ...

  5. java动态代理模式

    java动态代理机制详解 Spring的核心AOP的原理就是java的动态代理机制. 在java的动态代理机制中,有两个重要的类或接口: 1.InvocationHandler(Interface): ...

  6. java 动态代理模式(jdk和cglib)

    package proxy.dynamicproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Met ...

  7. 深度模拟java动态代理实现机制系类之三

    这里的内容就比较复杂了,要实现的是对任意的接口,对任意指定的方法,以及对任意指定的代理类型进行代理,就更真实的模拟出java虚拟机的动态代理机制 罗列一下这里涉及的类.接口之间的关系,方便大家学习.1 ...

  8. Java动态代理模式浅析

    Java代理设计模式 - 静态代理 Java中的动态代理 - 调用处理器 代理设计模式的UML图: 我将首先介绍Java中的各种代理实现方法 Java代理设计模式 - 静态代理 这个例子非常简单,只有 ...

  9. Java 动态代理模式浅析

    目录 Java代理设计模式 - 静态代理 静态代理的优点 静态代理的缺点 Java中的动态代理 - 调用处理器 主要笔记: 动态代理类的限制 代理设计模式的UML图: 我将首先介绍Java中的各种代理 ...

随机推荐

  1. bzoj 2152

    /************************************************************** Problem: 2152 User: idy002 Language: ...

  2. ZOJ 3213 Beautiful Meadow 简单路径 插头DP

    简单路径的题目,其实就是在状态后面多记了有多少个独立插头. 分类讨论独立插头: 1.只存在上插头或者左插头,可以选择作为独立插头. 2.都不存在上插头和左插头,选择作为独立插头的同时要标号为新的连通块 ...

  3. JavaScript学习笔记 isPrototypeOf和hasOwnProperty使用区别

    1.isPrototypeOf isPrototypeOf是用来判断指定对象object1是否存在于另一个对象object2的原型链中,是则返回true,否则返回false. 格式如下: object ...

  4. Linux下swap分区多大才合适的问题探讨

    说明: 1.这个话题在每个Linux发行版中都各不相同,且在当下内存硬盘的时代下,再组个磁盘阵列之后速度相当. 2.我觉得硬盘大的情况下,有多大搞多大,我只要控制内存的使用率在99%时才使用swap, ...

  5. 给WebAPI的REST接口添加测试页面(三)

    在前面的文章中,我介绍过了通过Swashbuckle在WebAPI中集成Swagger-UI.不过这种方式不适合于最新版的ASP.Net MVC6下的WebAPI,在网上搜了一下,发现了它还有一个专供 ...

  6. Android中MVC模型(复合模式)

    mvc是model,view,controller的缩写,mvc包括三个部分: 1.模型(model)对象:是应用程序的主体部分,全部的业务逻辑都应该写在该层. 2.视图(view)对象:是应用程序中 ...

  7. 无法执行磁盘检查因为windows无法访问

    固态硬盘迁移系统后,将原先的系统盘(H,重新系统后固态硬盘的主分区变为了C盘)格式化,并和邻近的D盘合并.合并后,将盘符重新改为D盘,而D盘原有的软件安装目录Program Files无法识别,显示目 ...

  8. java 调用shell命令

    原文:http://kongcodecenter.iteye.com/blog/1231177 Java通过SSH2协议执行远程Shell脚本(ganymed-ssh2-build210.jar)   ...

  9. python笔记17-字典如何按value排序

    前言 面试题:如何统计数组中出现次数最多的数据,按出现次数由大到小排序 这个排序看似简单,涉及到的基础知识点还是很多的,真正写起来并不容易 备注:本篇是以python3.6讲解的,python2会多一 ...

  10. 使用富文本OHAttributedLabel

    OHAttributedLabel 富文本标签 https://github.com/AliSoftware/OHAttributedLabel 以下是我渲染出来的效果 OHAttributedLab ...