加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java静态代理与动态代理

发布时间:2020-12-15 07:16:03 所属栏目:Java 来源:网络整理
导读:原文链接:http://www.orlion.ga/207/ 一、代理模式 ????代理模式是经常用到的设计模式,代理模式是给指定对象提供代理对象。由代理对象来控制具体对象的引用。 ? ? 代理模式涉及到的角色: ? ? ? ??抽象主题角色:声明了代理主题和真实主题的公共接口,使任

原文链接:http://www.orlion.ga/207/

一、代理模式

????代理模式是经常用到的设计模式,代理模式是给指定对象提供代理对象。由代理对象来控制具体对象的引用。

? ? 代理模式涉及到的角色:

? ? ? ??抽象主题角色:声明了代理主题和真实主题的公共接口,使任何需要真实主题的地方都能用代理主题代替。

  1. ? ? 代理主题角色:含有真实主题的引用,从而可以在任何时候操作真实主题,代理主题功过提供和真实主题相同的接口,使它可以随时代替真实主题。代理主题通过持有真实主题的引用,不但可以控制真实主题的创建或删除,可以在真实主题被调用前进行拦截,或在调用后进行某些操作。

    ? ?真实代理对象:定义了代理角色所代表的具体对象。

????(设计模式是通用的)

????按照代理创建的时期代理类可以分成两种:

????????静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在????????了。

????????动态代理:在程序运行时,运用反射机制动态创建而成。

? ??

二、静态代理

????Talk is cheap,show me the code

????首先定义个酒厂的接口:

????WineFactory.java

????package?ml.orlion.proxy;????
????
????public?interface?WineFactory?{
????
????	public?void?sell();
????}

????然后再定义一个酒厂类实现这个接口:

????WineFactoryImpl.java

????package?ml.orlion.proxy;

????public?class?WineFactoryImpl?implements?WineFactory{
????
????	@Override
????	public?void?sell()?{
????		System.out.println("卖酒");
????	}
????	
????}

????然后定义一个代理类,对酒厂进行代理:

????WineFactoryProxy.java

????package?ml.orlion.proxy;
????/**
?????*?代理类
?????*?对WineFactoryImpl进行代理
?????*/
????public?class?WineFactoryProxy?implements?WineFactory{
????	
????	private?WineFactory?winef;
????
????	public?WineFactoryProxy(WineFactory?winef){
????		this.winef?=?winef;
????	}
????
????	@Override
????	public?void?sell()?{
????		System.out.println("卖酒之前...");
????		winef.sell();
????		System.out.println("卖酒之后...");
????	}
????}

?

三、动态代理

????由静态代理的代码可以看到静态代理只能对一个接口进行服务,如果项目中有很多个接口,那么肯定会产生过多的代理。这时候就需要用到动态代理,由一个代理类完成所有的代理功能。动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。

????JDK动态代理中包含一个InvocationHandler接口和一个Proxy类

????(1)InvocationHandler接口

????public?interface?InvocationHandler?{?????
????????public?Object?invoke(Object?proxy,Method?method,Object[]?args)?throws?Throwable;?
????}

????其中Object porxy:是被代理的对象

????Method method:要调用的方法

????Object[] args:要调用的方法的参数

????(2)Proxy类

????Proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态地生成实现类,此类提供了如下的操作方法:

????public?static?Object?newProxyInstance(ClassLoader?loader,?Class<?>[]?interfaces,?????InvocationHandler?h)??throws?IllegalArgumentException

????其中ClassLoader loader:是类加载器;

????(在java中主要有三种类加载器:

????????Booststrap ClassLoader:此加载器采用C++编写,一般开发中是看不到的;

????????????Extendsion ClassLoader:用来进行扩展类的加载,一般对应的是jrelibext目录中的类;?

????????????AppClassLoader:(默认)加载classpath指定的类,是最常使用的是一种加载器。??????????

????)

????Class<?>[] interfaces:得到全部接口;

? ??InvocationHandler h:得到InvocationHandler接口的子类实例;

????code:

?????WineFactory.java和WineFactoryImpl.java和静态代理的代码相同。

????WineFactoryInvocationHandler.java:

????package?ml.orlion.proxy;
????
????import?java.lang.reflect.InvocationHandler;
????import?java.lang.reflect.Method;
????
????/**
?????*?JDK动态代理类
?????*?对WineFactoryImpl进行代理
?????*/
????public?class?WineFactoryInvocationHandler?implements?InvocationHandler{
????
????	private?Object?target;
????
????	@Override
????	public?Object?invoke(Object?porxy,?Method?m,?Object[]?args)?throws?Throwable?{
????		
????		Object?result?=?null;
????		
????		beforeMethod();
????		//?执行
????		result?=?m.invoke(target,?args);
????		
????		afterMethod();
????		return?result;
????	}
????	
????	public?void?beforeMethod(){
????		System.out.println("卖酒之前...");
????	}
????	
????	public?void?afterMethod(){
????		System.out.println("卖酒之后...");
????	}
????	
????	public?Object?getTarget()?{
????		return?target;
????	}
????
????	public?void?setTarget(Object?target)?{
????		this.target?=?target;
????	}
????}

????测试:

????//?产生一个被代理对象
????WineFactory?wf?=?new?WineFactoryImpl();
????//?将被代理对象交给InvocationHandler
????WineFactoryInvocationHandler?wfih?=?new?WineFactoryInvocationHandler();
????wfih.setTarget(wf);
????//?根据被代理对象产生一个代理
????WineFactory?wfp?=?(WineFactory)Proxy.newProxyInstance(wf.getClass().getClassLoader(),?wf.getClass().getInterfaces(),?wfih);
????wfp.sell();

????

????除了JDK动态代理外还有一种cglib动态代理,具体可参考文章(本文参考):http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读