代理模式在java中经常使用,其主要应用场景就是如果完成一件事情,但是事情中大部分是重复的,只有其中的某一部分需要单独完成,此时就需要代理类。如中介,相信北漂的同学们都有过租房子的经理。中介就相当于代理,房东相当于被代理者。房东将房子交给中介,中介负责带访客去看房子,有问题去解决,总后,将收到的钱交给房东。也就是说,只有将房子租给房客是房主需要做的。
下面我们首先做一个动态代理,理解一下代理模式。
首先创建一个接口,让代理者和被代理者都继承同样的接口。
public interface StaticProxy {
public void getMoney();//明星唱歌,收门票钱
public void sing();//唱歌
public void setWhere();//收拾场地
}
真实对象
真实对象主要的职责就是负责唱歌,其他的事情不用做
public class RealStar implements StaticProxy{
@Override
public void getMoney() {
// TODO Auto-generated method stub
}
@Override
public void sing() {
System.out.println("我是明星,我在唱歌!!!");
}
@Override
public void setWhere() {
// TODO Auto-generated method stub
}
}
下面我们创建代理对象,也继承这个接口
代理对象不用完成唱歌,但是其他的事情都要负责。
public class ProxyStart implements StaticProxy{
private RealStar realStar;
@Override
public void getMoney() {
System.out.println("我是代理,我是来收门票钱的!!!");
}
@Override
public void sing() {
realStar.sing();
}
@Override
public void setWhere() {
System.out.println("我是代理,唱完歌了,我来收拾场地!!!");
}
public ProxyStart(RealStar realStar) {
System.out.println("带动观众气氛,鼓掌");
realStar.sing();
System.out.println("太好了,再来一首");
}
}
public class Client {
public static void main(String[] args) {
ProxyStart proxyStart = new ProxyStart(new RealStar());
proxyStart.getMoney();
proxyStart.sing();
proxyStart.setWhere();
}
}
静态代理的实质就是在代理对象中,保存一个被代理的对象,完成代理不能做的事情。
下面介绍一下动态代理
主要写一下代理类和客户端调用
public class ProxyStart implements InvocationHandler{
private RealStar realStar;
public ProxyStart(RealStar realStar) {
super();
this.realStar = realStar;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("大家开始鼓掌");
Object invoke = method.invoke(realStar, args);
System.out.println("收拾场地");
return null;
}
}
public class Client {
public static void main(String[] args) {
ProxyStart proxyStart = new ProxyStart(new RealStar());
StaticProxy proxy = (StaticProxy) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[] {StaticProxy.class},proxyStart);
proxy.sing();
}
}
下面我们介绍一下参数问题
newProxyInstance方法一共有三个参数:
第一个:类加载器,一般我们用不到,记住怎么调用就可以了。主要就是调用代理对象的时候,将代理对象加入到内存中
第二个:接口,获取代理对象和目标对象的接口,获取到其中的方法。
第三个:代理对象。
invoke(Object proxy, Method method, Object[] args)方法:
第一个:代理对象
第二个:代理对象中的方法
第三个:代理对象的参数。