动态代理主要是为了处理重复创建模板代码的场景。
使用示例
public interface MyInterface {
String doSomething();
}
public class MyInterfaceImpl implements MyInterface{
@Override
public String doSomething() {
return "接口方法dosomething";
}
}
public class MyInvocationHandler implements InvocationHandler {
private final Object target;
public MyInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
System.out.println("Before method: " + method.getName());
Object result = method.invoke(target, objects); // 调用实际对象的方法
System.out.println("After method: " + method.getName());
return result;
}
}
public class Execute {
public String execute(){
MyInterface realObject = new MyInterfaceImpl();
MyInterface proxyInstance = (MyInterface) Proxy.newProxyInstance(
MyInterface.class.getClassLoader(),
new Class<?>[] { MyInterface.class },
new MyInvocationHandler(realObject)
);
return proxyInstance.doSomething(); // 调用代理对象的方法,实际调用的是
}
}
Proxy.newProxyInstance是Java动态代理的核心方法,其三个参数功能如下:
ClassLoader loader
负责加载动态生成的代理类字节码,通常使用目标接口的类加载器(如UserService.class.getClassLoader())23。该参数决定代理类的JVM加载方式1。
Class<?>[] interfaces
指定代理类需要实现的接口数组(如new Class[]{A.class, B.class}),代理对象将具备这些接口定义的方法能力35。注意该参数仅定义接口而非具体被代理对象1。
InvocationHandler handler
通过实现invoke方法定义代理逻辑,当调用代理对象方法时会触发此处理器,参数包含代理实例、方法对象及方法参数45。开发者在此实现横切逻辑(如日志、事务)