------- android培训、java培训、期待与您交流! ----------
假设我们现在有一个接口Hello里面有一个sayHello()的方法
public interface Hello { public void sayHello(); }
和一个实现类HelloImpl
public class HelloImpl implements Hello { @Override public void sayHello() { System.out.println("Hello"); } }
我们现在有这么一个需求,需要在sayHello()方法执行前做些事,在sayHello()方法执行后做些事,根据开放封闭原则不能改变原有的类,这该怎么办?
这时就该轮到我们的动态代理出场了!
首先介绍和动态代理有关的两个类:
1.interface InvocationHandler
只有一个Object invoke(Object proxy, Method method, Object[] args) 方法
从参数列表可见这个类传入了需要代理的类的方法的方法对象method,通过这个对象可以调用需要代理的类的方法,args是这个方法的参数。也就是这个接口定义了一个统一的入口供Proxy代理类调用。通过我们对这个接口的不同实现来完成不同的附加功能,这就是多态的体现。
2.class Proxy
真正表示动态代理的类,提供两个静态方法:
Class<?> getProxyClass(ClassLoader loader, Class<?>[] interface)
用来产生代理类,参数要提供interface数组,它会生成这些interface的“虚拟实现”,用来冒充真实的对象。从返回Class类型可见这个代理类是根据所传参数动态产生的,所以叫做动态代理。
Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
产生代理对象,多了InvocationHandler参数(只是InvocationHandler接口的实现类),它与代理对象关联,当请求分发到代理对象后,会自动执行h.invoke(...)方法,invoke方法就是我们用来做N多事情的地方\(^o^)/~。根据所传的InvocationHandler接口的实现产生动态代理类的实例。
---------------------------------可恶的分割线O(∩_∩)O~------------------------------------------------
通过上面介绍,我们首先得生成一个InvocationHandler 接口的实现来完成我们的功能,并在bind()方法中返回根据这个实现了InvocationHandler 接口的对象所生成的动态代理类的实例。
public class myHandler implements InvocationHandler { private Object target; /** * 绑定委托对象并返回一个代理类 * * @param target * @return */ public Object bind(Object target) { this.target = target; // 取得代理对象 return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; before(); result = method.invoke(target, args); after(); return result; } private void before() { System.out.println("before...."); } private void after() { System.out.println("after...."); } }
最后对代码进行测试
public class ProxyTest { public static void main(String[] args) { //首先生成我们自己定义的处理器实例 //默认对接口中的所有方法都是统一的代理实现 MyHandler my = new MyHandler(); //通过接口接受返回的代理对象 //传入具体类的实现 Hello hello = (Hello)my.bind(new HelloImpl()); //调用这个代理类中的方法 //接口中的所有方法都动态的加上了一定的功能 hello.sayHello(); } }
执行结果
before.... Hello after....
问题?动态代理给接口中的所有方法都统一的加上了指定的功能,能不能进行细粒度的控制?比如有的方法加上指定的功能,有的方法不变?或者能不能每个方法加的功能都不一样?我想这也只有通过静态代理才能实现了。
相关推荐
这是根据黑马程序员中关于Vue11天课程中,跟着视频编写的代码,一行行跟着写出来的,连备注基本也是和视频一样,用的是vscode开发工具,上传的资料已经把node_modules删除了,进入目录后,用cnpm i重新安装一下就...
C++黑马程序员学习资料,附赠《InterviewGuide第四版By阿秀》、《LeetCode刷题手册》、《背包问题九讲》、《算法图解》pdf版本,三个基础课程文档手册及三个实验项目,由简到繁分别为《通讯录管理系统》、《职工管理...
"黑马程序员Javase笔记"是一个自学者在学习黑马程序员提供的Java全套课程过程中整理的笔记,主要涵盖了Java Standard Edition (Javase) 的核心内容。下面将详细讨论其中的关键知识点。 首先,DOS命令是操作系统中的...
黑马程序员 C语言提高课程配套课件 黑马程序员 C语言提高课程配套课件
黑马程序员是一家知名的IT教育机构,他们提供的Javaweb教材源码是为了帮助学员深入理解和实践Web开发技术。下面将详细介绍JavaWeb的基本概念、核心技术和黑马程序员源码在学习过程中的作用。 1. **JavaWeb基础** ...
黑马程序员——Android移动开发源码
”这句话暗示了这份资料是由个人或团队根据黑马程序员的教学内容整理而出的,可能包含了个人的理解和总结。它并非官方教材,但作为辅助学习的资源,可能提供了一种不同的解题思路或者更贴近实践的应用方式,对于自主...
黑马程序员,C++核心编程
传智播客旗下黑马程序员c++视频课程内部讲义 就是上课时老师翻阅的那个讲义
【Java Web 全面解析】 ...本笔记深入浅出地介绍了Java Web开发的核心技术,通过学习这些知识点,开发者可以构建功能丰富的动态网站,并为进一步学习Spring、Hibernate、MyBatis等高级框架打下坚实基础。
内容概要:通过带着读者手写简化版 Spring 框架了解 Spring 核心原理。在手写Spring源码的过程中会摘取整体框架中的核心逻辑,简化代码实现过程保留核心功能, ...本代码基于黑马程序员的课程,最好根据课程同步学习
layui ajax 没有node.js功能都可用,高度类似。 黑马刘龙彬老师主讲的大事件项目,整体看完,给...最后,再次给黑马程序员和刘老师点个赞。 说明--ShowDoc https://www.showdoc.com.cn/escook?page_id=3707158761215217
黑马程序员JavaEE49期
在B站黑马程序员的Python教程中,你将深入理解Python的基础概念,包括: 1. **变量与数据类型**:Python支持多种数据类型,如整型(int)、浮点型(float)、字符串(str)和布尔型(bool)。此外,还有列表(list...
黑马程序员入学考试题,共10道,资源中有代码和题目。
"黑马程序员毕业设计资料,代码,数据库设计论文等" 这个标题表明这是一份来自“黑马程序员”教育平台的资源集合,主要用于帮助学生进行毕业设计。其中包含了项目代码、数据库设计相关的论文等内容,适用于计算机科学...
Netty基础,用于学习Netty,参考黑马程序员的netty教程
这个视频教程由黑马程序员提供,由黎活明主讲,旨在帮助开发者深入理解和掌握Struts2.1的核心概念和实际应用。 首先,从标题和描述我们可以了解到,本教程是关于Struts2.1的,它涵盖了从基础到进阶的多个主题。...
《Java Web程序设计任务教程》是一本专注于Java Web开发实践的书籍,由中国工信出版社出版,由传智播客旗下的高端教育品牌“黑马程序员”精心编著。这本书旨在帮助读者掌握Java Web开发的核心技术和实践方法,通过一...