代理模式就是多一个代理类出来,替原对象进行一些操作。控制对对象的访问,详细控制某个对象的方法,调用这个方法前做前置处理和后置处理。AOP的核心实现机制。
下面有一个场景:一个唱歌的明星,对应的经纪人就相当于代理类,只有唱歌的时候才是明星去唱,其余的比如收钱,会面等事情就是经纪人去做,但是需要注意一点,明星自己也可以收钱,会面的,不过,正如现实一样,明星不是所有人都能见到的,所有,请明星唱歌不可能直接联系明星,而是通过经纪人,这个就是对明星这个对象的控制。
公共接口
public interface StartInterface {
void sing();
void play();
void run();
void collectMoney();
}
被代理类
public class Star implements StartInterface{
@Override
public void sing() {
System.out.println("star sing!");
}
@Override
public void play() {
System.out.println("star play!");
}
@Override
public void run() {
System.out.println("star run!");
}
@Override
public void collectMoney() {
System.out.println("star collectMoney!");
}
}
代理类
public class ProxyStar implements StartInterface {
private StartInterface startInterface;
public ProxyStar( StartInterface startInterface){
this.startInterface = startInterface;
}
@Override
public void sing() {
//可以在前后做其他处理
startInterface.sing();
}
@Override
public void play() {
System.out.println("proxy play!");
}
@Override
public void run() {
System.out.println("proxy run!");
}
@Override
public void collectMoney() {
System.out.println("proxy collectMoney!");
}
}
public class ProxyTest {
public static void main(String[] args) {
Star star = new Star();
StartInterface startInterface = new ProxyStar(star);
startInterface.sing();
startInterface.play();
}
}
输出结果如下:
star sing!
proxy play!
上面的就是典型的静态代理的例子。下面看一下动态代理。
jdk自带的动态代理:
java.lang.reflect.Proxy(动态生成代理类和对象)。
java.lang.reflect.InvocationHandler。通过invoke方法实现对真实角色的代理访问。每次通过Proxy生成代理类对象时都要指定对应的处理器对象。
public class StarHandle implements InvocationHandler {
private StartInterface star;
public StarHandle(StartInterface star) {
this.star = star;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("sing")) {
method.invoke(star, args);
return null;
}
return null;
}
}
public class DynamicTest {
public static void main(String[] args) {
StartInterface star = new Star();
StarHandle starHandle = new StarHandle(star);
StartInterface obj =(StartInterface) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),
new Class[]{StartInterface.class},starHandle);
//进入到StarHandle invoke方法里面
obj.sing();
}
}
输出的结果是:
star sing!
这里就是动态代理实现了对对象的方法的调用。