从java静态代理到动态代理的过渡深入理解动态代理
java动态代理是怎么样的一个概念呢?初学者往往很困惑,下面先看看什么是静态代理。
——-静态代理
package com.mldn;
public class StaticProxy
{
public static void main(String[] args)
{
Subject sub = new ProxySubject(new RealSubject()); // 代理者为接口实例化
sub.say(“张三”, 30);
}
}
interface Subject // 定义一个接口,实现某种主题
{
public void say(String name, int age); // 抽象方法
}
class RealSubject implements Subject // 该主题的真正在意者
{
public RealSubject()
{
//
}
public void say(String name, int age)
{
System.out.println(“姓名:” + name + ” 年龄:” + age);
}
}
class ProxySubject implements Subject // 代理者,为基于此主题的行使代理操作
{
private Subject sub = null;
public ProxySubject(Subject sub)
{
this.sub = sub;
}
public void say(String name, int age)
{
this.sub.say(name, age); // 实现代理操作
}
}
/*
ubuntu@xu-desktop:~$ java com.mldn.StaticProxy
姓名:张三 年龄:30
// 这里模拟的是一个静态代理的例子:每个代理都是针对一个接口,若同时为多个接口代理,将出现大量的冗余工作!
// java中定义了动态代理的概念与操作类!
*/
——–java中的动态代理:
public interface InvocationHandler;// 该接口位于java.lang.reflect中;表示代理者要执行的调用处理!
InvocationHandler is the interface implemented by the invocation handler of a proxy instance.
public class Proxy
extends Object
implements Serializable;// Proxy类,可以为被代理类的所有功能接口同一地交给调用处理器统一处理!
Proxy provides static methods for creating dynamic proxy classes and instances, and it is also the superclass of all dynamic proxy classes created by those methods.
1.public static Object newProxyInstance(ClassLoader loader,
Class>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException;// 生成被代理类的所有实现的接口的公共的实例并且共享调用处理器
// ClassLoader:类加载器:三种:
1.Bootstrap ClassLoader:C++编写,一般开发中看不到的;
2.Extension ClassLoader:用来进行扩展类的加载,一般对应jre\lib\ext目录中的类;
3.AppClassLoader:加载classpath指定的类,最常用的!
public abstract class ClassLoader
extends Object;// java.lang.ClassLoader;
—实例:
package com.mldn;
public class ClassLoaderDemo
{
public static void main(String[] args)
{
Person per = new Person();
System.out.println(per.getClass().getClassLoader()); // 获取ClassLoader对象
ClassLoader cl = per.getClass().getClassLoader(); // 接收该加载器对象
System.out.println(cl.getClass().getName()); // 输出该对象类的名称
}
}
/*
ubuntu@xu-desktop:~$ java com.mldn.ClassLoaderDemo
sun.misc.Launcher$AppClassLoader@7d772e
sun.misc.Launcher$AppClassLoader
// AppClassLoader是最常用的加载器!
*/
—–动态代理的实例,运行时调用被代理类的某一方面的功能!
package com.mldn;
import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class ProxyDemo
{
public static void main(String[] args) throws Throwable
{
RealSubject rl = new RealSubject();
Class[] interfaces = rl.getClass().getInterfaces();
ProxySubject ps = new ProxySubject(rl);
Object proxy = Proxy.newProxyInstance(RealSubject.class.getClassLoader(), interfaces, ps); // 新的代理类是被代理类所有接口的实例!
Interface1 i1 = (Interface1)proxy;
i1.fun();
Subject sub = (Subject)proxy; // 使用当前接口,进行向下转型;
sub.say(“张三”, 30); // 每当调用所需接口的方法时,调用处理器的invoke(…)方法就被调用!
Interface2 i2 = (Interface2)proxy;
i2.fun1();
}
}
// 代理者,作为调用处理器
class ProxySubject implements InvocationHandler
{
private Object target = null; // 被代理对象
public ProxySubject(Object target)
{
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
if ((proxy == null) || (method == null))
{
return null;
}
System.out.println(“调用处理器invoke执行!”);
return method.invoke(this.target, args); // 调用处理器真正的操作:被代理者的当前方法被调用以当前实例执行
}
}
// 被代理者,实现若干接口
package com.mldn;
public class RealSubject implements Subject, Interface1, Interface2 // 该主题的真正在意者
{
public RealSubject()
{
//
}
public void say(String name, int age)
{
System.out.println(“姓名:” + name + ” 年龄:” + age);
}
public void fun()
{
System.out.println(“来自interface1接口的功能调用完毕!”);
}
public void fun1()
{
System.out.println(“来自interface2接口的功能调用完毕!”);
}
}
/*
ubuntu@xu-desktop:~$ java com.mldn.ProxyDemo
调用处理器invoke执行!
来自interface1接口的功能调用完毕!
调用处理器invoke执行!
姓名:张三 年龄:30
调用处理器invoke执行!
来自interface2接口的功能调用完毕!
// 代理:是为了更专一地使用被代理者局部的功能,从而达到代码简洁和操作方便的目的,功能使用接口表示!
// 代理分为:被代理者,代理者,被代理者的局部功能是用户关心的,代理者可以满足用户需求,并充当桥梁,本质是调用处理器!
// 动态:系统根据预定义规则响应并完成用户在运行时提出的确定的需求!
// 动态代理使实际开发得到更多优化!实现了代码复用、功能共享!
*/
———-动态代理实例2:
package com.mldn;
import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class ProxyDemo1
{
public static void main(String[] args)
{
RealSubject rsub = new RealSubject(); // 实例化被代理类;
Object obj = new MyInvocationHandler().bind(rsub);// 与代理类绑定;
Subject sub = (Subject)obj;
sub.say(“k187”, 2); // 调用Subject接口的方法;
Interface1 in1 = (Interface1)obj;
in1.fun(); // 调用Interface1接口的方法;
Interface2 in2 = (Interface2)obj;
in2.fun1(); // 调用Interface2接口的方法;
}
}
class MyInvocationHandler implements InvocationHandler
{
private Object target = null; // 声明被代理类
public MyInvocationHandler()
{
}
public Object bind(Object target)// 绑定被代理类和代理类!
{
this.target = target;
return Proxy.newProxyInstance(this.target.getClass().getClassLoader(), this.target.getClass().getInterfaces(), this); // 返回新代理类,
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
if (proxy == null || method == null) // 绑定失败或者方法不存在结束此方法
{
return null;
}
return method.invoke(this.target, args); // 在被代理对象中执行该方法
}
}
class RealSubject implements Subject, Interface1, Interface2 // 该主题的真正在意者
{
public RealSubject()
{
//
}
public void say(String name, int age) // 来自于接口Subject
{
System.out.println(“姓名:” + name + ” 年龄:” + age);
}
public void fun() // 来自于接口Interface1
{
System.out.println(“来自interface1接口的功能调用完毕!”);
}
public void fun1() // 来自于接口Interface2
{
System.out.println(“来自interface2接口的功能调用完毕!”);
}
}
/*
ubuntu@xu-desktop:~$ java com.mldn.ProxyDemo1
姓名:k187 年龄:2
来自interface1接口的功能调用完毕!
来自interface2接口的功能调用完毕!
*/
声明: 除非转自他站(如有侵权,请联系处理)外,本文采用 BY-NC-SA 协议进行授权 | 嗅谱网
转载请注明:转自《从java静态代理到动态代理的过渡深入理解动态代理》
本文地址:http://www.xiupu.net/archives-145.html
关注公众号:
微信赞赏
支付宝赞赏