Java中有两种实现动态代理的方式jdk动态代理和CGLIB动态代理
- jdk动态代理: 基于接口的动态代理, 目标对象必须实现接口
- cglib动态代理: 基于字节生成技术(ASM代码生成库), 能在运行时对java类和接口进行扩展实现
那么动态代理这个技术到底能帮我们干啥?
个人感觉这个技术在框架中用的比较多, 比如SpringAop, servlet的filter, mysql运行时动态生成Mapper接口实现, Spring事务拦截, 日志框架, 权限控制等等
代码实现起来也不难, 下面提供2个demo
jdk-demo
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class ProxyDemo {public static void main(String[] args) {User user = new UserImpl();JdkHandler jdkHandler = new JdkHandler(user);User userJdkProxy = (User) jdkHandler.getProxy();userJdkProxy.getName();}}interface User {String getName();
}class UserImpl implements User{@Overridepublic String getName() {return "test name";}
}class JdkHandler implements InvocationHandler{private Object target;public JdkHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("begin");Object result = method.invoke(target, args);System.out.println(result);System.out.println("end");return result;}public Object getProxy(){return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);}
}
cglib-demo
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;public class ProxyDemo {public static void main(String[] args) {CglibHandler cglibHandler = new CglibHandler();User userJdkProxy = (UserImpl) cglibHandler.getProxy(UserImpl.class);userJdkProxy.getName();}}interface User {String getName();
}class UserImpl implements User{@Overridepublic String getName() {return "test name";}
}class CglibHandler implements MethodInterceptor{private Enhancer enhancer = new Enhancer();public Object getProxy(Class clazz){enhancer.setSuperclass(clazz);enhancer.setCallback(this);return enhancer.create();}@Overridepublic Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {System.out.println("begin");Object result = methodProxy.invokeSuper(o, args);System.out.println(result);System.out.println("end");return result;}
}
执行结果