Java 反射之JDK动态代理
Proxy提供用于创建动态代理类和代理对象的静态方法,它也是所有动态代理类的父类。如果我们在程序中为一个或多个接口动态地生成实现类,就可以使用Proxy来创建动态代理类;如果需要为一个或多个接口动态的创建实例,也可以使用Proxy来创建动态代理实例。
Proxy提供了如下两个方法来创建动态代理类和动态代理类:
(1)、static Class<?> getProxyClass(ClassLoader loader,Class<?> ...interfaces) : 创建一个动态代理类所对应的Class对象,该代理类将实现interfaces所指定的多个接口。第一个ClassLoader指定生成动态代理类的类加载器。
(2)、static Object newProxyInstance(ClassLoader loader,Class<?> interfaces, InvocationHandler h) :直接创建一个动态代理对象,该代理对象的实现类实现了interfaces指定的系列接口,执行代理对象的每个方法时都会被替换成执行 InvocationHandler对象的invoke方法。
实际上,即使采用第一种方式获取了一个动态代理类之后,当程序需要通过该代理类来创建对象时一样需要传入一个InvocationHandler对象。也就是说,系统生成的每个代理对象都有一个与之关联的InvocationHandler对象。
下面是AOP动态代理的实现:
在方法前后加入一写通用方法,比如项目中的日志记录。
Dog.java
package com.reflect.proxy; public interface Dog {
public void info();
public void run();
}
GunDog.java
package com.reflect.proxy; public class GunDog implements Dog { @Override
public void info() {
System.out.println("我是一只猎狗");
} @Override
public void run() {
System.out.println("我奔跑迅速");
} }
DogUtil.java
package com.reflect.proxy; public class DogUtil { public void method1(){
System.out.println("=====模拟第1个通用方法======");
} public void method2(){
System.out.println("=====模拟第2个通用方法======");
} }
借助于Proxy和InvocationHandler就可以实现:当程序调用info()方法和run()方法时,系统就可以“自动” 将method1()和method2() 两个通用方法插入info()和run()犯法
package com.reflect.proxy; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; public class MyInvocationHandler implements InvocationHandler { //需要被代理的对象
private Object target; public void setTarget(Object target){
this.target=target;
} //指定动态代理的所有方法时,都会替换成执行如下的invoke方法
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
DogUtil du=new DogUtil(); //执行DogUtil中的method1
du.method1();
//以target为主掉来执行method方法
Object result=method.invoke(target, args);
System.out.println(result);
//执行DogUtil中的Method2
du.method2();
return result;
} }
为指定的target生成代理类.
package com.reflect.proxy; import java.lang.reflect.Proxy; public class MyProxyFactory { //为指定target生成动态代理对象
public static Object getProxy(Object target){
MyInvocationHandler handler=new MyInvocationHandler();
//为MyInvotationHandler设置target对象
handler.setTarget(target);
//创建并返回一个动态代理
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler);
}
}
测试类
package com.reflect.proxy; public class Test { public static void main(String[] args) { //创建一个原始的GunDog对象,作为target
Dog target=new GunDog();
//以指定的target创建动态代理
Dog dog=(Dog) MyProxyFactory.getProxy(target);
dog.info();
dog.run();
}
}
输出:
=====模拟第1个通用方法======
我是一只猎狗
=====模拟第2个通用方法====== =====模拟第1个通用方法======
我奔跑迅速
=====模拟第2个通用方法======
Java 反射之JDK动态代理的更多相关文章
- 利用反射生成JDK动态代理
利用反射生成JDK动态代理 在Java的java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口可以生成JDK动态代理类和动态代理 ...
- Java反射机制以及动态代理
Java反射机制以及动态代理 Java反射机制 含义与功能 Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类 ...
- Java基础之反射生成JDK动态代理
在Java的java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口.通过这个类和接口可以生成JDK动态代理类或动态代理对象. JDK动态代理例子: / ...
- Java学习笔记--JDK动态代理
1.JDK动态代理 JDK1.3之后,Java提供了动态代理的技术,允许开发者在运行期创建接口的代理实例.JDK的动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和 ...
- MyBatis之反射技术+JDK动态代理+cglib代理
一.反射 引用百度百科说明: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功 ...
- Java中的JDK动态代理
所谓代理,其实就是相当于一个中间人,当客户端需要服务端的服务时,不是客户直接去找服务,而是客户先去找代理,告诉代理需要什么服务,然后代理再去服务端找服务,最后将结果返回给客户. 在日常生活中,就拿买火 ...
- java反射机制与动态代理
在学习HadoopRPC时.用到了函数调用.函数调用都是採用的java的反射机制和动态代理来实现的,所以如今回想下java的反射和动态代理的相关知识. 一.反射 JAVA反射机制定义: JAVA反射机 ...
- JavaSE---使用反射生成JDK动态代理
1.概述 1.1 在Java.lang.reflect包下,提供了Proxy类.InvocationHandler接口,使用它们可以生成JDK动态代理类或动态代理对象: 1.2 [Proxy类] 1. ...
- Java设计模式之JDK动态代理原理
动态代理核心源码实现public Object getProxy() { //jdk 动态代理的使用方式 return Proxy.newProxyInstance( this.getClass(). ...
随机推荐
- 开源一个自己造的轮子:基于图的任务流引擎GraphScheduleEngine
GraphScheduleEngine是什么: GraphScheduleEngine是一个基于DAG图的任务流引擎,不同语言编写.运行于不同机器上的模块.程序,均可以通过订阅GraphSchedul ...
- Android等宽字体
Android等宽字体 效果图 在xml中设置 添加属性 android:typeface="monospace" 例如 <TextView android:layout_w ...
- Swift中如何化简标准库中冗长的类实例初始化代码
可能有些童鞋并不知道,在Swift中缩写点符号对于任何类型的任何static成员都有效. 我们实际写一个例子看一下: import UIKit class CFoo{ static let share ...
- Swift类型推测在可选调用中的小提示
我们知道Swift中协议里也有对应于Objc中的可选方法或计算属性,当然协议必须以@objc伪指令修饰否则不可以哦. 如下示例: @objc protocol Transaction{ fun com ...
- Tomcat如何实现WebSocket
WebSocket协议属于HTML5标准,越来越多浏览器已经原生支持WebSocket,它能让客户端和服务端实现双向通信.在客户端和服务器端建立一条WebSocket连接后,服务器端消息可直接发送到客 ...
- 微信小程序基本组件概述
为了更好的理解微信小程序,本文90%文字描述来源于官网的介绍.官网原链接https://mp.weixin.qq.com/debug/wxadoc/dev/component/?t=20161222 ...
- [sed]命令笔记
sed是linux下经常用到的工具,英文全名为stream editor. sed 在windows上的实现可以在这里找到 http://gnuwin32.sourceforge.net/packag ...
- 使用C++将OpenCV中Mat的数据写入二进制文件,用Matlab读出
在使用OpenCV开发程序时,如果想查看矩阵数据,比较费劲,而matlab查看数据很方便,有一种方法,是matlab和c++混合编程,可以用matlab访问c++的内存,可惜我不会这种方式,所以我就把 ...
- [nginx] 对UA为空的请求返回403
nginx blocking blank user agent . sometime apps' backgroud request always visit a url, and these req ...
- java.io.FileNotFoundException: ..\lib\commons-el.jar
安装openfire成功后,启动遇到java.io.FileNotFoundException: ..\lib\commons-el.jar错误,并不是缺少了jar包,只需以管理员身份运行即可解决.