Java动态代理 ----- jdk代理与cglib代理
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代理的更多相关文章
- spring的AOP动态代理--JDK代理和CGLIB代理区分以及注意事项
大家都知道AOP使用了代理模式,本文主要介绍两个代理模式怎么设置以及区别,对原文一些内容进行了引用后加入了自己的理解和更深入的阐述: 一.JDK代理和CGLIB代理的底层实现区别* JDK代理只能 ...
- 总结两种动态代理jdk代理和cglib代理
动态代理 上篇文章讲了什么是代理模式,为什么用代理模式,从静态代理过渡到动态代理. 这里再简单总结一下 什么是代理模式,给某个对象提供一个代理对象,并由代理对象控制对于原对象的访问,即客户不直接操控原 ...
- Java中jdk代理和cglib代理
代理模式 给某一个对象提供一个代理,并由代理对象控制对原对象的引用.在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 在Java中代理模式从实 ...
- 动态代理(二)—— CGLIB代理原理
前篇文章动态代理(一)--JDK中的动态代理中详细介绍了JDK动态代理的Demo实现,api介绍,原理详解.这篇文章继续讨论Java中的动态代理,并提及了Java中动态代理的几种实现方式.这里继续介绍 ...
- jdk代理和cglib代理源代码之我见
以前值是读过一遍jdk和cglib的代理,时间长了,都忘记入口在哪里了,值是记得其中的一些重点了,今天写一篇博客,当作是笔记.和以前一样,关键代码,我会用红色标记出来. 首先,先列出我的jdk代理对象 ...
- jdk代理和cglib代理
1.jdk静态代理(静态代理和动态代理) 本质:在内存中构建出接口的实现类. 缺陷:只能对实现接口的类实现动态代理, 使用cglib可以对没有实现接口的类进行动态代理. 2.cglib动态代理 ...
- java 动态生成类再编译最后代理
package spring.vhostall.com.proxy; public interface Store { public void sell(); } ------------------ ...
- Java代理模式精讲之静态代理,动态代理,CGLib代理
代理(Proxy)是一种设计模式,通俗的讲就是通过别人达到自己不可告人的目的(玩笑). 如图: 代理模式的关键点是:代理对象与目标对象.代理对象是对目标对象的扩展,并会调用目标对象 这三个代理模式,就 ...
- Spring框架_代理模式(静态代理,动态代理,cglib代理)
共性问题: 1. 服务器启动报错,什么原因? * jar包缺少.jar包冲突 1) 先检查项目中是否缺少jar包引用 2) 服务器: 检查jar包有没有发布到服务器下: ...
随机推荐
- Spring Security入门篇——标签sec:authorize的使用
Security框架可以精确控制页面的一个按钮.链接,它在页面上权限的控制实际上是通过它提供的标签来做到的 Security共有三类标签authorize authentication accessc ...
- 配置 IO 时要记得换 Page
配置 IO 时要记得换 Page 在配置某些芯片时,配置 IO 时要记得换页,不然不生效. 注意查看 IO 的相关规格书说明,而且每个厂商是不一样的.
- 阿里云MaxCompute 2019-4月刊
摘要: 4月新功能发布,精彩技术好文推荐,5月线上线下活动抢先知道,尽在4月刊. 您好,MaxCompute 2019.4月刊为您带来产品最新动态和丰富的产品技术内容,欢迎阅读. 导读 [功能发布]4 ...
- 自定义View系列教程02--onMeasure源码详尽分析
深入探讨Android异步精髓Handler 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)- 核心基础 Android多分辨率适配框架(2)- 原理剖析 Andr ...
- 10-1 body标签里面相关的标签(列表,表单,表格)
一 列表标签<ul>,<ol>,<dl> <!DOCTYPE html> <html lang="en"> <he ...
- 终端安装opencv
安装 要想在 notebook 中安装和使用 OpenCV,请打开终端窗口(也被称为 Windows 用户的命令提示符窗口),并使用以下命令通过 conda 安装最新版本 (v3): conda in ...
- PageProxy分页的实现
PageProxy是Ext.Net实现的一种分页方式,PageProxy通过实现OnReadData事件来完成分页. <ext:Store runat=" OnReadData=&qu ...
- 防止SyntaxHighlighter.js的闪烁闪一下的方法
SyntaxHighlighter.js是一个代码高亮的JS插件,使用也很简单,但是由于是浏览器段执行JS代码来着色,会出现视觉上闪一下的效果.比如你的20行代码网页打开显示高度为100px,但是Sy ...
- HDU3336 Count the string 题解 KMP算法
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3336 题目大意:找出字符串s中和s的前缀相同的所有子串的个数. 题目分析:KMP模板题.这道题考虑 n ...
- Codeforces Round #172 (Div. 1 + Div. 2)
A. Word Capitalization 模拟. B. Nearest Fraction 枚举. C. Rectangle Puzzle 求出两个矩形的点,套简单多边形的面积交板子. D. Max ...