代理可以理解为委托,委托别人帮你完成某种事情。
代理分为静态代理、动态代理两种。“静态”和”动态“区别主要在于前者需要手写代理类,后者的代理类为运行时在内存中生成。当然,这不是两者的核心区别。
被代理类 Actor.java
package main.java;
public class Actor {
private String name;
private int age;
public Actor(String name, int age) {
this.name = name;
this.age = age;
}
public Actor() {
}
public void play(){
System.out.println(name+" is playing");
}
}
代理类 ActorProxy.java
package main.java;
public class ActorProxy {
private Actor actor;
public ActorProxy() {
this.actor = new Actor("袁朗", 30);
}
public ActorProxy(Actor actor) {
this.actor = actor;
}
public void play() {
System.out.println("ActorProxy.play()");
actor.play();
}
}
测试类 Main.java
package main.java;
public class Main {
public static void main(String[] args) {
//默认被代理对象
ActorProxy actorProxy=new ActorProxy();
actorProxy.play();
//手动指定被代理对象
ActorProxy actorProxy1=new ActorProxy(new Actor("高城",29));
actorProxy1.play();
}
}
更一般的做法是,代理类和被代理类继承同一个接口,代理类中明确被代理对象的类型如这样:
接口,被代理类和代理类都要实现
package main.java;
public interface DoJob {
void play();
}
被代理类 Actor.java 实现DoJob接口
package main.java;
public class Actor implements DoJob {
private String name;
private int age;
public Actor(String name, int age) {
this.name = name;
this.age = age;
}
public Actor() {
}
@Override
public void play() {
System.out.println(name+" is playing");
}
}
代理类 ActorProxy.java 实现DoJob接口
package main.java;
public class ActorProxy implements DoJob{
private DoJob doJob;
public ActorProxy(DoJob doJob) {
this.doJob =doJob;
}
public void play() {
System.out.println("ActorProxy.play()");
doJob.play();
}
}
package main.java;
public class Main {
public static void main(String[] args) {
//被代理对象
Actor actor=new Actor("高城",29);
//代理对象
ActorProxy actorProxy=new ActorProxy(actor);
actorProxy.play();
}
}
与上面的主要区别在于代理类和被代理类实现了共同的接口。实现共同的接口是必要的,Actor能play,ActorProxy代理Actor后,仍然需要向外提供play方法,站在调用者角度,两者没什么区别。
静态代理的麻烦之处在于,需要手动实现代理对象,并往往需要手动在代理对象中添加与被代理对象相同的许多方法。动态代理会自动帮我们生成代理对象,拦截对被代理对象的请求。这是静态与动态的主要
接口 DoJob.java
package main.java;
public interface DoJob {
void play();
}
被代理类 Actor.java
package main.java;
public class Actor implements DoJob {
private String name;
private int age;
public Actor(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public void play() {
System.out.println(name + " is playing");
}
}
拦截器 PlayHandler.java 继承InvocationHandler.java
package main.java;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class PlayHandler implements InvocationHandler {
private Object object;
public PlayHandler(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before calling play()");
Object res=method.invoke(object,args);
System.out.println("after calling play()");
return res;
}
}
package main.java;
import java.lang.reflect.Proxy;
public class Main {
public static void main(String[] args) {
//被代理对象
DoJob actor=new Actor("伍六一",24);
//“拦截器”
PlayHandler playHandler=new PlayHandler(actor);
//动态生成代理类
DoJob actorProxy= (DoJob) Proxy.newProxyInstance(actor.getClass().getClassLoader(),actor.getClass().getInterfaces(),
playHandler);
//与直接访问被代理类方式相同,但暗地里方法被代理对象中的playHandler被拦截了
actorProxy.play();
}
}
无它,仅作备忘