1、jdk代理

针对接口进行代理,接口可以没有方法, InvocationHandler会拦截所有方法,不过好像意义不大....只能执行Object类的方法,执行结果有点奇怪...

package test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class TestJdkProxy { public static void main(String[] args) { //接口的实例对象,这里用的匿名对象
Test test = new Test() {
}; //拦截类
InvocationHandler invocationHandler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//proxy为实际创建的代理类, method为代理类执行的方法, args为方法调用对应的参数 System.out.println("代理前");
Object object = method.invoke(test, args);
System.out.println("代理后"); return object;
}
}; Test proxy = (Test) Proxy.newProxyInstance(test.getClass().getClassLoader(),
test.getClass().getInterfaces(), invocationHandler); System.out.println("-------------------------------");
System.out.println(proxy.equals(proxy)); // ? 有点奇怪, 是false
System.out.println("-------------------------------");
System.out.println(Integer.toHexString(proxy.hashCode()));
System.out.println("-------------------------------");
System.out.println(proxy.toString()); // Object类的toString方法调用了一次hashCode方法, toString方法和hashCode方法只拦截了一次?
} public interface Test { } }

输出为:

-------------------------------
代理前
代理后
false
-------------------------------
代理前
代理后
61bbe9ba
-------------------------------
代理前
代理后
test.TestJdkProxy$1@61bbe9ba

接口有方法情况:

package test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class TestJdkProxy { public static void main(String[] args) { //接口的实例对象,这里用的匿名对象
Test test = new Test() {
@Override
public void test() {
System.out.println("执行代理的接口方法");
}
}; //拦截类
InvocationHandler invocationHandler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//proxy为实际创建的代理类, method为代理类执行的方法, args为方法调用对应的参数 System.out.println("代理前");
Object object = method.invoke(test, args);
System.out.println("代理后"); return object;
}
}; Test proxy = (Test) Proxy.newProxyInstance(test.getClass().getClassLoader(),
test.getClass().getInterfaces(), invocationHandler);
proxy.test();
} public interface Test {
void test();
} }

输出为

代理前
执行代理的接口方法
代理后

2、cglib代理

代理类不能为final 类,

maven引入jar包

        <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
package test;

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 TestCglibProxy { public static void main(String[] args) throws Exception { MethodInterceptor handler = new MethodInterceptor() {
@Override
public Object intercept(Object proxy, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//proxy为创建的代理类, 我的理解是对需要代理的类进行了继承(?), 所以需要代理的类不能为final类 System.out.println("代理前");
Object result = methodProxy.invokeSuper(proxy, objects);
System.out.println("代理后");
return result;
}
}; Enhancer enhancer = new Enhancer();
//设置需要代理的类,不能是final类
enhancer.setSuperclass(Test.class);
//设置方法拦截
enhancer.setCallback(handler);
//创建代理类,根据Test构造方法所需要的参数指定create参数, 如本例中Test类有String参数构造方法
Test test = (Test) enhancer.create(new Class[]{String.class}, new Object[]{"Aa"});
test.test();
System.out.println("-------------------------------");
test = (Test) enhancer.create();
test.test();
System.out.println("-------------------------------");
//对代理类的方法都会进行拦截, Object类的toString方法调用了一次hashCode方法, toString方法和hashCode方法都进行了拦截
System.out.println(test.toString());
System.out.println("-------------------------------");
System.out.println(test.equals(test));
} public static class Test { private String str; public void test() {
System.out.println("test : " + str);
} public Test() { } public Test(String string) {
str = string;
} } }

输出为

代理前
test : Aa
代理后
-------------------------------
代理前
test : null
代理后
-------------------------------
代理前
代理前
代理后
代理后
test.TestCglibProxy$Test$$EnhancerByCGLIB$$d7a97ec4@7506e922
-------------------------------
代理前
代理后
true

Java动态代理 ----- jdk代理与cglib代理的更多相关文章

  1. spring的AOP动态代理--JDK代理和CGLIB代理区分以及注意事项

    大家都知道AOP使用了代理模式,本文主要介绍两个代理模式怎么设置以及区别,对原文一些内容进行了引用后加入了自己的理解和更深入的阐述:   一.JDK代理和CGLIB代理的底层实现区别* JDK代理只能 ...

  2. 总结两种动态代理jdk代理和cglib代理

    动态代理 上篇文章讲了什么是代理模式,为什么用代理模式,从静态代理过渡到动态代理. 这里再简单总结一下 什么是代理模式,给某个对象提供一个代理对象,并由代理对象控制对于原对象的访问,即客户不直接操控原 ...

  3. Java中jdk代理和cglib代理

    代理模式 给某一个对象提供一个代理,并由代理对象控制对原对象的引用.在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 在Java中代理模式从实 ...

  4. 动态代理(二)—— CGLIB代理原理

    前篇文章动态代理(一)--JDK中的动态代理中详细介绍了JDK动态代理的Demo实现,api介绍,原理详解.这篇文章继续讨论Java中的动态代理,并提及了Java中动态代理的几种实现方式.这里继续介绍 ...

  5. jdk代理和cglib代理源代码之我见

    以前值是读过一遍jdk和cglib的代理,时间长了,都忘记入口在哪里了,值是记得其中的一些重点了,今天写一篇博客,当作是笔记.和以前一样,关键代码,我会用红色标记出来. 首先,先列出我的jdk代理对象 ...

  6. jdk代理和cglib代理

    1.jdk静态代理(静态代理和动态代理) 本质:在内存中构建出接口的实现类. 缺陷:只能对实现接口的类实现动态代理, 使用cglib可以对没有实现接口的类进行动态代理. 2.cglib动态代理     ...

  7. java 动态生成类再编译最后代理

    package spring.vhostall.com.proxy; public interface Store { public void sell(); } ------------------ ...

  8. Java代理模式精讲之静态代理,动态代理,CGLib代理

    代理(Proxy)是一种设计模式,通俗的讲就是通过别人达到自己不可告人的目的(玩笑). 如图: 代理模式的关键点是:代理对象与目标对象.代理对象是对目标对象的扩展,并会调用目标对象 这三个代理模式,就 ...

  9. Spring框架_代理模式(静态代理,动态代理,cglib代理)

    共性问题: 1. 服务器启动报错,什么原因? * jar包缺少.jar包冲突 1) 先检查项目中是否缺少jar包引用 2) 服务器: 检查jar包有没有发布到服务器下:                 ...

随机推荐

  1. Java练习 SDUT-3106_小鑫数数儿

    小鑫数数儿 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 某天小鑫忽然得到了许多的数字,他很好学,老师给他布置了一个任 ...

  2. Python基础:13装饰器

    装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的应用有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同 ...

  3. Firefox浏览器怎么安装adobe flash player插件

    https://jingyan.baidu.com/article/0a52e3f435d171bf62ed7237.html 有些朋友在使用Firefox火狐浏览器,但是火狐浏览器安装以后是没有fl ...

  4. P2P需集齐四大证照

    今后做P2P需集齐四大证照 比牌照制还严 2016-09-05 11:53:24 分类:热点观察 作者:汪祖刚 8月24日,P2P网贷监管细则在千呼万唤中始出来,整个行业内外的关注热度可谓史无前例.有 ...

  5. 8.5打包libgdx为一个桌面程序(jar包)

    简陋的地图编辑终于做好了,于是要开始制作地图了,想导出为一个windows下可用的程序,让熟人代做地图,然后找人问了下打包流程,其实跟普通java打包为jar没什么区别,记录如下: 导出类型选第三个 ...

  6. Pytorch源码与运行原理浅析--网络篇(一)

    前言 申请的专栏开通了,刚好最近闲下来了,就打算开这个坑了hhhhh 第一篇就先讲一讲pytorch的运行机制好了... 记得当时刚刚接触的时候一直搞不明白,为什么自己只是定义了几个网络,就可以完整的 ...

  7. Android Studio(四):Android Studio集成Genymotion

    Android Studio相关博客: Android Studio(一):介绍.安装.配置 Android Studio(二):快捷键设置.插件安装 Android Studio(三):设置Andr ...

  8. TortoiseSVN各种状态

    黄色感叹号(有冲突): --这是有冲突了,冲突就是说你对某个文件进行了修改,别人也对这个文件进行了修改,别人抢在你提交之前先提交了,这时你再提交就会被提示发生冲突,而不允许你提交,防止你的提交覆盖了别 ...

  9. Codeforces Round #190 (Div. 1 + Div. 2)

    A. Ciel and Dancing 模拟. B. Ciel and Flowers 混合类型的数量只能为0.1.2,否则3个可以分成各种类型各自合成. C. Ciel and Robot 考虑一组 ...

  10. java分配内存空间

    分配内存空间 数组名=new 数据类型[数组长度]: new关键字用来实现为数组或对象分配内存 (堆内存) 数组具有固定的长度.获取数组的长度: 数组名.length 定义数组+分配内存空间 数据类型 ...