java中动态反射
java中动态反射能达到的效果和python的语法糖很像,能够截获方法的实现,在真实方法调用之前和之后进行修改,甚至能够用自己的实现进行特别的替代,也可以用其实现面向切片的部分功能。动态代理可以方便实现AOP,AOP将应用系统分为两部分,核心业务逻辑(Core business concerns)及横向的通用逻辑,也就是所谓的方面Crosscutting enterprise concerns,例如,所有大中型应用都要涉及到的持久化管理(Persistent)、事务管理(Transaction Management)、安全管理(Security)、日志管理(Logging)和调试管理(Debugging)等。
JDK默认的动态代理机制基于interface,而使用CGLib可以实现对类的动态代理功能。JDK动态代理机制涉及到几个地方:
(1) Proxy类
Proxy类提供了用于创建动态代理类和实例对象的方法,它是所创建的动态代理类的父类,它最常用的方法如下:
- public static Class<?> getProxyClass(ClassLoader loader,Class<?>... interfaces):该方法用于返回一个Class类型的代理类,在参数中需要提供类加载器并需要指定代理的接口数组(与真实主题类的接口列表一致)。
- public static Object newProxyInstance(ClassLoader loader, Class<?>[]interfaces, InvocationHandler h):该方法用于返回一个动态创建的代理类的实例,方法中第一个参数loader表示代理类的类加载器,第二个参数interfaces表示代理类所实现的接口列表(与真实主题类的接口列表一致),第三个参数h表示所指派的调用处理程序类。
(2) InvocationHandler接口
InvocationHandler接口是代理处理程序类的实现接口,该接口作为代理实例的调用处理者的公共父类,每一个代理类的实例都可以提供一个相关的具体调用处理者(InvocationHandler接口的子类)。在该接口中声明了如下方法:
- public Object invoke(Objectproxy, Method method, Object[] args):该方法用于处理对代理类实例的方法调用并返回相应的结果,当一个代理实例中的业务方法被调用时将自动调用该方法。invoke()方法包含三个参数,其中第一个参数proxy表示代理类的实例,第二个参数method表示需要代理的方法,第三个参数args表示代理方法的参数数组。
动态代理类需要在运行时指定所代理真实主题类的接口,客户端在调用动态代理对象的方法时,调用请求会将请求自动转发给InvocationHandler对象的invoke()方法,由invoke()方法来实现对请求的统一处理。
下面的这个例子,在每个方法前后分别打印日志,说明该方法开始执行,在改方法结束的时候打印日志方法结束。如果不采用动态代理机制,则需要在每个方法的开始和结束的位置都加上类似的日志,有了代理机制以后只用一句话。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; interface TestInterface {
void print(String p); void filter(); void say(String string);
} class TestImpl implements TestInterface { public void say(String to) {
System.out.println("Say hello to " + to);
} public void print(String s) {
System.out.println("print : " + s);
} public void filter() {
System.out.println("filter");
}
} class LogHandler implements InvocationHandler {
private Object dele; public LogHandler(Object obj) {
this.dele = obj;
} public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String funcname = method.getName();
// 这里过滤掉filter方法,什么都不做
if (method.getName().equals("filter")) {
System.out.println(method.getName() + " filter,not execute");
return null;
}
beforeFunction(funcname);
Object result = method.invoke(dele, args);
endFunction(funcname);
return result;
} private void beforeFunction(String funcname) {
System.out.println("method:" + funcname + " begins.");
} private void endFunction(String funcname) {
System.out.println("method:" + funcname + " ends.");
}
} public class ProxyTest { public static void main(String[] args) {
TestImpl impl = new TestImpl();
LogHandler handler = new LogHandler(impl);
// 这里把handler与impl新生成的代理类相关联
TestInterface testinter = (TestInterface) Proxy.newProxyInstance(impl.getClass().getClassLoader(),
impl.getClass().getInterfaces(), handler);
// 这里无论访问哪个方法,都是会把请求转发到handler.invoke
testinter.print("All the test");
testinter.say("Cob");
// 这里过滤掉filter方法,什么都不返还
testinter.filter();
} }
java中动态反射的更多相关文章
- 【Java基础】java中的反射机制与动态代理
一.java中的反射机制 java反射的官方定义:在运行状态下,可以获取任意一个类的所有属性和方法,并且可通过某类任意一对象实例调用该类的所有方法.这种动态获取类的信息及动态调用类中方法的功能称为ja ...
- Java中的反射和注解
前言 在Java中,反射机制和注解机制一直是一个很重要的概念,那么他们其中的原理是怎么样呢,我们不仅仅需要会使用,更要知其然而之所以然. 目录 反射机制 反射如何使用 注解定义 注解机制原理 注解如何 ...
- java中的反射机制在Android开发中的用处
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反 ...
- 浅说Java中的反射机制(二)
写过一篇Java中的反射机制,不算是写,应该是抄了,因为那是别人写的,这一篇也是别人写的,摘抄如下: 引自于Java基础--反射机制的知识点梳理,作者醉眼识朦胧.(()为我手记) 什么是反射? 正常编 ...
- 浅说Java中的反射机制(一)
在学习传智播客李勇老师的JDBC系列时,会出现反射的概念,由于又是第一次见,不免感到陌生.所以再次在博客园找到一篇文章,先记录如下: 引用自java中的反射机制,作者bingoideas.(()为我手 ...
- 第89节:Java中的反射技术
第89节:Java中的反射技术 反射技术是动态的获取指定的类,和动态的调用类中的内容(没有类前就可以创建对象,将对象的动作完成,这就是动态的获取指定的类). 配置文件把具体实现的类名称定义到配置文件中 ...
- java笔记十:java中的反射
Java中,反射是一种强大的工具.它使您能够创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代表链接.反射允许我们在编写与执行时,使我们的程序代码能够接入装载到JVM中的类的内部信息,而 ...
- java 中利用反射机制获取和设置实体类的属性值
摘要: 在java编程中,我们经常不知道传入自己方法中的实体类中到底有哪些方法,或者,我们需要根据用户传入的不同的属性来给对象设置不同的属性值,那么,java自带的反射机制可以很方便的达到这种目的,同 ...
- java中的反射(三)
目录 一.反射 1.class类 2.访问字段 3.调用方法 4.调用构造方法 5.获取继承对象 6.动态代理 二.sping中的反射 本篇转自:https://depp.wang/2020/05/0 ...
随机推荐
- Add-VMNetworkAdapterAcl(添加访问控制列表)
Add-VMNetworkAdapterAclCreates an ACL to apply to the traffic through a virtual machine network adap ...
- jQuery 编辑div内容
div显示如下 <div id="showResult"></div> div中添加的html,进行拼接 $("#showResult" ...
- C# DataTable的詳細使用方法
在项目中经经常使用到DataTable,假设DataTable使用得当,不仅能使程序简洁有用,并且可以提高性能,达到事半功倍的效果,现对DataTable的使用技巧进行一下总结. 一.DataTabl ...
- POJ 3670 , 3671 LIS
题意:两题意思差不多,都是给你一个序列,然后求最少需要改变多少个数字,使得成为一个最长不升,或者最长不降子序列. 当然3671是只能升序,所以更简单一点. 然后就没有什么了,用二分的方法求LIS即可. ...
- URAL - 1736 - Chinese Hockey
题意:n支队伍打比赛,每2队只进行1场比赛,规定时间内胜得3分,败得0分,若是打到了加时赛,那么胜得2分,败得1分,给出n支队伍最后的总得分,问这个结果是否是可能的,是的话输出“CORRECT”及各场 ...
- careercup-递归和动态规划 9.1
9.1 有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶.2阶或3阶.实现一个方法,计算小孩有多少种上楼梯的方法. 解法: 我们可以采用自上而下的方式来解决这个问题.小孩上楼梯的最后一步,也就是 ...
- UIStackView 看我就够了
介绍 UIStackView 是 iOS9新增的一个布局技术.熟练掌握相当节省布局时间. UIStackView 是 UIView 的子类,是用来约束子控件的一个控件.但他的作用仅限于此,他不能用来呈 ...
- 关于Fragment与Fragment、Activity通信的四种方式
一直想总结一下Fragment与Fragment.Activity通信的问题,今天有时间一共总结了三种,权当抛砖引玉,如果大家还有更好的方式来实现Fragment和Fragment.Activity的 ...
- C# 解决DrawImage绘制图片拉伸产生渐变
ImageAttributes ImgAtt = new ImageAttributes(); ; ImgAtt.SetWrapMode(System.Drawing. ...
- Android_Intent_note
Activity间传递参数的方法方法1. 通过putExtra()传递基本数据类型方法2. 通过putExtras()传递Bundle数据类型方法3. 通过Application读写全局变量 方法4. ...