厦门+外贸公司做网站重庆seo网站推广优化
代理模式是一种常用的设计模式,为其他对象提供一种代理以控制对这个对象的访问。代理模式就像是一个中间人,客户端通过代理来间接访问目标对象,可以在不修改目标对象的基础上,对目标对象的功能进行增强或扩展。代理模式主要分为静态代理和动态代理,本文将详细探讨这两种代理模式。
本文目录
- 一、静态代理
- 1. 代码实现
- 2. 优缺点
- 二、动态代理
- 1. JDK动态代理实现
- 2. CGLIB动态代理
一、静态代理
静态代理是指在编译时就已经确定代理类和目标类的关系。代理类和目标类都需要实现相同的接口,代理类中持有目标类的引用,在代理类的方法中调用目标类的相应方法,并可以在调用前后添加额外的逻辑。
1. 代码实现
// 定义接口
interface UserService {void addUser();void deleteUser();
}// 实现类
class UserServiceImpl implements UserService {@Overridepublic void addUser() {System.out.println("添加用户");}@Overridepublic void deleteUser() {System.out.println("删除用户");}
}// 静态代理类
class UserServiceProxy implements UserService {private UserService target;public UserServiceProxy(UserService target) {this.target = target;}@Overridepublic void addUser() {System.out.println("添加用户前的日志记录");target.addUser();System.out.println("添加用户后的日志记录");}@Overridepublic void deleteUser() {System.out.println("删除用户前的日志记录");target.deleteUser();System.out.println("删除用户后的日志记录");}
}public class StaticProxy {public static void main(String[] args) {UserService target = new UserServiceImpl();UserService proxy = new UserServiceProxy(target);proxy.addUser();System.out.println("-------------------");proxy.deleteUser();}
}
在代理类的方法中,调用
目标对象的方法前后
添加了日志记录的逻辑
2. 优缺点
- 优点:实现简单,易于理解,在编译时就可以确定代理关系,性能相对较高。
- 缺点:代理类和目标类必须实现相同的接口,当接口方法发生变化时,代理类和目标类都需要修改。而且如果需要代理多个不同的目标类,就需要为每个目标类创建一个对应的代理类,代码会变得冗余。
二、动态代理
动态代理是指在运行时动态生成代理类,而不需要在编译时就确定代理类的代码。Java提供了两种实现动态代理的方式:JDK 动态代理和 CGLIB 动态代理。
1. JDK动态代理实现
JDK 动态代理是基于接口的动态代理,它使用 java.lang.reflect.Proxy
类和 java.lang.reflect.InvocationHandler
接口来实现。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;interface UserService {void addUser();void deleteUser();
}class UserServiceImpl implements UserService {@Overridepublic void addUser() {System.out.println("添加用户");}@Overridepublic void deleteUser() {System.out.println("删除用户");}
}// 自定义InvocationHandler
class MyInvocationHandler implements InvocationHandler {private Object target;public MyInvocationHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(method.getName() + " 方法调用前的日志记录");Object result = method.invoke(target, args);System.out.println(method.getName() + " 方法调用后的日志记录");return result;}
}public class JdkDynamicProxy {public static void main(String[] args) {UserService target = new UserServiceImpl();MyInvocationHandler handler = new MyInvocationHandler(target);UserService proxy = (UserService) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),handler);proxy.addUser();System.out.println("-------------------");proxy.deleteUser();}
}
这种方式不需要为每个目标类创建代理类,只需要实现
InvocationHandler
接口,就可以为多个目标类提供代理服务。只能代理实现了接口的类,不能代理没有实现接口的类。
2. CGLIB动态代理
CGLIB 动态代理是基于继承的动态代理,可以代理没有实现接口的类。CGLIB是一个强大的、高性能的代码生成库,通过继承目标类来生成代理类。
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;// 目标类
class UserService {public void addUser() {System.out.println("添加用户");}public void deleteUser() {System.out.println("删除用户");}
}// 自定义MethodInterceptor
class MyMethodInterceptor implements MethodInterceptor {@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println(method.getName() + " 方法调用前的日志记录");Object result = proxy.invokeSuper(obj, args);System.out.println(method.getName() + " 方法调用后的日志记录");return result;}
}public class CglibDynamicProxy {public static void main(String[] args) {Enhancer enhancer = new Enhancer();enhancer.setSuperclass(UserService.class);enhancer.setCallback(new MyMethodInterceptor());UserService proxy = (UserService) enhancer.create();proxy.addUser();System.out.println("-------------------");proxy.deleteUser();}
}
可以代理没有实现接口的类,灵活性更高,但是由于是基于继承实现的,所以不能代理 final
类和 final
方法。
← 上一篇 Java进阶——常用类及常用方法详解 | 记得点赞、关注、收藏哦! | 下一篇 Java进阶——数组超详细整理 → |