java JDK动态代理的机制
一:前言
自己在稳固spring的一些特性的时候在网上看到了遮掩的一句话“利用接口的方式,spring aop将默认通过JDK的动态代理来实现代理类,不适用接口时spring aop将使用通过cglib 来实现代理类",我对JDK的动态代理机制其实一点都不了解,学习java的时候也是只是知道会用,会去查api的文档就行,所以这些底层的操作方式我自己不是很清楚,现在既然要了解一些底层的代码,就谢谢自己的想发,大部分都是差不多的。
二:实现
先给出接口和实现类的代码:
UserDao.java:
package dynamicProxy;
public interface UserDao {
String saveUser(String name);
void deleteUser(String name);
}
UserDaoImpl.java:
package dynamicProxy;
public class UserDaoImpl implements UserDao{
@Override
public String saveUser(String name) {
System.out.println("姓名:"+name);
return name;
}
@Override
public void deleteUser(String name) {
System.out.println("要删除的姓名:"+name);
}
}
既然都说了是JDK的动态代理,那么现在我们需要些一个累来实现"java.lang.reflect.InvocationHandler"的接口,里面有invoke(*,*,*)方法,该方法有三个参数,参数意思下面会说给出代码如下:
package dynamicProxy; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; public class MouseHandler implements InvocationHandler { private Object target; public MouseHandler(Object target) {
this.target = target;
} public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("代理的类为:"+proxy.getClass());
System.out.println("目标类:"+target.getClass()+"target对象--->"+target);
System.out.println("方法:"+method);
System.out.println("参数:"+args);
System.out.println("开始输出日志");
Object obj=method.invoke(target, args);
System.out.println("obj的值:"+obj);
return obj;
} }
当你自己把这些参数全部打印出来了,就会知道参数的意思。下面我写下来了
Object proxy:要代理的类(打印结果为------>代理的类为:class $Proxy0)
Method method:这里的method是指要调用得方法(打印结果-------->方法:public abstract java.lang.String dynamicProxy.UserDao.saveUser(java.lang.String))
Object[] args:这里是参数数组,就是该方法的参数
还有就是这个方法(public Object invoke(Object proxy, Method method, Object[] args))最后我们返回的值:返回的值就是我们调用该方法,该方法返回的值 (输出结果为---->obj的值:老鼠)
再来说说这和Object proxy,如果你在method.invoke(proxy,args)这里的第一个参数依然使用proxy(自动生成的代理类)的话,在运行程序你会发现程勋会一会运行(报错),一直循环,错误代码如下:


这里需要指定要代理的对象。
下面在看看Test.java类
package dynamicProxy;
import java.lang.reflect.Proxy;
public class Test {
public static void main(String args[]){
UserDao userDao=new UserDaoImpl();
System.out.println("-->"+userDao.getClass().getClassLoader());//(打印结果:-->sun.misc.Launcher$AppClassLoader@addbf1)
System.out.println("-->"+userDao.getClass().getInterfaces());//(打印结果:-->[Ljava.lang.Class;@61de33)
UserDao userDaoProxy=(UserDao)Proxy
.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces()
, new MouseHandler(userDao));
userDaoProxy.saveUser("老鼠");
}
}
看看Proxy(*,*,*)方法中的三个参数
userDao.getClass().getClassLoader():这是类加载器
userDao.getClass().getInterfaces():代理的接口
new MouseHandler(userDao):实例化传入需要代理的对象(对UserDaoImpl的引用)
如果你再加断点调试的话就会发现,其实MouseHandler中的invoke方法只有在调用方法userDaoProxy.saveUser("老鼠");的时候才会执行,也就是说调用得是saveUser("老鼠"),实际上时在调用invoke方法。上面的知识其实有的也是看看网上的资料,在结合下来写的,但是真正需要自己断点来运行下
其实现在我在理解底层代码,很多都是需要自己来敲一遍,自己断点运行,自己来调试,只有这样自己的理解才会会更加的彻底。这几天算是把spring ioc和aop给理解了一遍,IOC还好,但是aop自己觉得理解起来好是郁闷啊。不过我还是回尽量的去理解,这对自己还是有好处的。明天就是我自己的生日了,这是我出社会(还未毕业的出社会)第一次过生日,写篇博客提前祝自己生日快乐吧。实习已经快3个月了,不敢说自己现在又多么多么的牛逼,但是真的觉得自己进步了,自己有了方向感,自己知道需要去学习些什么东西。这一点很是重要。以前虽然也知道要学java,但是只是懂了皮毛,真正的东西还是不理解。这就是基础。最近在补习很多东西,java、linux、计算机网络等。还有好远的路要走啊。明天在写篇自己这块三个月的感感想吧。记录下自己的感受。努力加油,一天一天的进步。努力!!!
java JDK动态代理的机制的更多相关文章
- JDK动态代理实现机制
=========================================== 原文链接: JDK动态代理实现机制 转载请注明出处! =========================== ...
- java中动态代理实现机制
前言: 代理模式是常用的java设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系 ...
- Java JDK 动态代理使用及实现原理分析
转载:http://blog.csdn.net/jiankunking 一.什么是代理? 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为委托类预处理 ...
- java jdk动态代理模式举例浅析
代理模式概述 代理模式是为了提供额外或不同的操作,而插入的用来替代”实际”对象的对象,这些操作涉及到与”实际”对象的通信,因此代理通常充当中间人角色. java中常用的动态代理模式为jdk动态代理和c ...
- Java JDK 动态代理实现和代码分析
JDK 动态代理 内容 一.动态代理解析 1. 代理模式 2. 为什么要使用动态代理 3. JDK 动态代理简单结构图 4. JDK 动态代理实现步骤 5. JDK 动态代理 API 5.1 java ...
- Java JDK动态代理解析
动态代理虽不常自己实现,但在Spring或MyBatis中都有重要应用.动态代理的意义在于生成一个占位(又称代理对象),来代理真实对象,从而控制真实对象的访问.Spring常JDK和CGLIB动态代理 ...
- java jdk动态代理学习记录
转载自: https://www.jianshu.com/p/3616c70cb37b JDK自带的动态代理主要是指,实现了InvocationHandler接口的类,会继承一个invoke方法,通过 ...
- Java,JDK动态代理的原理分析
1. 代理基本概念: 以下是代理概念的百度解释:代理(百度百科) 总之一句话:三个元素,数据--->代理对象--->真实对象:复杂一点的可以理解为五个元素:输入数据--->代理对象- ...
- java jdk动态代理
在面试的时候面试题里有一道jdk的动态代理是原理,并给一个事例直接写代码出来,现在再整理一下 jdk动态代理主要是想动态在代码中增加一些功能,不影响现有代码,实现动态代理需要做如下几个操作 1.首先必 ...
随机推荐
- 一种简单实用的双向电平转换电路3.3V-5V
当你使用3.3V的单片机的时候,电平转换就在所难免了,经常会遇到3.3转5V或者5V转3.3V的情况,这里介绍一个简单的电路,他可以实现两个电平的相互转换(注意是相互哦,双向的,不是单向的!).电路十 ...
- stm32--FatFs调试过程(SPIFlash)
移植方法参见我的另一篇博客:<stm32--FatFs移植(SPIFlash)>. 本文仅记录在初次移植完成后,遇到的问题,和解决的过程. 调试记录: 问题1:f_open返回3,即磁盘没 ...
- jmeter如何连接数据库
大家都知道jmeter是java编写的,java/jmeter如果想连接数据库就要通过java database connector(JDBC)去连接,首先需先下载一个驱动 (mysql-connec ...
- VSCode 前端必备插件
VSCode 前端必备插件 Debugger for Chrome 让 vscode 映射 chrome 的 debug功能,静态页面都可以用 vscode 来打断点调试 { "versio ...
- 使用Scrapy自带的ImagesPipeline下载图片,并对其进行分类。
ImagesPipeline是scrapy自带的类,用来处理图片(爬取时将图片下载到本地)用的. 优势: 将下载图片转换成通用的JPG和RGB格式 避免重复下载 缩略图生成 图片大小过滤 异步下载 . ...
- 以太坊 生成助记词和infuru插件
https://iancoleman.io/bip39/ https://infura.io google faucet : https://faucet.rinkeby.io/ 登录google账号 ...
- ubuntu 和 centOS 的apache设置
更改ubuntu的网站访问根目录: 在sudo gedit /etc/apache2/sites-enabled/000-default,把 DocumentRoot /var/www #这 ...
- 基本数据类型的成员变量放在jvm的哪块内存区域里?
几个月前自己提问的一个问题没人回答,现在突然翻到,自己回答下: 问题: 比如class{private int i;}如上代码,之前一直以为基本数据类型都是放在虚拟机栈中的,最近看了<深入理解j ...
- winform 控件半透明设置
1.backcolor属性为color.FromArgb(100, 220, 220, 220); 2.全透明设置为transparent方法.
- Top K 算法详解
http://xingyunbaijunwei.blog.163.com/blog/static/7653806720111149318357/ 问题描述 百度面试题: ...