掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
不出意外,你可能只知道兩種類代理的方式。一種是JDK自帶的,另外一種是CGLIB。

創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、前郭網(wǎng)絡(luò)推廣、微信小程序定制開發(fā)、前郭網(wǎng)絡(luò)營銷、前郭企業(yè)策劃、前郭品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供前郭建站搭建服務(wù),24小時(shí)服務(wù)熱線:18982081108,官方網(wǎng)址:www.cdcxhl.com
我們先定義出一個(gè)接口和相應(yīng)的實(shí)現(xiàn)類,方便后續(xù)使用代理類在方法中添加輸出信息。
「定義接口」
- public interface IUserApi {
- String queryUserInfo();
- }
「實(shí)現(xiàn)接口」
- public class UserApi implements IUserApi {
- public String queryUserInfo() {
- return "沉淀、分享、成長,讓自己和他人都能有所收獲!";
- }
- }
好!接下來我們就給這個(gè)類方法使用代理加入一行額外輸出的信息。
- @Test
- public void test_reflect() throws Exception {
- Class
clazz = UserApi.class; - Method queryUserInfo = clazz.getMethod("queryUserInfo");
- Object invoke = queryUserInfo.invoke(clazz.newInstance());
- System.out.println(invoke);
- }
- public class JDKProxy {
- public static
T getProxy(Class clazz) throws Exception { - ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
- return (T) Proxy.newProxyInstance(classLoader, new Class[]{clazz}, new InvocationHandler() {
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- System.out.println(method.getName() + " 你被代理了,By JDKProxy!");
- return "沉淀、分享、成長,讓自己和他人都能有所收獲!";
- }
- });
- }
- }
- @Test
- public void test_JDKProxy() throws Exception {
- IUserApi userApi = JDKProxy.getProxy(IUserApi.class);
- String invoke = userApi.queryUserInfo();
- logger.info("測試結(jié)果:{}", invoke);
- }
- /**
- * 測試結(jié)果:
- *
- * queryUserInfo 你被代理了,By JDKProxy!
- * 19:55:47.319 [main] INFO org.itstack.interview.test.ApiTest - 測試結(jié)果: 沉淀、分享、成長,讓自己和他人都能有所收獲!
- *
- * Process finished with exit code 0
- */
- public class CglibProxy implements MethodInterceptor {
- public Object newInstall(Object object) {
- return Enhancer.create(object.getClass(), this);
- }
- public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
- System.out.println("我被CglibProxy代理了");
- return methodProxy.invokeSuper(o, objects);
- }
- }
- @Test
- public void test_CglibProxy() throws Exception {
- CglibProxy cglibProxy = new CglibProxy();
- UserApi userApi = (UserApi) cglibProxy.newInstall(new UserApi());
- String invoke = userApi.queryUserInfo();
- logger.info("測試結(jié)果:{}", invoke);
- }
- /**
- * 測試結(jié)果:
- *
- * queryUserInfo 你被代理了,By CglibProxy!
- * 19:55:47.319 [main] INFO org.itstack.interview.test.ApiTest - 測試結(jié)果: 沉淀、分享、成長,讓自己和他人都能有所收獲!
- *
- * Process finished with exit code 0
- */
- public class ASMProxy extends ClassLoader {
- public static
T getProxy(Class clazz) throws Exception { - ClassReader classReader = new ClassReader(clazz.getName());
- ClassWriter classWriter = new ClassWriter(classReader, ClassWriter.COMPUTE_MAXS);
- classReader.accept(new ClassVisitor(ASM5, classWriter) {
- @Override
- public MethodVisitor visitMethod(int access, final String name, String descriptor, String signature, String[] exceptions) {
- // 方法過濾
- if (!"queryUserInfo".equals(name))
- return super.visitMethod(access, name, descriptor, signature, exceptions);
- final MethodVisitor methodVisitor = super.visitMethod(access, name, descriptor, signature, exceptions);
- return new AdviceAdapter(ASM5, methodVisitor, access, name, descriptor) {
- @Override
- protected void onMethodEnter() {
- // 執(zhí)行指令;獲取靜態(tài)屬性
- methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
- // 加載常量 load constant
- methodVisitor.visitLdcInsn(name + " 你被代理了,By ASM!");
- // 調(diào)用方法
- methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
- super.onMethodEnter();
- }
- };
- }
- }, ClassReader.EXPAND_FRAMES);
- byte[] bytes = classWriter.toByteArray();
- return (T) new ASMProxy().defineClass(clazz.getName(), bytes, 0, bytes.length).newInstance();
- }
- }
- @Test
- public void test_ASMProxy() throws Exception {
- IUserApi userApi = ASMProxy.getProxy(UserApi.class);
- String invoke = userApi.queryUserInfo();
- logger.info("測試結(jié)果:{}", invoke);
- }
- /**
- * 測試結(jié)果:
- *
- * queryUserInfo 你被代理了,By ASM!
- * 20:12:26.791 [main] INFO org.itstack.interview.test.ApiTest - 測試結(jié)果: 沉淀、分享、成長,讓自己和他人都能有所收獲!
- *
- * Process finished with exit code 0
- */
- public class ByteBuddyProxy {
- public static
T getProxy(Class clazz) throws Exception { - DynamicType.Unloaded> dynamicType = new ByteBuddy()
- .subclass(clazz)
- .method(ElementMatchers.
named("queryUserInfo")) - .intercept(MethodDelegation.to(InvocationHandler.class))
- .make();
- return (T) dynamicType.load(Thread.currentThread().getContextClassLoader()).getLoaded().newInstance();
- }
- }
- @RuntimeType
- public static Object intercept(@Origin Method method, @AllArguments Object[] args, @SuperCall Callable> callable) throws Exception {
- System.out.println(method.getName() + " 你被代理了,By Byte-Buddy!");
- return callable.call();
- }
- @Test
- public void test_ByteBuddyProxy() throws Exception {
- IUserApi userApi = ByteBuddyProxy.getProxy(UserApi.class);
- String invoke = userApi.queryUserInfo();
- logger.info("測試結(jié)果:{}", invoke);
- }
- /**
- * 測試結(jié)果:
- *
- * queryUserInfo 你被代理了,By Byte-Buddy!
- * 20:19:44.498 [main] INFO org.itstack.interview.test.ApiTest - 測試結(jié)果: 沉淀、分享、成長,讓自己和他人都能有所收獲!
- *
- * Process finished with exit code 0
- */
- public class JavassistProxy extends ClassLoader {
- public static
T getProxy(Class clazz) throws Exception { - ClassPool pool = ClassPool.getDefault();
- // 獲取類
- CtClass ctClass = pool.get(clazz.getName());
- // 獲取方法
- CtMethod ctMethod = ctClass.getDeclaredMethod("queryUserInfo");
- // 方法前加強(qiáng)
- ctMethod.insertBefore("{System.out.println(\"" + ctMethod.getName() + " 你被代理了,By Javassist\");}");
- byte[] bytes = ctClass.toBytecode();
- return (T) new JavassistProxy().defineClass(clazz.getName(), bytes, 0, bytes.length).newInstance();
- }
- }
- @Test
- public void test_JavassistProxy() throws Exception {
- IUserApi userApi = JavassistProxy.getProxy(UserApi.class)
- String invoke = userApi.queryUserInfo();
- logger.info("測試結(jié)果:{}", invoke);
- }
- /**
- * 測試結(jié)果:
- *
- * queryUserInfo 你被代理了,By Javassist
- * 20:23:39.139 [main] INFO org.itstack.interview.test.ApiTest - 測試結(jié)果: 沉淀、分享、成長,讓自己和他人都能有所收獲!
- *
- * Process finished with exit code 0
- */

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流