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 ...
- myeclipse中使用gradle开发项目
gradle可以直接使用maven的代码库,并且支持编程,可以说是maven的加强版.今天我们学习下,如何在MyEclipse下使用gradle开发项目.我们的开发环境:myeclipse 2015, ...
- 微信.NET 微信开发 自己主动内容回复 ASP.NET C#代码
微信开发中,首先遇到的问题就是处理怎样接收和响应用户消息 , 本文将向大家介绍一下方法和关键的代码. 本文使用的接口库是 :https://github.com/chendong152/Weixin ...
- mac上SVN项目管理,提示被锁定的解决方法
问题 mac上SVN项目管理,提示被锁定.不能commit.也不能update.提示 clean the working copy and then. .. 解决方法 watermark/2/text ...
- Ubuntu jdk报Picked up JAVA_TOOL_OPTIONS信息解决
下面是摘自http://www.cnblogs.com/coderbean/p/4522182.html 以下是我在网上找了好久找到的: Ubuntu jdk报Picked up JAVA_TOOL_ ...
- iostat详解
http://www.penglixun.com/tech/system/use_iostat_analyse_linux_disks.html
- Linux运维工程师成长必经之路
本路线图是从0基础开始,全方位由浅入深,按照多年Linux培训经验和优秀教学方法制定的学习思路和学习方法,路线图包括初级入门.中级进阶.高级提升和资深冲刺四个阶段,每阶段对应着不同优秀的课程和学习方法 ...
- secureCRT常用设置
一.快捷键: 1. ctrl + a : 移动光标到行首[常用] 2. ctrl + e :移动光标到行尾[常用] 3. ctrl + d :删除光标之后的一个字符 4. ctrl + w : 删除行 ...
- [转]使用Beaglebone Black的SPI
分类: Beaglebone Black2013-11-24 18:21 678人阅读 评论(6) 收藏 举报 beaglebone blackbeagleboneSPIdevice tree 目 ...
- Cisco交换机设置管理IP
需要准备一根CONSOLE线和带串行接口的电脑. (图1) 用CONSOLE线连接好电脑与交换机(交换机的CONSOLE口一般都有表示). 然后按照图1点“开始→程序→超级终端”会弹出来一个窗口(图2 ...