代理设计:
一个操作的接口有两个子类,其中一个是真实主题的实现类,另外一个是代理类,代理
实现类要完成比真实主题实现类更多的内容,而且本身还需要处理一些与具体业务有关的
程序代码。
定义一个接口:
interface Subject //定义接口
{
public String say(String name,int age){
}
}
真实实现类:
class RealSubject implements Subject //真实实现类
{
public String say(String name,int age){
return "姓名:"+name+",年龄:"+age;
}
}
代理实现类:
class ProxySubject implements Subject //代理实现类
{
private Subject sub=null;
public ProxySubject(Subject sub){ //引入真实实现类接口,来实现比实现类更多的功能
this.sub=sub;
}
public String say(String name,int age){
return this.sub.say(name,age);
}
}
测试类:
public class ProxyDemo
{
public static void main(String args[]){
Subject sub=new ProxySubject(new RealSubject());
String info=sub.say("李兴华",30);
System.out.println(info);
}
}
以上的代码操作实际上是称为静态代理,因为一个代理类只能为一个接口服务,那么如果现在有很多个接口的话,
那么肯定代理代理类就很多的了,而且,所有代理操作除了调用的方法不一样之外,其他的操作一样,则此时
肯定是重复代码。
动类代理:
InvocationHandler接口:
public interface InvocationHandler{
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;
}
参数说明:
Object proxy:被代理的对象
Method method:要调用的方法
Object args[] :方法调用时所需要的参数
可以将InvocationHandler接口的子类想象成一个代理的最终操作类,替换掉ProxySubject
class MyInvocationHandler implements InvacationHandler{
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
}
}
Proxy类:
Proxy类是专门完代理的操作类,可以通过此类为一个或多个接口动态地生成实现类,此类提供了如下的操作方法:
pubblic static Object newProxyInstance(ClassLoader loader,class<?> interfaces, InvocationHandler h)
throws IllegalArgumentException
参数说明:
ClassLoader loader:类加载器
Class<?> interfaces :得到全部的接口
InvacationHandler h:得到InvacationHandler接口的子类实例
提示:类加载器
在Proxy类中的newProxyInstance()方法中需要一个ClassLoader类的实例,ClassLoader实际对应的是类加载器,
在Java中主要有以下三种类加载器:
Bootstrap ClassLoader:此加载器采用C++编写,一般开发中是看不到是;
Extension ClassLoader:用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类;
AppClassLoader:加载classpath指定的类,是最常使用的一种加载器
如果要想得到一个加载器的对象,则肯定使用Class类完成。
class person{}
public class ClassLoaderDemo{
public static void nain(){
Person stu= new Person();
System.out.println("类加载器:"+stu.getClass().getClassLoader().getClass().getName());
}
}
定义一个接口:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.lang.reflect.Method;
interface Subject
{
public String say(String name,int age);
}
真现实现类:
class RealSubject implements Subject
{
public String say(String name,int age){
return "姓名:"+name+",年龄:"+age;
}
}
动态代理类:
class MyInvocationHandler implements InvocationHandler
{
private Object obj;
public Object bind(Object obj){ //绑定
this.obj=obj; //真实主题类
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
}
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
Object temp=method.invoke(this.obj,args); //调用方法
return temp;
}
}
测试类:
public class DynaProxyDemo
{
public static void main(String args[]){
Subject sub=(Subject)new MyInvocationHandler().bind(new RealSubject());
String info=sub.say("李兴华",30);
System.out.println(info);
}
}
此时使用动态代理,就可以完成代理的功能,而且可以代理全部的接口。