java代理模式
2022/1/4 20:05:06
本文主要是介绍java代理模式,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
代理模式
指的是使用一个代理对象将原对象包装起来,之后用这个代理来取代该对象,任何对原始对象的调用都需要通过代理。
1. 静态代理
程序运行之前就已经定好代理类和委托类的关系。
BasicSubject.java
/** * 代理接口 */ public interface BasicSubject { public void doSomething(); }
BasicImpl.java
/** * 委托类,真正执行任务的类,实现了代理接口 */ public class BasicImpl implements BasicSubject{ @Override public void doSomething() { System.out.println("do something!"); } }
BasicProxy.java
/** * 代理类,实现了代理接口,同时里面有委托类的对象引用 */ public class BasicProxy implements BasicSubject{ private BasicImpl basic = new BasicImpl(); @Override public void doSomething() { this.before(); basic.doSomething(); this.after(); } public void before(){ System.out.println("before"); } public void after(){ System.out.println("after"); } }
testStaticProxy.java
public class testStaticProxy { public static void main(String[] args) { BasicSubject basicSubject = new BasicProxy(); basicSubject.doSomething(); } }
可以看出,静态代理类由于一个类只能代理一种类型的对象,因此代码量比较多。同时当接口添加了一个方法时,除了实现类,所有的代理类也要添加改方法的实现,增加了代码维护工作量。
2. 动态代理
动态代理改进了静态代理的一些缺点,主要是编译后动态生成字节码并加载到JVM中进行实现。也被叫做JDK代理
BasicImpl01.java
public class BasicImpl01 implements BasicSubject{ @Override public void doSomething() { System.out.println("01 do something!"); } }
BasicImpl02.java
public class BasicImpl02 implements BasicSubject{ @Override public void doSomething() { System.out.println("02 do something!"); } }
DynamicSubjectProxy.java
public class DynamicSubjectProxy implements InvocationHandler { private Object ProxyObject; public Object newProxyInstance(Object ProxyObject){ this.ProxyObject = ProxyObject; return Proxy.newProxyInstance( ProxyObject.getClass().getClassLoader(), ProxyObject.getClass().getInterfaces(), this ); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before do something"); Object result = method.invoke(ProxyObject, args); System.out.println("after do something"); return result; } }
TestDynamicProxy.java
public class TestDynamicProxy { public static void main(String[] args) { DynamicSubjectProxy dynamicProxy = new DynamicSubjectProxy(); BasicImpl01 basicImpl01 = new BasicImpl01(); BasicImpl02 basicImpl02 = new BasicImpl02(); BasicSubject basicSubject01 = (BasicSubject) dynamicProxy.newProxyInstance(basicImpl01); basicSubject01.doSomething(); BasicSubject basicSubject02 = (BasicSubject) dynamicProxy.newProxyInstance(basicImpl02); basicSubject02.doSomething(); } }
动态代理对象不需要实现接口,但是要求目标对象必须实现接口,否则不能使用动态代理。
3. Cglib代理
cglib可以代理没有实现接口的类
使用时需要引入jar包
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.2.5</version> </dependency>
AdminCglibService.java
public class AdminCglibService { public void doSomething(){ System.out.println("do something!"); } public Object returnSomething(){ System.out.println("return something!"); return new Object(); } }
AdminServiceCglibProxy.java
public class AdminServiceCglibProxy implements MethodInterceptor { private Object target; public AdminServiceCglibProxy(Object target){ this.target = target; } public Object getProxyInstance(){ Enhancer en = new Enhancer(); en.setSuperclass(target.getClass()); en.setCallback(this); return en.create(); } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("before"); Object obj = method.invoke(target); System.out.println("after"); return obj; } }
CglibProxyTest.java
public class CglibProxyTest { public static void main(String[] args) { AdminCglibService target = new AdminCglibService(); AdminServiceCglibProxy proxyFactory = new AdminServiceCglibProxy(target); AdminCglibService proxy = (AdminCglibService) proxyFactory.getProxyInstance(); Object obj = proxy.returnSomething(); proxy.doSomething(); } }
对比
- 静态代理实现比较简单,只需要对对象进行封装,即可实现功能,但是静态代理只能代理一个目标对象,当目标对象过多时,需要重复编写许多代理类。
- 动态代理需要目标对象实现业务接口,代理类只需实现InvocationHandler接口。
- 静态代理在编译时就产生class字节码文件,效率较高
- 动态代理必须实现InvocationHandler接口,通过反射代理方法,比较消耗系统性能,但可以减少代理类的数量,使用更灵活
- cglib代理无需实现接口,通过生成类字节码实现代理,比反射稍快,不存在性能问题,但cglib会继承目标对象,需要重写方法,所以目标对象不能为final类
这篇关于java代理模式的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-10-01基于Python+Vue开发的医院门诊预约挂号系统
- 2024-10-01基于Python+Vue开发的旅游景区管理系统
- 2024-10-01RestfulAPI入门指南:打造简单易懂的API接口
- 2024-10-01初学者指南:了解和使用Server Action
- 2024-10-01Server Component入门指南:搭建与配置详解
- 2024-10-01React 中使用 useRequest 实现数据请求
- 2024-10-01使用 golang 将ETH账户的资产平均分散到其他账户
- 2024-10-01JWT用户校验课程:从入门到实践
- 2024-10-01Server Component课程入门指南
- 2024-09-30Dnd-Kit学习:新手快速入门指南