Java动态代理:原理、应用场景及示例
Java动态代理是一种在运行时根据需要创建对象的机制。它主要依赖于Java的反射API和Proxy类。
原理:
- 使用反射API,提供被代理方法的定义信息。
- 创建一个实现了目标接口的代理类。
- 在代理类中重写或包装被代理的方法。
- 当调用目标对象的被代理方法时,会通过代理类来执行。
应用场景:
- 隐藏实现细节:对于不想暴露给客户端的具体实现代码,可以使用代理隐藏这部分信息。
- 动态扩展功能:在运行时根据需要添加或修改某个对象的功能,可以通过动态代理实现。
- 负载均衡:当多个代理实例同时处理请求时,可以实现负载均衡。
示例:
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
// 假设我们有一个接口和一个具体的实现类
public interface Target {
void doSomething();
}
class ConcreteTarget implements Target {
@Override
public void doSomething() {
System.out.println("Doing something...");
}
}
// 创建动态代理类,实现Target接口
public class DynamicProxy implements Target {
private Object targetInstance;
private List<Method> methodsTo Intercept;
// 构造器,传入具体目标实例
public DynamicProxy(Object targetInstance) {
this.targetInstance = targetInstance;
this.methodsTo Intercept = new ArrayList<>();
}
@Override
public void doSomething() {
System.out.println("Doing something in proxy...");
if (methodsTo Intercept.isEmpty()) {
// 如果没有需要拦截的方法,则直接调用目标实例的方法
targetInstance.doSomething();
} else {
Method methodToIntercept = methodsTo Intercept.get(0);
try {
// 保存被代理方法的原始实现
Method originalMethod = ConcreteTarget.class.getMethod(methodToIntercept.getName()), methodToIntercept.getParameterTypes());
// 实现动态代理,包装目标方法并调用
Object proxyResult = Proxy.newProxyInstance(
targetInstance.getClass().getClassLoader(),
new Class<?>[]{ConcreteTarget.class, Target.class}},
new MethodInterceptor[] {new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args) throws Throwable {
// 调用原始实现方法
return originalMethod.invoke(obj, args));
}
}}}), targetInstance.getClass());
// 调用代理类的方法,实际上会调用被代理对象的方法
proxyResult.doSomething();
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
System.out.println("Error while intercepting method: " + e.getMessage());
}
}
}
// 添加需要拦截的方法到列表中
public void addInterceptorMethod(String methodName, Class<?>[] parameterTypes)) {
methodsTo Intercept.add(new Method(ConcreteTarget.class, methodName), parameterTypes));
}
}
在这个示例中,我们首先定义了一个接口Target
和一个具体的实现类ConcreteTarget
。然后创建了一个动态代理类DynamicProxy
。
在DynamicProxy
中,我们初始化了目标实例以及需要拦截的方法列表。当调用目标方法时,会根据添加的拦截器方法判断是否进行拦截并执行相应的逻辑。
还没有评论,来说两句吧...