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. python 字典创建

  2. Python基础:08列表解析与生成器表达式

    一:列表解析 列表解析(List comprehensions)来自函数式编程语言Haskell .它可以用来动态地创建列表.它在 Python 2.0 中被加入. 列表解析的语法:     [exp ...

  3. GitOps:Kubernetes多集群环境下的高效CICD实践

    为了解决传统应用升级缓慢.架构臃肿.不能快速迭代.故障不能快速定位.问题无法快速解决等问题,云原生这一概念横空出世.云原生可以改进应用开发的效率,改变企业的组织结构,甚至会在文化层面上直接影响一个公司 ...

  4. day3_python之函数参数

    一.形参 在定义函数时,括号内的参数称为形参,特点:形参就是变量名 def foo(x, y): # x=1,y=2 print(x) print(y) 二.实参 在调用函数时,括号内的参数成为实参, ...

  5. ODT 珂朵莉树 入门

    #include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> ...

  6. iptables 操作规则

    iptables -nL查看本机关于iptables的设置情况,默认查看的是-t filter,可以指定-t nat iptables-save > iptables.rule会保存当前的防火墙 ...

  7. activiti工作流引擎之uel表达式

    qq讨论群:313032825本人做了一个微信公众号,用于分享各类视频学习资源和我多年学习经验,喜欢的可以关注哦! 有了前面几章,我们肯定有一定的困惑,activiti如何与实际业务整合,比如一条采购 ...

  8. mac上的mysql管理工具sequel pro

    https://blog.csdn.net/wan_zaiyunduan/article/details/54909389 以前用过Plsql.Navicat.Workbench,现在换到mac上,用 ...

  9. jq杂项方法/工具方法----each() grep() map()

    each() 用于循环数组 对象(单纯遍历) 返回 false 可提前停止循环.接受的参数是数组名和要执行的函数,函数参数为数组索引和当前元素. var arr = [30, 40, 50,1 ,8] ...

  10. hdu 1254 推箱子(嵌套搜索,bfs中有dfs)

    推箱子 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...