1.代理模式的介绍
定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
以一个简单的例子:当我们打游戏的时候,找代练,需要给代练自己的帐号。代练就是一个代理,这里的重点的是需要将自己的帐号给代练, 也就是需要将被代理对象要执行的方法传给代理者去执行。
2.实现上面简单的例子(静态代理)
public interface IGamePlayer {
boolean login(String userName, String userPwd);
void killBoss();
void upgrade();
}
public class GamePlayer implements IGamePlayer{
private String name;
@Override
public boolean login(String userName, String userPwd) {
this.name = userName;
System.out.println(this.name +" is login");
return false;
}
@Override
public void killBoss() {
System.out.println(this.name + " kill boss");
}
@Override
public void upgrade() {
System.out.println(this.name + " upgrade");
}
}
public class GamePlayerProxy implements IGamePlayer{
private IGamePlayer gamePlayer;
public GamePlayerProxy(IGamePlayer gamePlayer) {
this.gamePlayer = gamePlayer;
}
@Override
public boolean login(String userName, String userPwd) {
this.gamePlayer.login(userName,userPwd);
return false;
}
@Override
public void killBoss() {
this.gamePlayer.killBoss();
}
@Override
public void upgrade() {
this.gamePlayer.upgrade();
}
}
public class Client {
public static void main(String[] args) {
IGamePlayer gamePlayer = new GamePlayer();
IGamePlayer gamePlayer1 = new GamePlayerProxy(gamePlayer);
System.out.println("game begin time:" + System.currentTimeMillis());
gamePlayer1.login("kate","123");
gamePlayer1.killBoss();
gamePlayer1.upgrade();
System.out.println("game end time:" + System.currentTimeMillis());
}
}
3.动态代理(JDK动态代理)
动态代理常用两种方式实现:一种是JDK的Proxy,二是Cglib。两者的区别是Proxy必须有接口。而Cglib无论接口还是抽象类都可以做代理。这里只写JDK动态代理。
public interface Calc {
public int add(int i,int j);
public int sub(int i ,int j);
public int mul(int i, int j);
public int div(int i, int j);
}
public class CalcImpl implements Calc{
@Override
public int add(int i, int j) {
return i+j;
}
@Override
public int sub(int i, int j) {
return i-j;
}
@Override
public int mul(int i, int j) {
return i*j;
}
@Override
public int div(int i, int j) {
return i/j;
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class CalcProxyUtils {
public static Calc newCalcProxyINstance(Calc calc){
ClassLoader loader = calc.getClass().getClassLoader();
Class<?>[] interfaces = calc.getClass().getInterfaces();
InvocationHandler h = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("object method" +method.getName()+" ready for execute");
Object result = method.invoke(calc,args);
System.out.println("the method reslut: "+ result);
return result;
}
};
return (Calc) Proxy.newProxyInstance(loader,interfaces,h);
}
}
public class CalcTest {
public static void main(String[] args) {
Calc calc = new CalcImpl();
Calc proxy = CalcProxyUtils.newCalcProxyINstance(calc);
int result = proxy.add(1,2);
System.out.println(result);
}
}