代理模式
定义:为另一个对象提供一个替身或者占位符,以控制对这个对象的访问。
代理模式和装饰者模式
- 装饰者模式是为对象附加新的行为
- 代理模式是让访问者通过代理类访问对象,从而可以在代理类中添加对对象访问的控制。
类图
示例
//Subject public interface Actor { void visit(); } //Proxy public class ActorProxy implements Actor { RealActor realActor; @Override public void visit() { if(realActor==null){ realActor = new RealActor(); } System.out.println("访问之前要做的事!"); realActor.visit(); System.out.println("访问之后要做的事!"); } } //RealSubject public class RealActor implements Actor{ @Override public void visit() { System.out.println("访问真正的演员!"); } } public class Client { public static void main(String[] args){ Actor actorProxy = new ActorProxy(); actorProxy.visit(); } }
运行结果
Java动态代理
- JDK中的动态代理是通过反射类Proxy以及InvocationHandler回调接口实现的,但是,JDK中所要进行动态代理的类必须要实现一个接口
- java.lang.reflect.InvocationHandler:需要实现这个接口,实现自己的处理器。处理器控制对象的访问。
- java.lang.reflect.Proxy:产生代理对象,需要指定实现的处理器试
示例
//Subject public interface Actor { void visit(); } //ConcreteInvocationHandler public class ActorInvocationHandler implements InvocationHandler { Actor actor; public ActorInvocationHandler(Actor actor){ this.actor = actor; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("访问前"); Object object = method.invoke(actor,args); System.out.println("访问后"); return object; } } public class Client { public static void main(String[] args) { Actor realActor = new RealActor(); Actor actor = (Actor) Proxy.newProxyInstance(realActor.getClass().getClassLoader(), realActor.getClass().getInterfaces(), new ActorInvocationHandler(realActor)); actor.visit(); } }
运行结果
Cglib动态代理
使用CGLib实现动态代理,完全不受代理类必须实现接口的限制,需要注意的是,CGLib不能对声明为final的方法进行代理,因为CGLib原理是动态生成被代理类的子类。
Jar包:
- cglib-nodep.jar:使用nodep包不需要关联asm的jar包,jar包内部包含asm的类。
- cglib.jar:使用此jar包需要关联asm的jar包,否则运行时报错。
示例
//RealSubject public class RealActor { public void visit() { System.out.println("访问真正的演员!"); } } public class CglibProxy implements MethodInterceptor { private Object target; public CglibProxy(Object target){ this.target = target; } public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("调用前"); Object obj = method.invoke(target,objects); System.out.println("调用后"); return obj; } public static Object getProxy(Object target){ Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(target.getClass()); enhancer.setCallback(new CglibProxy(target)); return enhancer.create(); } } public class Client { public static void main(String[] args){ RealActor realActor = (RealActor) CglibProxy.getProxy(new RealActor()); realActor.visit(); } }
运行结果
语言是思想的载体
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步