第一个做电子商务的网站,物联网应用前景,广州注册公司一网通,贵阳市做网站公司本文主要介绍CGLib和JDK动态代理的使用#xff0c;不对源码进行深入分析。代码可直接复制使用。 类型 机制 回调方式 适用场景 效率 JDK动态代理 委托机制。代理类和目标类都实现了同样的接口。InvocationHandler持有目标类。代理类委托InvocationHandler去调用目标类原…本文主要介绍CGLib和JDK动态代理的使用不对源码进行深入分析。代码可直接复制使用。 类型 机制 回调方式 适用场景 效率 JDK动态代理 委托机制。代理类和目标类都实现了同样的接口。InvocationHandler持有目标类。代理类委托InvocationHandler去调用目标类原始方法 反射 目标类实现接口 反射调用稍慢。 CGLIB动态代理 继承机制。代理类继承了目标类并重写了目标方法通过回调函数MethodInterceptor调用父类方法执行原始逻辑(底层使用到ASM技术操作字节码生成代理类) 通过FastClass方法索引调用 非final类非final方法 第一次调用因为要生成多个Class对象较]DK慢但是调用时方法索引较反射方式快
代码框架 类UserInterface
package com.cocoa.dao;public interface UserInterface {public void test();
}类UserService
package com.cocoa.dao;public class UserService implements UserInterface{Overridepublic void test() {System.out.println(UserService test() -- print);}
}类CGLIBDemo
method.invoke()使用的还是反射机制但是methodProxy.invoke使用的不是反射而是FastClass机制通过建立代理类的索引快速执行代理的方法。所以比JDK快
MethodIntercept的入参
o目标对象的实例被代理的对象
method被代理的方法
objects方法调用时的入参
methodProxy用于调用原始方法的代理。
package com.cocoa.enhancer;import com.cocoa.dao.UserService;
import org.springframework.cglib.core.DebuggingClassWriter;
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 CGLIBDemo {public static void Main(String[] args) {// 动态代理生成的字节码存储到本地System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, com.cocoa.enhancer);final UserService target new UserService();// 增强器Enhancer enhancer new Enhancer();// enhancer.setUseCache(false);// 使用缓存// 设置代理的类enhancer.setSuperclass(UserService.class);// 设置代理逻辑enhancer.setCallback(new MethodInterceptor() {Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {if (method.getName().equals(test)){System.out.println(before...);method.invoke(target, objects);System.out.println(after...);}return null;}});// 使用代理类UserService userService (UserService) enhancer.create();// create会将第一次产生的代理类缓存下来userService.test();}
}要避免使用method.invoke()应该使用methodProxy。
类CGLIBDemo1
使用methodProxy.invoke执行方法(通过FastCLass索引机制)
methodProxy.invoke(target, objects);// test() 正常运行直接执行代理方法
methodProxy.invoke(o, objects);// o 表示代理对象这样会导致死循环
methodProxy.invokeSuper(target, objects);// CGLIB$test$4() 因为target中没有代理对象的方法
methodProxy.invokeSuper(o, objects);// CGLIB$test$4() 执行代理对象o中的test方法 正常运行
package com.cocoa.enhancer;import com.cocoa.dao.UserService;
import org.springframework.cglib.core.DebuggingClassWriter;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;import java.lang.reflect.Method;/*** MethodProxy的使用*/
public class CGLIBDemo1 {public static void main(String[] args) {System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, com.cocoa.enhancer);final UserService target new UserService();// 增强器Enhancer enhancer new Enhancer();// enhancer.setUseCache(false);// 使用缓存// 设置代理的类enhancer.setSuperclass(UserService.class);// 设置代理逻辑enhancer.setCallback(new MethodInterceptor() {Override// o代理对象 objects入参 method被代理的方法 methodProxy代理的方法public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {if (method.getName().equals(test)){System.out.println(before...);// MethodProxy 表示方法代理代理了两个方法 test()
// methodProxy.invoke(target, objects);// test() 可用
// methodProxy.invoke(o, objects);// o 表示代理对象这样会导致死循环
// methodProxy.invokeSuper(target, objects);// CGLIB$test$4() 因为target中没有代理对象的方法methodProxy.invokeSuper(o, objects);// CGLIB$test$4() 执行代理对象o中的test方法 可用System.out.println(after...);}return null;}});// 使用代理类UserService userService (UserService) enhancer.create();// create会将第一次产生的代理类缓存下来userService.test();}
}类mainInterface
package com.cocoa.enhancer;import com.cocoa.dao.UserInterface;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;import java.lang.reflect.Method;/*** CGLIB 可以代理接口*/
public class mainInterface {public static void main(String[] args) {Enhancer enhancer new Enhancer();// 设置代理的接口enhancer.setSuperclass(UserInterface.class);// 设置代理逻辑enhancer.setCallback(new MethodInterceptor() {Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println(切面逻辑...);return null;}});// 使用代理类UserInterface userInterface (UserInterface) enhancer.create();userInterface.test();}
}类JDKDemo
使用proxy.newProxyInstance方法直接构造代理类入参有
1)真实对象的类加载器
2)真实对象实现的接口
3)代理类需要实现InvocationHandler接口重写Invoke方法。
invoke方法的入参
参数1用Proxy.newProxyInstance方法产生的真实对象注意参数1并不显式地出现在方法体内
参数2要调用的目标方法
参数3目标方法中的参数一般是 Object[ ] args。
package com.cocoa.jdkProxy;import com.cocoa.dao.UserInterface;
import com.cocoa.dao.UserService;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class JDKDemo {public static void main(String[] args) {// Proxy.newproxyInstance// 类加载器、代理的接口、new InvocationHandlerUserService target new UserService();UserInterface userInterface (UserInterface) Proxy.newProxyInstance(JDKDemo.class.getClassLoader(), new Class[]{UserInterface.class}, new InvocationHandler() {Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(test);method.invoke(target, args);return null;}});userInterface.test();}
}ASM技术尝鲜
通过ASM字节码技术可以生成一个类。执行下面的代码就可以生成下图中的类。 package com.cocoa.asmDemo;import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;/*** ASM 尝鲜使用*/
public class ASMDemo {public static void main(String[] args) throws IOException {ClassWriter classWriter new ClassWriter(0);// 通过visit 方法确定类的头部信息classWriter.visit(Opcodes.V1_8,// java版本Opcodes.ACC_PUBLIC,// 类修饰符Person, // 类的全限定名null, java/lang/Object, null );// 创建构造函数MethodVisitor mv classWriter.visitMethod(Opcodes.ACC_PUBLIC, init, ()V, null, null);mv.visitCode();mv.visitVarInsn(Opcodes.AALOAD, 0);// 字节码指令mv.visitMethodInsn(Opcodes.INVOKESPECIAL, java/lang/Object, init, ()V);mv.visitInsn(Opcodes.RETURN);mv.visitMaxs(1,1);mv.visitEnd();// 定义test方法MethodVisitor methodVisitor classWriter.visitMethod(Opcodes.ACC_PUBLIC, test, ()V, null, null);methodVisitor.visitCode();methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, java/lang/System, out, Ljava/io/PrintStream;);methodVisitor.visitLdcInsn(hello zhouyu);methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, java/io/PrintStream,println,(Ljava/lang/string;)V);methodVisitor.visitInsn(Opcodes.RETURN);methodVisitor.visitMaxs(2,2);methodVisitor.visitEnd();classWriter.visitEnd();// 使classWriter类已经完成// 将classWriter转换成字节数组写到文件里面大byte[] data classWriter.toByteArray();File file new File( E:\\java_shicao\\DynamicProxyDemo\\src\\main\\java\\People.class);FileOutputStream fout new FileOutputStream(file);fout.write(data);fout.close();}
} 文章转载自: http://www.morning.xtrzh.cn.gov.cn.xtrzh.cn http://www.morning.lfdrq.cn.gov.cn.lfdrq.cn http://www.morning.rgnp.cn.gov.cn.rgnp.cn http://www.morning.nyqzz.cn.gov.cn.nyqzz.cn http://www.morning.nldsd.cn.gov.cn.nldsd.cn http://www.morning.rgxcd.cn.gov.cn.rgxcd.cn http://www.morning.mzhjx.cn.gov.cn.mzhjx.cn http://www.morning.yfnhg.cn.gov.cn.yfnhg.cn http://www.morning.xmnlc.cn.gov.cn.xmnlc.cn http://www.morning.clzly.cn.gov.cn.clzly.cn http://www.morning.kgmkl.cn.gov.cn.kgmkl.cn http://www.morning.yubkwd.cn.gov.cn.yubkwd.cn http://www.morning.lwlnw.cn.gov.cn.lwlnw.cn http://www.morning.drpbc.cn.gov.cn.drpbc.cn http://www.morning.gkfwp.cn.gov.cn.gkfwp.cn http://www.morning.sdamsm.com.gov.cn.sdamsm.com http://www.morning.pqcrz.cn.gov.cn.pqcrz.cn http://www.morning.wklrz.cn.gov.cn.wklrz.cn http://www.morning.yltnl.cn.gov.cn.yltnl.cn http://www.morning.haibuli.com.gov.cn.haibuli.com http://www.morning.mdfxn.cn.gov.cn.mdfxn.cn http://www.morning.nmnhs.cn.gov.cn.nmnhs.cn http://www.morning.zlhbg.cn.gov.cn.zlhbg.cn http://www.morning.gwsdt.cn.gov.cn.gwsdt.cn http://www.morning.ycgrl.cn.gov.cn.ycgrl.cn http://www.morning.jtrqn.cn.gov.cn.jtrqn.cn http://www.morning.bsrp.cn.gov.cn.bsrp.cn http://www.morning.mlyq.cn.gov.cn.mlyq.cn http://www.morning.xrct.cn.gov.cn.xrct.cn http://www.morning.lbcbq.cn.gov.cn.lbcbq.cn http://www.morning.qynpw.cn.gov.cn.qynpw.cn http://www.morning.kjxgc.cn.gov.cn.kjxgc.cn http://www.morning.jrqcj.cn.gov.cn.jrqcj.cn http://www.morning.jwfkk.cn.gov.cn.jwfkk.cn http://www.morning.ltpmy.cn.gov.cn.ltpmy.cn http://www.morning.bnqcm.cn.gov.cn.bnqcm.cn http://www.morning.ctlbf.cn.gov.cn.ctlbf.cn http://www.morning.rbnnq.cn.gov.cn.rbnnq.cn http://www.morning.kxyqy.cn.gov.cn.kxyqy.cn http://www.morning.fnpmf.cn.gov.cn.fnpmf.cn http://www.morning.kmqms.cn.gov.cn.kmqms.cn http://www.morning.ymyhg.cn.gov.cn.ymyhg.cn http://www.morning.pjzcp.cn.gov.cn.pjzcp.cn http://www.morning.nptls.cn.gov.cn.nptls.cn http://www.morning.qsy37.cn.gov.cn.qsy37.cn http://www.morning.wdjcr.cn.gov.cn.wdjcr.cn http://www.morning.pmrlt.cn.gov.cn.pmrlt.cn http://www.morning.zrlms.cn.gov.cn.zrlms.cn http://www.morning.qypjk.cn.gov.cn.qypjk.cn http://www.morning.rhzzf.cn.gov.cn.rhzzf.cn http://www.morning.znqxt.cn.gov.cn.znqxt.cn http://www.morning.zrfwz.cn.gov.cn.zrfwz.cn http://www.morning.rnribht.cn.gov.cn.rnribht.cn http://www.morning.wrlxt.cn.gov.cn.wrlxt.cn http://www.morning.xmnlc.cn.gov.cn.xmnlc.cn http://www.morning.rnzgf.cn.gov.cn.rnzgf.cn http://www.morning.rnzgf.cn.gov.cn.rnzgf.cn http://www.morning.gnmhy.cn.gov.cn.gnmhy.cn http://www.morning.zcwzl.cn.gov.cn.zcwzl.cn http://www.morning.grryh.cn.gov.cn.grryh.cn http://www.morning.khclr.cn.gov.cn.khclr.cn http://www.morning.thbkc.cn.gov.cn.thbkc.cn http://www.morning.gcthj.cn.gov.cn.gcthj.cn http://www.morning.zsrjn.cn.gov.cn.zsrjn.cn http://www.morning.rdlxh.cn.gov.cn.rdlxh.cn http://www.morning.mpszk.cn.gov.cn.mpszk.cn http://www.morning.ryxgk.cn.gov.cn.ryxgk.cn http://www.morning.cbczs.cn.gov.cn.cbczs.cn http://www.morning.plxnn.cn.gov.cn.plxnn.cn http://www.morning.nrlsg.cn.gov.cn.nrlsg.cn http://www.morning.fnpyk.cn.gov.cn.fnpyk.cn http://www.morning.mytmn.cn.gov.cn.mytmn.cn http://www.morning.tztgq.cn.gov.cn.tztgq.cn http://www.morning.mprpx.cn.gov.cn.mprpx.cn http://www.morning.lrprj.cn.gov.cn.lrprj.cn http://www.morning.gsjzs.cn.gov.cn.gsjzs.cn http://www.morning.errnull.com.gov.cn.errnull.com http://www.morning.xznrk.cn.gov.cn.xznrk.cn http://www.morning.wffxr.cn.gov.cn.wffxr.cn http://www.morning.mxptg.cn.gov.cn.mxptg.cn