静态代理与动态代理二

           

   动态代理的实现是基于java的三种API的,下面先来介绍一下:

           1、java.lang.reflect.Proxy

            这是 Java 动态代理机制生成的所有动态代理类的父类,它提供了一组静态方法来为一组接口动态地生成代理类及其对象。          

<span style="font-size:14px;">// 方法 1: 该方法用于获取指定代理对象所关联的调用处理器
static InvocationHandler getInvocationHandler(Object proxy) 

// 方法 2:该方法用于获取关联于指定类装载器和一组接口的动态代理类的类对象
static Class getProxyClass(ClassLoader loader, Class[] interfaces) 

// 方法 3:该方法用于判断指定类对象是否是一个动态代理类
static boolean isProxyClass(Class cl) 

// 方法 4:该方法用于为指定类装载器、一组接口及调用处理器生成动态代理类实例
static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
</span>

          当然啦,我觉得这些方法不需要记住,只需要在用的时候去查API,多用也就容易上手啦~~

         2、java.lang.reflect.InvocationHandler

           这是调用处理器接口,它自定义了一个 invoke 方法,用于集中处理在动态代理类对象上的方法调用,通常在该方法中实现对委托类的代理访问。每次生成动态代理类对象时都要指定一个对应的调用处理器对象。 
       

<span style="font-size:14px;">// 该方法负责集中处理动态代理类上的所有方法调用。第一个参数既是代理类实例,第二个参数是被调用的方法对象
// 第三个方法是调用参数。调用处理器根据这三个参数进行预处理或分派到委托类实例上反射执行
Object invoke(Object proxy, Method method, Object[] args)
</span>

         3、java.lang.ClassLoader(看到java类装载器,突然想到drp的时候还提到了tomcat类装载器)

        这是类装载器类,负责将类的字节码装载到 Java 虚拟机(JVM)中并为其定义类对象,然后该类才能被使用。Proxy 静态方法生成动态代理类同样需要通过类装载器来进行装载才能使用,它与普通类的唯一区别就是其字节码是由 JVM 在运行时动态生成的而非预存在于任何一个 .class 文件中。
每次生成动态代理类对象时都需要指定一个类装载器对象 。

       下面用和上边相似的例子说一下:

       1、  创建一个处理器,用来动态生成代理

<span style="font-size:14px;">/****************创建自己的调用处理器 *****************/
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class TestInvocationHandler implements <span style="color:#ff0000;">InvocationHandler</span> {

	//代理类持有委托类的引用
	private Object delegate;

	public TestInvocationHandler(Object delegate){
		this.delegate=delegate;
	}

	/**
	 * @param proxy:代理类实例
	 * @param method:被调用的方法
	 * @param args:参数
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		long stime = System.currentTimeMillis();
		  //利用反射机制将请求分派给委托类处理。Method的invoke返回Object对象作为方法执行结果。
		 //因为示例程序没有返回值,所以这里忽略了返回值处理
		 method.invoke(delegate, args);
		 long ftime = System.currentTimeMillis();
		 System.out.println("执行任务耗时"+(ftime - stime)+"毫秒");  

		 return null;  

	}

}
</span>

          2、
      

<span style="font-size:14px;">/*************生成动态代理对象的工厂,工厂方法列出了如何生成动态代理类对象的步骤。***************/
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class DynamicTestFactory {

	public  static ITest getInstance() {
		ITest delegate=new Test();
		InvocationHandler testInvocationHandler=new TestInvocationHandler(delegate);
		ITest proxy = null;
		 proxy = (ITest)Proxy.newProxyInstance(delegate.getClass().getClassLoader(),delegate.getClass().getInterfaces(),testInvocationHandler);
		 return proxy;  

	}
}
</span>

         3、客户端调用工厂,隐藏方法          

<span style="font-size:14px;">public class DynamicClient {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		ITest delegate=DynamicTestFactory.getInstance();
		delegate.addStudent("坏学生");

	}

}
</span>

         下面是动态代理的类继承图:

          
         由图可见,Proxy 类是它的父类,这个规则适用于所有由 Proxy 创建的动态代理类。而且该类还实现了其所代理的一组接口,这就是为什么它能够被安全地类型转换到其所代理的某接口的根本原因。 

        那动态代理有哪些优点呢?如果认真看过前面对静态代理的解释的话,我想,动态代理的优点就是避免了静态代理的缺点。

        动态代理接口中声明的所有方法都被转移到调用处理器一个集中的方法中处理(InvocationHandler.invoke)。这样,在接口方法数量比较多的时候,我们可以进行灵活处理,而不需要像静态代理那样每一个方法进行中转。

         Proxy 已经设计得非常优美,但是还是有一点点小小的遗憾之处,那就是它始终无法摆脱仅支持 interface 代理的桎梏,因为它的设计注定了这个遗憾。回想一下那些动态生成的代理类的继承关系图,它们已经注定有一个共同的父类叫
Proxy。Java 的继承机制注定了这些动态代理类们无法实现对 class 的动态代理,原因是多继承在 Java 中本质上就行不通。 
       
 

时间: 2024-05-07 17:35:55

静态代理与动态代理二的相关文章

Java动态代理学习2——静态代理和动态代理并对照spring的通知

  一.代理模式  代理模式是常用的java设计模式,特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等. 代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务.  按照代理的创建时期,代理类可以分为两种: 静态代理:由程序员创建或特定工具自动生成源代码再对其编译.在程序运行前代理类的.class文件就已经存在了. 动态

关于java中的静态代理和动态代理的疑问

问题描述 本人java还未入门者,看到java的反射这一块,里面介绍java的静态代理和动态代理,看的一知半解,有点没想明白的是,动态代理相对于静态代理到底有哪些优势,使用反射机制生成动态代理类,能实现的功能,用静态代理类也可以实现.动态代理不需要写代理类,但是需要写InvocationHandler类,以我的观点看,使用动态代理反而使代码更加难以理解.还请各位大侠给以指点,不胜感激! 解决方案 说一下我对这个问题的看法吧.代理应用的情况有以下几种: 访问控制 远程访问 加载开销比较大的资源(加

静态代理与动态代理

           记得刚接触代理,是在大话设计模式,最近在技术总结和学些java的过程又接触到静态代理和动态代理,尤其是动态代理,在学习AOP时,用到了动态代理,下面我用一些例子来对静态代理和动态代理做个总结.          其实用了代理之后最大的好处就是隐藏了真实类(委托类),这样更加安全,而静态代理和动态代理最大的区别就是,静态代理的代理类是程序员自己写的,在程序运行之前就已经存在的,而动态代理则是在程序运行时动态生成的,而且因为动态代理更加灵活,也常被应用.           首

深入解析java中的静态代理与动态代理_java

java编码中经常用到代理,代理分为静态代理和动态代理.其中动态代理可以实现spring中的aop. 一.静态代理:程序运行之前,程序员就要编写proxy,然后进行编译,即在程序运行之前,代理类的字节码文件就已经生成了 被代理类的公共父类 复制代码 代码如下: package staticproxy;public abstract class BaseClass {    public abstract void add();} 被代理类 复制代码 代码如下: package staticpro

简单静态代理与动态代理

静态: 首先需要一个接口 public interface Neting {  public void netting();    public String playGame(String name); } 然后需要一个实例去继承: public class NetImpl implements Neting {  @Override  public void netting() {   System.out.println("上网中....");  }  @Override  pu

代理模式-动态代理

package pattern.proxy.dynamic; import java.lang.reflect.Proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** * 代理模式:Proxy Pattern * Java对代理模式的支持: * java.lang.reflect.Proxy.java.lang.reflect.InvocationHandler. * @ver

【动态代理】动态代理Proxy_04

我们继续上一篇总结. 上篇我们说到,怎么让before()和after()中的内容也让客户灵活指定? 不管怎么样,我们现在需要一个这样的东西:可以动态指定对方法进行处理的指令. 我们创建一个方法调用的处理器,用来对任意方法进行自定义的处理: package cn.edu.hpu.proxy; import java.lang.reflect.Method; //方法调用的处理器 public interface InvocationHandler { //你只要给我一个Method方法,我就能对

java代理 jdk动态代理应用案列_java

java代理有jdk动态代理.cglib代理,这里只说下jdk动态代理,jdk动态代理主要使用的是java反射机制(既java.lang.reflect包) 原理是(歌手.经纪人做例子): 建立一个公共的接口,比如:歌手public interface Singer: 用具体的类实现接口,比如:周杰伦,他是歌手所以实现Singer这个类,class MySinger implements Singer 建立代理类,这里也就是经纪人,他需要实现InvocationHandler类,并重写invok

【SSH系列】静态代理&amp;amp;&amp;amp;动态代理

从设计模式说起 代理模式是二十三中设计模式中的一种,代理模式就是指由一个代理主题来操作真实的主题,真实的主题执行具体的业务操作,而代理主题负责其她相关业务,简而言之,代理模式可以由以下三个部分组成: a.抽象角色:通过接口或抽象类声明真实角色实现的业务方法. b.代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作. c.真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用.第一次接触代理模式的是在学习大话设计模式的时候,首先