代理模式指的是:为某个对象提供一个代理对象,并且由代理对象控制对原对象的访问。
使用场景:
1、安全代理:屏蔽对真实角色的直接访问。
2、远程代理:通过代理类处理远程方法调用(RMI)。
3、延迟加载:先加载轻量级的代理对象,真正需要再加载真实对象。
分类:
1、静态代理:静态定义代理类。
例子:静态代理设计模式
2、动态代理:动态生成代理类。
实现方式:
- JDK自带的动态代理
- javassist字节码操作库实现
- CGLIB
- ASM
使用JDK自带的动态代理,实现:
1、创建一个处理器,处理器继承 java.lang.reflect 包下的InvocationHandler 接口,组合真实对象,重写 invoke 方法,在invoke方法中实现对真实对象的控制访问。
2、在需要代理角色的时候,通过java.lang.reflect.Proxy 类的静态方法 newProxyInstance(类加载器,处理器的构造器参数,处理器)获取一个代理对象。
例子:
Star 接口:
/** * 歌星 */ public interface Star { void eat();//吃饭 void sing();//唱歌 void sleep();//睡觉 }
RealStar 真实对象:
/** * 歌星:佩奇 */ public class RealStar implements Star{ @Override public void eat() { System.out.println("佩奇吃饭饭"); } @Override public void sing() { System.out.println("我是一只佩奇~ 我不会唱歌~"); } @Override public void sleep() { System.out.println("佩奇睡觉觉"); } }
StarHandler 歌星处理器:实现 InvocationHandler 接口,组合 Star 类,重写 inboke 类。
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** * 处理器 */ public class StarHandler implements InvocationHandler { private Star star;//需要代理的对象 public StarHandler(Star star) { this.star = star; }
/** * * @param o 代理对象 * @param method 获取的对象的方法 * @param objects 方法的参数 * @return * @throws Throwable */ @Override public Object invoke(Object o, Method method, Object[] objects) throws Throwable { System.out.println("---------------invoke方法开始"); //调用的是吃饭,代理对象来处理 if(method.getName().equals("eat")){ System.out.println(o.getClass().getSimpleName()+":吃饭我来就行了"); } //如果是唱歌,那就让真正的歌星去唱歌。 if(method.getName().equals("sing")){ method.invoke(star,objects); } //调用的是睡觉,代理对象来处理 if(method.getName().equals("sleep")){ System.out.println(o.getClass().getSimpleName()+":吃饭我来就行了"); } System.out.println("---------------invoke方法结束"); return null; } }
客户测试一下:
import java.lang.reflect.Proxy; public class Client { public static void main(String[] args) { //创建真实对象 Star peiqi = new RealStar(); //获取处理器 StarHandler starHandler = new StarHandler(peiqi); //获取代理类对象:通过Proxy获取,需要指定类加载器、构造器参数、处理器。 Star proxy = (Star) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Star.class}, starHandler); //代理角色吃饭干活 proxy.eat(); proxy.sing(); proxy.sleep(); } }
运行结果:
标签:Star,对象,void,代理,模式,Proxy,println,public From: https://www.cnblogs.com/lurenjia-bky/p/16923595.html