代理模式的目的:
在不改变代源码的情况下,实现对目标对象的功能的扩展
假如现在有一个歌手,名字叫做Singer,这个对象有一个唱歌的方法sing()。
public class Singer{
public void sing(){
System.out.println("唱一首歌");
}
}
现在你通过某种方式创建了一个歌手的对象,在唱歌前想要对观众问好,唱歌后对观众进行答谢,即对目标对象Singer的sing方法功能进行扩展
public void sing(){
System.out.println("向观众问好");
System.out.println("唱一首歌");
System.out.println("谢谢大家");
}
这个代理是手动代理有几个类和一个功能接口组成
/**
*公用的一个功能接口
*/
interface ISinger{
void sing();//唱歌的方法
}
/**
*歌手对象实现功能接口(被代理对象)
*/
class Singer implements ISinger{
@Override
public void sing(){
System.out.println("我是一个歌手,我开始唱歌了");
}
}
/**
*代理类
*/
class SingerProxy implements ISinger{
//代理类必须持有代理对象的引用通过构造器注入
private Singer singer;
public Singer Proxy(Singersinger){
this.singer=singer;
}
//对方法进行扩展
@Override
public void sing(){
System.out.println("首先我需要向观众问好!");
singer.sing();
System.out.println("答谢观众!");
}
}
public class TestStaticProxy{
public static void main(String[]args){
//1.创建被代理对象
Singer singer = new Singer();
//2.创建代理类,并注入被代理的对象
SingerProxy singerProxy = new SingerProxy(singer);
//3.执行已经扩展的代理类的方法
singerProxy.sing();
}
}
很简单的就实现了一个静态的代理,歌手只用做自己的唱歌的功能,很好的实现了解耦,也实现了对功能的扩展,注意一点代理类必须持有被代理对象的引用
缺点:就是每一个代理类都需要自己动手写,当公用方法接口改变了之后就需要去手动的维护,维护起来比较麻烦。
public class TestDynamicProxy{
public static void main(String[] args){
Singer singer = new Singer();
ISingerproxy = (ISinger)Proxy.newProxyInstance(singer.getClass().getClassLoader(),singer.getClass().getInterfaces(),new InvocationHandler(){
@Override
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
System.out.println("向观众问好");
//执行目标对象方法
Object returnValue = method.invoke(singer,args);
System.out.println("谢谢大家");
return returnValue;
}
});
//调用代理对象的方法
proxy.sing();
}
}
这就实现了简单的动态代理,动态代理是所有Projxy.newProxyInstance()来获取一个动态的代理的实例然后调用目标方法就实现了动态的代理
Public class MyInvocationHandle<T> implements InvocationHandler{
Private T tager;//被代理的实体类的引用
Public MyInvocationHandle(T tager){
this.tager=tager;
}
@Override
Public Object invoke(Object proxy,Method method,Object[] args)throwsThrowable{
//1.实现自己的扩展的方法
…
//2.直接目标方法,对象是代理对象tager
Objectinvoke=method.invoke(tager,args);
returninvoke;
}
}
Public static void main(String[] args){
InvocationHandler ins = new MyInvocationHandle
Object singer = Proxy.newProxyInstance(Singer.class.getClassLoader(),new Class[]{ISinger.class},ins);
((ISinger)singer).sing();
}
代理中首先创建一个自己的invocationHandler,然后传入自己的代理对象,然后把这对象给proxy来产生自己的代理对象其实第一种和第二种都是一种,只不过第二种来扩展方法的时候更方便
public final class DynamicProxyExalpme extends Proxy implements ISinger{ privatestaticMethodm1; privatestaticMethodm2; privatestaticMethodm3; privatestaticMethodm0;
publicDynamicProxyExalpme(InvocationHandlervar1){ super(var1); }
static{ try{ m1 =Class.forName("java.lang.Object").getMethod("equals",Class.forName("java.lang.Object")); m2=Class.forName("java.lang.Object").getMethod("toString"); m3=Class.forName("proxy.ISinger").getMethod("sing"); m0=Class.forName("java.lang.Object").getMethod("hashCode"); }catch(NoSuchMethodExceptionvar2){ thrownewNoSuchMethodError(var2.getMessage()); }catch(ClassNotFoundExceptionvar3){ thrownewNoClassDefFoundError(var3.getMessage()); } } Public final void sing(){ try{ super.h.invoke(this,m3,(Object[])null); }catch(RuntimeException|Errorvar2){ throw var2; }catch(Throwablevar3){ thrownewUndeclaredThrowableException(var3); } } } |
到了这个程度只是会用了,但是具体是如何实现的还是不太了解,等到自己的能力再高一点了自己来实现一个