动态代理
常用的动态代理技术有两种:
1、JDK代理
2、Cglib代理
JDK代理
要求被代理对象必须有接口,动态代理生成的实际为接口的子类,所以在接收动态代理类是要用父接口。
public class JdkProxyFactory implements InvocationHandler { private Object target; public JdkProxyFactory(Object target){ this.target = target; } public Object getProxyObject(){ //实现第三个参数的invoke方法 return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } //被代理对象方法执行时调用 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("方法执行前增强"); Object object = method.invoke(target, args); System.out.println("方法执行后增强"); if(object == null ){ object = ""; } System.out.println("将null值变为空串"); return object; //返回方法的返回值 } }
Cglib代理
第三方代理框架,已经整合进spring-core包下,被代理对象无需实现接口,代理生成的类为被代理对象的子类。
public class CglibProxyFactory implements MethodInterceptor { private Object target; public CglibProxyFactory(Object target){ this.target = target; } public Object getProxyObject(){ //实例化cglib增强器 Enhancer enhancer = new Enhancer(); //设置两个属性 //1、要代理的类型 enhancer.setSuperclass(target.getClass()); //2、设置回调方法 enhancer.setCallback(this); return enhancer.create(); } /** * 被代理对象方法执行时调用 * @param proxy 生成的代理对象 * @param method 执行的目标对象的方法 * @param args 方法参数 * @param methodProxy 代理后的方法 * @return * @throws Throwable */ @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { System.out.println("记录日志了。。"); // return method.invoke(target, args); // return methodProxy.invoke(target, args); // return methodProxy.invokeSuper(proxy, args); // Object o = method.invoke(target, args); // Object o = methodProxy.invoke(target, args); Object o = methodProxy.invokeSuper(proxy, args); System.out.println(methodProxy.getSignature()); System.out.println(Arrays.toString(methodProxy.getSignature().getArgumentTypes())); System.out.println(methodProxy.getSignature().getName()); System.out.println(methodProxy.getSignature().getReturnType()); System.out.println(methodProxy.getSignature().getDescriptor()); System.out.println(methodProxy.getSuperName()); System.out.println("记录日志结束。。。"); return o; } }