代理对象作为客户端和真实对象之间的中介,替代真实对象处理请求,实现对访问的控制和作用增强。客户端通过代理间接操作真实对象,二者通常实现相同接口。

代理对象作为客户端和真实对象之间的中介,替代真实对象处理请求,实现对访问的控制和作用增强。客户端通过代理间接操作真实对象,二者通常实现相同接口。

目录定义结构适用场景使用实例

定义 代理对象作为客户端和真实对象之间的中介,替代真实对象处理请求,实现对访问的控制和功能增强。客户端通过代理间接操作真实对象,二者通常实现相同接口。

结构

适用场景1)远程代理为一个对象在不同的地址空间提供局部代表 2)虚拟代理根据需要创建开销很大的对象 3)安全代理控制对原始对象的访问 4)日志代理记录操作行为

使用实例这里以日志代理为例,说明java中代理的几种方式。 1、静态代理 2、JDK动态代理 3、Cglib代理

/**

* 定义业务接口

*/

public interface UserService {

void addUser(String username);

void deleteUser(String userId);

}

public class UserServiceImpl implements UserService{

@Override

public void addUser(String username) {

System.out.println("真实操作:添加用户 " + username);

}

@Override

public void deleteUser(String userId) {

System.out.println("真实操作:删除用户ID " + userId);

}

}

/**

* 定义静态代理类

*/

public class UserServiceProxy implements UserService {

private final UserService target;

public UserServiceProxy(UserService target) {

this.target = target;

}

@Override

public void addUser(String username) {

System.out.println("静态代理,【前置日志】调用addUser,参数: " + username);

target.addUser(username); // 调用真实对象

System.out.println("静态代理,【后置日志】addUser执行完成");

}

@Override

public void deleteUser(String userId) {

System.out.println("静态代理,【前置日志】调用deleteUser,参数: " + userId);

target.deleteUser(userId);

System.out.println("静态代理,【后置日志】deleteUser执行完成");

}

}

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

/**

* 定义JDK动态代理核心处理类

*/

public class LoggingHandler implements InvocationHandler {

private final Object target;

public LoggingHandler(Object target) {

if (target == null) {

throw new IllegalArgumentException("Target object cannot be null");

}

this.target = target;

}

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

System.out.println("JDK,调用方法: " + method.getName());

return method.invoke(target, args);

}

}

import net.sf.cglib.proxy.MethodInterceptor;

import net.sf.cglib.proxy.MethodProxy;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;

/**

* 定义Cglib代理核心处理类

*/

public class LogInterceptor implements MethodInterceptor {

private static final Logger logger = LoggerFactory.getLogger(LogInterceptor.class);

@Override

public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {

logger.info("Cglib,方法调用开始 => {}.{}()", obj.getClass().getSuperclass().getSimpleName(), method.getName());

Object result = proxy.invokeSuper(obj, args);

logger.info("Cglib,方法调用结束 <= {}", method.getName());

return result;

}

}

测试

import net.sf.cglib.proxy.Enhancer;

import java.lang.reflect.Proxy;

public class Client {

public static void main(String[] args) {

// 静态代理

UserService realService = new UserServiceImpl();

UserService proxy = new UserServiceProxy(realService);

proxy.addUser("张三");

proxy.deleteUser("100001");

// jdk动态代理

UserService jdkProxy = (UserService) Proxy.newProxyInstance(

UserService.class.getClassLoader(),

new Class[]{UserService.class},

new LoggingHandler(realService)

);

jdkProxy.addUser("Alice");

jdkProxy.deleteUser("100002");

// Cglib代理(针对类)

Enhancer enhancer = new Enhancer();

enhancer.setSuperclass(UserServiceImpl.class);

enhancer.setCallback(new LogInterceptor());

UserService cglibProxy = (UserService) enhancer.create();

cglibProxy.addUser("张五");

cglibProxy.deleteUser("100003");

}

}

相关推荐

汕头中博职校今年预计招生1700人,2个专业进入“职普同招”第一梯队
3800 日元等于多少人民币?
base365

3800 日元等于多少人民币?

📅 01-19 👁️ 5492
战争艺术:赤潮
365娱乐游戏是什么

战争艺术:赤潮

📅 10-24 👁️ 1553