代理模式的学习
首先,我们知道代理模式分为静态代理模式和动态代理模式
静态代理模式,简单说,就是我们自己来写一个代理对象,然后通过这个代理对象来实现代理功能。
那么如何实现静态代理呢?下面给出一个例子
1.创建一个interface接口(Singing ),在这个接口里写你想通过代理对象调用的方法
package cn.mec_1202.play_1.interfac;
public interface Singing {
public void singing(String songname);
}
2.创建你想要代理的类(Singer ),实现1中创建的接口
package cn.mec_1202.play_1.model;
import cn.mec_1202.play_1.interfac.Singing;
public class Singer implements Singing{
public void singing(String songname) {
System.out.println(songname+":。。。。。");
}
}
3.创建一个代理对象类(SingProxy ),实现1中的接口(Singing ),并创建一个需要代理的成员类(singer),在实现Singing 接口的singing方法中,调用singer的singing方法
package cn.mec_1202.play_1.core;
import cn.mec_1202.play_1.interfac.Singing;
import cn.mec_1202.play_1.model.Singer;
public class SingProxy implements Singing {
private Singer singer;
public SingProxy(Singer singer) {
this.singer = singer;
}
public void singing(String songname) {
System.out.println("演出开始,准备欢呼吧!");
singer.singing(songname);
System.out.println("演出结束,请大家离场。");
}
}
4.创建一个测试类(Test )
package cn.mec_1202.play_1.test;
import cn.mec_1202.play_1.core.SingProxy;
import cn.mec_1202.play_1.model.Singer;
public class Test {
public static void main(String[] args) {
Singer singer=new Singer();
SingProxy singProxy=new SingProxy(singer);
singProxy.singing("烟花易冷");
}
}
运行结果为:
演出开始,准备欢呼吧!
烟花易冷:。。。。。
演出结束,请大家离场。
我们来分析一下整个过程,我们为Singer 类创建了代理对象SingProxy 类, Singer 只需要处理唱歌就好了,至于观众入场,退场之类的功能,由代理对象SingProxy来完成,我们不需要为了演唱地点的改变,去改变Singer 类的代码。只需要为它创建对应的代理对象。
看完了静态代理模式,接下来,让我们看看动态代理模式
还是给出一个例子
1.和静态代理模式一样,创建一个interface接口(Singing ),在这个接口里写你想通过代理对象调用的方法
package cn.mec_1202.play_2.interfac;
public interface Singing {
public void singing(String songname);
}
2.创建你想要代理的类(Singer ),实现1中创建的接口
package cn.mec_1202.play_2.model;
import cn.mec_1202.play_2.interfac.Singing;
public class Singer implements Singing {
public void singing(String songname) {
System.out.println(songname+":。。。。。");
}
}
3.创建代理工厂类()
package cn.mec_1202.play_2.Factory;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class SingFactory {
private Object object;
public SingFactory(Object object) {
this.object = object;
}
public Object getproxy(){
InvocationHandler invocationHandler=new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("请准备欣赏该表演");
Object a=method.invoke(object,args);
System.out.println("演出结束,请退场!");
return a;
}
};
return Proxy.newProxyInstance(object.getClass().getClassLoader(),
object.getClass().getInterfaces(), invocationHandler
);
}
}
4.创建一个测试类(Test )
package cn.mec_1202.play_2.test;
import cn.mec_1202.play_2.Factory.SingFactory;
import cn.mec_1202.play_2.interfac.Singing;
import cn.mec_1202.play_2.model.Singer;
public class Test {
public static void main(String[] args) {
Singer singer=new Singer();
SingFactory singFactory=new SingFactory(singer);
Singing a=(Singing)singFactory.getproxy();
a.singing("黎明花开");
}
}
运行结果为:
请准备欣赏该表演
黎明花开:。。。。。
演出结束,请退场!
动态代理模式,它的代理对象是利用JDK的API,动态的在内存中构建代理对象,我们只需要提供 被代理对象的类加载器以及实现的接口的类型,和InvocationHandler 即可,下面是proxy.java的newProxyInstance方法
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
Objects.requireNonNull(h);
final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
动态代理和静态代理相比,前者自动产生代理对象,代理对象不用实现对应接口,在业务繁杂的情况下,避免了创建繁杂的代理对象
暂时了解到这个程度,如果有什么错误之处,还望大佬们帮忙指出,我会及时更改。