代理模式指某些情况下,一个客户不想或者不能直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
通过代理,控制对对象的访问。
代理模式核心角色:
抽象角色:定义代理角色和真实角色的公共对外方法
真实角色:真正的业务实现
代理角色: 实现抽象角色,通过对真实角色的业务实现方法来实现抽象方法。也可以新增自己的操作(比如:AOP)
分类:
静态代理: 静态代理对象调用的真实对象由自己创建
/** * 定义一个抽象角色 */ public interface Star { /** * 会谈 */ void confer(); /** * 唱歌 */ void sing(); void sing(int a); }
/** * 真实角色 */ public class ReadStar implements Star { @Override public void confer() { System.out.println("confer"); } @Override public void sing() { System.out.println("sign"); } @Override public void sing(int a) { System.out.println("sign:"+ a); } }
/** * 静态代理,真实对象由调用者提供 */ public class StaticProxy implements Star { private ReadStar readStar; public StaticProxy(ReadStar readStar) { this.readStar = readStar; } @Override public void confer() { readStar.confer(); } @Override public void sing() { readStar.sing(); } @Override public void sing(int a) { readStar.sing(a); } }
public class Main { public static void main(String[] args) { ReadStar star = new ReadStar(); Star proxy = new StaticProxy(star); proxy.confer(); proxy.sing(); } }
动态代理:动态代理中,代理类由工具动态生成。常见由jdk动态代理,c'g'lib字节码等。
JDK动态代理:
--java.lang.reflect.Proxy:动态生成代理类和对象
--java.lang.reflect.InvocationHandler(处理器接口):通过invoke方法实现对真实角色的代理访问。
public class StarHandler implements InvocationHandler { Star realStar; public StarHandler(Star realStar) { super(); this.realStar = realStar; } /** * 调用方法时 * @param proxy * @param method * @param args * @return * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("jdk proxy...."+ args); method.invoke(realStar, args); return null; } }
public class Main { public static void main(String[] args) { Star star = new ReadStar(); StarHandler handler = new StarHandler(star); Star proxy = (Star) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Star.class}, handler); proxy.sing(1); } }
基于JDK动态代理之能对接口创建代理实例。如果需要对类创建代理,可以采用Cglib字节码方式。