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包有没有发布到服务器下: ...
随机推荐
- python环境测试MySQLdb、DBUtil、sqlobject性能
python环境测试MySQLdb.DBUtil.sqlobject性能 首先介绍下MySQLdb.DBUtil.sqlobject: (1)MySQLdb 是用于Python连接Mysql数据库的接 ...
- C++:只用初始化列表初始化变量的几种情况
1.类成员函数中const变量的初始化(也就是第一点) 有几个容易混淆的地方: (1)const 的变量只能通过构造函数的初始化列表进行初始化:(貌似在C++11中可以正常编译) (2)static ...
- oracle函数 nls_charset_name(n1)
[功能]返回字符集名称参应id值 [参数]n1,数值型 [返回]字符型 sql> select nls_charset_name(852) from dual; nls_char ------- ...
- oracle函数 BFILENAME(dir,file)
[功能]函数返回一个空的BFILE位置值指示符,函数用于初始化BFILE变量或者是BFILE列. [参数]dir是一个directory类型的对象,file为一文件名. insert into lob ...
- Knative Tracing 介绍
摘要: 一个完整的业务实现想要基于 Serverless 模型来开发的话可能会分解成多个 Serverless 模块,每一个模块单独通过 Knative 的 Serving 部署,那么这些不同的 Se ...
- linux自动挂载NTFS格式移动硬盘
转自:http://blog.163.com/cmh_lj/blog/static/100812304201252522119264/ 由于移动硬盘还有不少的资料,刚插入移动硬盘的时候发现只能自动挂载 ...
- PHP导入导出Excel方法小结
基本上导出的文件分为两种: 1:类Excel格式,这个其实不是传统意义上的Excel文件,只是因为Excel的兼容能力强,能够正确打开而已.修改这种文件后再保存,通常会提示你是否要转换成Excel文件 ...
- H3C ISDN网络构成
- 原生js实现选字游戏
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Python--day71--内容回顾