Java动态代理是一种代理设计模式,能够在方法调用时动态地创建一个代理对象,而不是在编译时创建静态代理对象。Java动态代理是通过反射机制实现的,可以在运行时创建代理和方法调用。
Java动态代理实现原理主要包括三个方面:代理对象、InvocationHandler接口和反射机制。其具体实现步骤如下:
1.创建一个实现InvocationHandler接口的类,重写其中的invoke()方法,该方法中的逻辑定义了代理对象实现的方法的具体行为,以及对被代理对象方法的调用。
示例代码:
public class MyInvocationHandler implements InvocationHandler {
private Object target;
public MyInvocationHandler(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;
}
}
2.通过Proxy类的newProxyInstance()方法创建一个代理对象,该方法需要传递三个参数:ClassLoader、Class[]和InvocationHandler。其中ClassLoader是指定代理对象使用的类加载器,Class[]是指被代理对象实现的接口数组,InvocationHandler是实现InvocationHandler接口的对象。
示例代码:
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
InvocationHandler handler = new MyInvocationHandler(realSubject);
Subject proxy = (Subject) Proxy.newProxyInstance(RealSubject.class.getClassLoader(), RealSubject.class.getInterfaces(), handler);
proxy.request();
}
3.调用代理对象的方法时,会自动调用InvocationHandler接口的invoke()方法,在该方法中对方法调用进行处理,并通过反射机制调用被代理对象的方法。
示例代码:
public interface Subject {
void request();
}
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("RealSubject:request");
}
}
public class MyInvocationHandler implements InvocationHandler {
private Object target;
public MyInvocationHandler(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;
}
}
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
InvocationHandler handler = new MyInvocationHandler(realSubject);
Subject proxy = (Subject) Proxy.newProxyInstance(RealSubject.class.getClassLoader(), RealSubject.class.getInterfaces(), handler);
proxy.request();
}
输出结果为:
Before method request
RealSubject:request
After method request
另外,Java动态代理还可以通过CGLIB库实现,CGLIB是一种基于ASM实现的Java字节码生成库,可以动态生成Java类。与Java动态代理不同的是,CGLIB可以代理非接口类型的类。
示例代码:
public class Subject {
public void request() {
System.out.println("Subject:request");
}
}
public class CglibProxy implements MethodInterceptor {
private Object target;
public CglibProxy(Object target) {
this.target = target;
}
public Object getProxy() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("Before method " + method.getName());
Object result = methodProxy.invoke(target, objects);
System.out.println("After method " + method.getName());
return result;
}
}
public static void main(String[] args) {
Subject subject = new Subject();
CglibProxy proxy = new CglibProxy(subject);
Subject proxySubject = (Subject) proxy.getProxy();
proxySubject.request();
}
输出结果为:
Before method request
Subject:request
After method request
以上是Java动态代理的实现原理以及示例说明。在实际开发中,Java动态代理可以应用于AOP编程、事务处理、缓存处理等方面,具有很高的使用价值。