Java动态代理原理及其应用场景实例
Java动态代理是一种在运行时动态创建代理类和对象的机制,它允许在不修改原类代码的情况下,增加额外的功能。动态代理主要通过java.lang.reflect.Proxy
类和java.lang.reflect.InvocationHandler
接口实现。
动态代理原理1. 接口定义:动态代理要求被代理的类必须实现一个或多个接口。
- 创建代理类:
Proxy
类的newProxyInstance
方法在运行时动态创建一个实现了指定接口的代理类实例。 - 实现InvocationHandler:创建一个实现了
InvocationHandler
接口的类,该类负责处理对代理对象方法的调用。 - 方法调用:当代理对象的方法被调用时,
InvocationHandler
的invoke
方法会被触发,你可以在这个方法中添加额外的逻辑,然后调用原始对象的方法。
应用场景实例####场景一:日志记录假设我们有一个接口Calculator
,我们希望在执行计算操作时记录日志。
```javapublic interface Calculator {
int add(int a, int b);
int subtract(int a, int b);
}
public class CalculatorImpl implements Calculator {
public int add(int a, int b) {
return a + b;
}
public int subtract(int a, int b) {
return a - b;
}
}
public class LoggingInvocationHandler implements InvocationHandler {
private Object target;
public LoggingInvocationHandler(Object target) {
this.target = target;
}
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(“Before method: “ + method.getName());
Object result = method.invoke(target, args);
System.out.println(“After method: “ + method.getName());
return result;
}
}
// 使用动态代理创建日志记录的代理对象Calculator calculatorProxy = (Calculator) Proxy.newProxyInstance(
Calculator.class.getClassLoader(),
new Class[] { Calculator.class },
new LoggingInvocationHandler(new CalculatorImpl())
);
//调用代理对象的方法int result = calculatorProxy.add(5,3);``在这个例子中,每次调用
Calculator`接口的方法时,都会在方法执行前后打印日志。
场景二:权限控制我们可以创建一个动态代理来控制对某些方法的访问权限。
```javapublic class AccessControlInvocationHandler implements InvocationHandler {
private Object target;
private Map
public AccessControlInvocationHandler(Object target, Map
this.target = target;
this.accessMap = accessMap;
}
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (accessMap.getOrDefault(method, true)) {
return method.invoke(target, args);
} else {
throw new SecurityException(“Access denied for method: “ + method.getName());
}
}
}
//定义权限控制Map
accessMap.put(CalculatorImpl.class.getMethod(“add”, int.class, int.class), true);
accessMap.put(CalculatorImpl.class.getMethod(“subtract”, int.class, int.class), false);
Calculator calculatorProxy = (Calculator) Proxy.newProxyInstance(
Calculator.class.getClassLoader(),
new Class[] { Calculator.class },
new AccessControlInvocationHandler(new CalculatorImpl(), accessMap)
);
//尝试调用方法try {
calculatorProxy.subtract(5,3);
} catch (SecurityException e) {
System.out.println(e.getMessage());
}``在这个例子中,我们通过
AccessControlInvocationHandler控制对
subtract`方法的访问,使其被拒绝。
动态代理是一种强大的技术,可以用于实现诸如日志记录、权限控制、事务管理等多种功能,而无需修改原始类代码。
还没有评论,来说两句吧...