JAVA代理相关主要知识如下:

(1)利用代理可以在运行时创建一个实现了一组给定接口的新类。

        这种功能只有在编译时无法确定需要实现哪个接口时才有必要使用。



(2)假设有一个表示接口的Class对象,它的确切类型在编译时无法知道。

        要想构建一个实现接口的类,就需要使用NewInstance方法或反射找出这个类的构造器。

        但是不能实例化一个接口,需要在程序处于运行状态时定义一个新类。



(3)为解决这个问题,有些程序将会生成代码,将这些代码放置在一个文件中,使用编译器,然后再加载结果类文件。

        针对上述繁琐的过程,可以使用代理机制。

        代理机制是一种很好的解决方案,代理类可以再运行时创建全新的类,这样的代理类能够实现指定的接口。

        但是,这样做的速度会比较的慢,且需要将编译器与程序放在一起。



(4)它具有下列的方法:

       (a)指定接口所需要的全部方法。

       (b)Object类中的全部方法,例如toString、equals等。



(5)但是不能在运行时定义这些方法,需要提供一个调用处理器(Invocationhandler)。

         调用处理器是实现了Invocationhandler接口的类对象。

         这个接口只有一个方法:

                        Object invoke(Object proxy, Method method, Object[] args)



(6)无论何时调用代理对象方法,调用处理器的invoke方法都会被调用,并向其传递Method对象和原始的调用参数。



(7)要创建以一个代理对象,需使用Proxy类的NewProxyInstance方法。方法的三个参数为:

       (a)一个类加载器。

       (b)一个Class对象数组,每个元素都是需要实现的接口。

       (c)一个调用处理器。



(8)代理类的特性:

        代理类实在程序运行过程中创建的,一旦被创建,就变成常规类了。

        所有的代理类都扩展于Proxy类。一个代理类只有一个实例域——调用处理器。它定义在Proxy超类中,

        为了履行代理对象的职责,所需要的任何附加数据都必须存储在调用处理器中。 

        所有代理类都覆盖了Object类中的toString、equals和hashCode方法。



(9)对于特定的类加载器和预设的一组接口来说,只能有一个代理类。

        如果使用同一个类加载器的接口数组调用两次newProxyInstance方法,那么只能得到同一个类的两个对象,

        也可以使用getProxyClass方法获得这个类:

                     Class proxyClass = Proxy.getProxyClass(null, interfaces);



(10)代理类一定是public和final。

        如果代理类实现的所有接口都是public,代理类就不属于某个特定的包;

        否则,所有非公有的接口都必须属于同一个包,同时,代理类也属于这个包。

        可以通过调用Proxy类中的isProxyClass方法检测一个特定的Class对象是否代表一个代理类。



        通过下面的代码展示,能够让我们进一步的理解代理类及其运行机制:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Random;

public class TestProxy {
	public static void main(String[] args) {
		Object[] elements = new Object[1000];
		for (int i = 0; i < elements.length; i++) {
			Integer value = i + 1;
			/**创建调用处理器**/
			InvocationHandler handle = new TraceHandler(value);
			/**创建代理类对象**/
			Object proxy = Proxy.newProxyInstance(null, new Class[] { Comparable.class }, handle);
			elements[i] = proxy;
		}

		Integer key = new Random().nextInt(elements.length) + 1;
		int result = Arrays.binarySearch(elements, key);
		if (result >= 0)
			System.err.println(elements[result]);
	}
}

class TraceHandler implements InvocationHandler {
	private Object target;

	public TraceHandler(Object t) {
		target = t;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
		System.err.print(target);
		System.err.print("." +method.getName()+"(");
		if (args != null) {
			for (int i = 0; i < args.length; i++) {
				System.err.print(args[i]);
				if (i < args.length - 1)
					System.err.print(", ");
			}
		}
		System.err.println(")");
		/**执行method所代表的包含指定参数的方法**/
		return method.invoke(target, args);
	}
}

JAVA代理机制的更多相关文章

  1. Java代理机制之初见(理解及实现)

    都知道Java中的Spring,有一重要思想:AOP,实现原理也就是Java的动态代理机制.初见代理这个名词时,觉得生活中常有代理的这一说法. 那么,在Java中,代理又是什么呢?它又是如何实现的?实 ...

  2. 从头捋了一遍 Java 代理机制,收获颇丰

    尽人事,听天命.博主东南大学硕士在读,热爱健身和篮球,乐于分享技术相关的所见所得,关注公众号 @ 飞天小牛肉,第一时间获取文章更新,成长的路上我们一起进步 本文已收录于 「CS-Wiki」Gitee ...

  3. Java 代理机制

    Table of Contents 1 引言 2 常见的代理 3 代理模式UML图 4 代理模式实例 5 java动态代理 5.1 java动态代理UML图 6 代理模式与装饰者模式的区别 6.1 装 ...

  4. 黑马程序猿_Java 代理机制学习总结

    -------<a href="http://www.itheima.com/"">android培训</a>.<a href=" ...

  5. Java 动态代理机制详解

    在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...

  6. java的动态代理机制详解

    在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...

  7. java Proxy(代理机制)

    我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的我们的功能,我们更需要学习 ...

  8. 学习AOP之JAVA的代理机制

    从一个输出日志的实例分析JAVA的代理机制 一.通用的日志输出方法  :需要在每个类里都增加对输出日志信息的代码 二.通过面向接口编程实现日志的输出(JAVA的静态代理):虽然实现了业务逻辑与输出日志 ...

  9. java中的动态代理机制

    java中的动态代理机制 在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface).另一个则是 Proxy(Class),这一个类和接口是实现 ...

随机推荐

  1. 数据挖掘_requests模块的get方法

    关于requests模块 之前在跟大家讲通过字典列表批量获取数据的时候用过这个模块 安装过程就不再讲解了 requests模块是python的http库,可以完成绝大部分与http应用相关的工作,所以 ...

  2. @RequestBody和@RequestParam区别

    @RequestParam 用来处理Content-Type: 为 application/x-www-form-urlencoded编码的内容.(Http协议中,默认传递的参数就是applicati ...

  3. 152. Maximum Product Subarray(中等, 神奇的 swap)

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  4. centos 6安装opencv

    昨天装好的,今天有些细节已经记不起来里,大致写一下吧. 首先,从opencv官网下载linux的opencv-2.4.9安装包,下载地址:http://jaist.dl.sourceforge.net ...

  5. zabbix API基本使用方法介绍

    前言: 以下内容根据zabbix 3.2官方文档总结:https://www.zabbix.com/documentation/3.2/manual/api 此文档只是简单的介绍API的基本使用,关于 ...

  6. Android开发技巧——使用Drawable实现小红点

    在产品的设计中,总难免需要我们开发去实现各种各样的小红点,小红点,小红点. 通常,我们可能会这样做: 用一个View实现小红点,放在相对布局里,设置好内边距或外边距,让它位于图片的右上角. 或者是给图 ...

  7. windows上安装nodejs,升级npm,安装webpack指南

    安装nodejs https://nodejs.org/en/ 安装webpack和其他一些常用的 npm install -g node-gyp webpack coffee-script 监控 w ...

  8. tomcat内存溢出解决,java.lang.OutOfMemoryError: PermGen space

    今天遇到了一个java.lang.OutOfMemoryError: PermGen space异常问题,一直解决不了,根据网上修改了tomcat的配置文件,但是还是解决不了,最后是通过如下方式解决的 ...

  9. Linux下C/C++程序调试基础(GCC,G++,GDB,CGDB,DDD)

    在写程序的时候,经常会遇到一些问题,比如某些变量计算结果不是我们预期的那样,这时我们需要对程序进行调试.本文主要介绍调试C/C++在Linux操作系统下主要的调试工具. 在Linux下写程序,C/C+ ...

  10. linux下的清屏命令

    Linux下有两个清屏命令: clear 这个命令将会刷新屏幕,系统的操作是让终端显示页向后翻了一页,如果向上滚动屏幕还可以看到之前的操作信息.一般都会使用这个命令. reset 这个命令将完全刷新终 ...