代理设计模式是一种常用的设计模式,属于结构型模式的一种。代理对象通过持有真实对象来达到访问真实对象的功能,从而保护真实对象,并且可以扩展真实对象的功能。代理设计模式一般有三种:静态代理、JDK动态代理和Cglib动态代理。
静态代理
静态代理中,真实对象和代理对象需要实现同一个接口。
接口类:
package com.test.staticproxy;
public interface FunctionInterface {
void function();
}
真实对象类:
package com.test.staticproxy;
public class RealFunctionProvider implements FunctionInterface {
@Override
public void function() {
System.out.println("RealFunctionProvider -> function() ");
}
}
代理对象类:
package com.test.staticproxy;
public class ProxyFunctionProvider implements FunctionInterface {
private RealFunctionProvider realObject;
public ProxyFunctionProvider(RealFunctionProvider realObject) {
this.realObject = realObject;
}
@Override
public void function() {
System.out.println("ProxyFunctionProvider -> function()");
realObject.function();
}
}
测试类:
package com.test.staticproxy;
public class Test {
public static void main(String[] args) {
RealFunctionProvider realObject = new RealFunctionProvider();
ProxyFunctionProvider proxyObject = new ProxyFunctionProvider(realObject);
proxyObject.function();
}
}
执行结果:
JDK动态代理
在JDK中的java.lang.reflect包下有一个InvocationHandler接口,是JDK动态代理需要实现的接口。JDK动态代理是通过反射机制,动态生成接口的实例来代理真实对象。
接口类:
package com.test.jdkdynamicproxy;
public interface FunctionInterface {
void function();
}
真实对象类:
package com.test.jdkdynamicproxy;
public class RealFunctionProvider implements FunctionInterface {
@Override
public void function() {
System.out.println("RealFunctionProvider -> function()");
}
}
代理对象类:
package com.test.jdkdynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicProxyFunctionProvider implements InvocationHandler {
RealFunctionProvider realObject;
public DynamicProxyFunctionProvider(RealFunctionProvider realObject) {
this.realObject = realObject;
}
@Override
public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable {
System.out.println("DynamicProxyFunctionProvider -> invoke");
arg1.invoke(realObject, arg2);
return realObject;
}
}
代理类需要实现InvocationHandler 接口和invoke方法,invoke方法中有三个参数分别是:代理对象、调用的接口方法的 Method 实例和代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为 null。
在invoke方法体中,应该通过arg1.invoke(realObject, arg2);传入真实对象和方法参数。
测试类:
package com.test.jdkdynamicproxy;
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) {
RealFunctionProvider realObject = new RealFunctionProvider();
DynamicProxyFunctionProvider proxyObject = new DynamicProxyFunctionProvider(realObject);
ClassLoader classLoader = realObject.getClass().getClassLoader();
FunctionInterface fun = (FunctionInterface) Proxy.newProxyInstance(classLoader,
new Class[]{FunctionInterface.class}, proxyObject);
fun.function();
}
}
运行结果:
Cglib动态代理
实现Cglib动态代理需要引入Cglib的jar包和依赖包:
使用Cglib实现动态时,真实对象类不需要实现接口,代理类需要实现Cglib中的MethodInterceptor接口。在运行过程会创建真实对象的子类来实现代理。
真实对象类:
package com.test;
public class RealFunctionProvider {
public void function() {
System.out.println("RealFunctionProvider -> function");
}
}
代理类:
package com.test;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CglibDynamicProxyFunctionProvider implements MethodInterceptor{
@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
System.out.println("CglibDynamicProxyFunctionProvider -> intercept");
Object result = arg3.invokeSuper(arg0, arg2);
return result;
}
}
测试类:
package com.test;
import net.sf.cglib.proxy.Enhancer;
public class Test {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(RealFunctionProvider.class);
enhancer.setCallback(new CglibDynamicProxyFunctionProvider());
RealFunctionProvider realObject = (RealFunctionProvider) enhancer.create();
realObject.function();
}
}
运行结果:
Cglib是基于字节码操作的,不需要通过反射,执行效率要高于JDK动态代理;不需要实现接口,在执行的过程中会生成真实对象的子类来代理。