这几天,为了工作,重新学习了一下InvocationHandler以及Proxy。JAVA的代理和反射在公司的框架搭建、service处理以及RPC调用等地方都能看到他们的身影。因而越发感觉必须要熟练掌握他们的原理和使用方法才行。废话不多说了,切入正题
做了一个简单的demo。Car是一个接口,Jeep是Car的实现类。
package bo;
public interface Car {
public abstract void carName();
}
package bo;
public class Jeep implements Car{
@Override
public void carName(){
System.out.println("Nice to Meet You, I'm Jeep");
}
}
自定义了一个InvocationHandler类,并重载了invoke方法,对使用该Handler生成的代理类$Proxy0在调用非final方法前注入了一句话。效果可以理解为类似AOP。
package handler;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.logging.Logger;
import bo.Car;
public class DetailInvocationHandler implements InvocationHandler{
private Car car;
public DetailInvocationHandler(Car car){
this.car = car;
}
Logger logger = Logger.getLogger(DetailInvocationHandler.class.getName());
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
/**
* 1、此时如果如下调用,则将栈溢出。
* 原因:可以看到proxy即为生成的代理类$Proxy0,当调用proxy的carName方法时,
* 等于调用了handler中的invoke方法,此时,就会陷入死循环导致最后栈溢出,
* 然而调用getClass方法并不会溢出,这是因为该方法时final的。
* 2、此处传入proxy的话可以对于annotation、name、method等参数进行监控
*
*/
System.out.println(proxy.getClass().getName()); // 不会溢出
// ((Car)proxy).carName(); // 会溢出
logger.info("Now Enter In InvocationHandler!");
method.invoke(car, args);
return null;
}
}
最后,分别采用三种方法进行代理类的生成,并在最后测试了final方法是否会被拦截。
package service.impl;
import handler.DetailInvocationHandler;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import bo.Car;
import bo.Jeep;
import service.CarService;
class mockClass{
}
public class CarServiceImpl implements CarService{
@SuppressWarnings("unchecked")
public static void main(String[] args) throws Exception{
/**
* ClassLoader:
* 在调用用户定义的用JAVA实现的ClassLoader时,调用的是ExtClassLoader
* 在调用其他默认情况下的class(classpath下的)时,调用的是AppClassLoader
*
*/
System.out.println(Jeep.class.getClassLoader());
System.out.println(Car.class.getClassLoader());
System.out.println(mockClass.class.getClassLoader());
/**
* Proxy.newProxyInstance方法中,需要三个参数
* 一、ClassLoader,用以将生成的class加载入JVM中去执行
* 二、Interface,用以根据需要实现的接口去生成代理类(相当于子类)
* 三、InvocationHandler,用以对代理类的方法进行调度
*
*/
Car car = new Jeep();
InvocationHandler handler = new DetailInvocationHandler(car);
/**
* 1和2为两种获取interface的方法
*
*/
System.out.println("====================1==========================");
Car proxy = (Car)Proxy.newProxyInstance(mockClass.class.getClassLoader(),car.getClass().getInterfaces(), handler);
proxy.carName();
System.out.println("====================2==========================");
Car proxy2 = (Car)Proxy.newProxyInstance(Car.class.getClassLoader(),new Class[]{Car.class}, handler);
proxy2.carName();
/**
* Class.getConstructor用来声明特指一个代理类的构造函数(源代码中:Proxy(InvocationHandler h){this.h = h})
* Constructor.newInstance用来填入构造函数,并生成相应的代理类
*
*/
System.out.println("====================3==========================");
Class class1 = Proxy.getProxyClass(Car.class.getClassLoader(), car.getClass().getInterfaces());
Car proxy3 = (Car)class1.getConstructor(new Class[]{InvocationHandler.class}).newInstance(new Object[]{handler});
proxy3.carName();
/**
* final修饰符的方法不会被拦截!
*/
System.out.println("====================4==========================");
Car proxy4 = (Car)Proxy.newProxyInstance(Car.class.getClassLoader(),new Class[]{Car.class}, handler);
System.out.println(proxy4.getClass().getName());
}
}
详细的解释以及需要关注的一些地方都在注释中了,大部分在网上都能查得到。只是做了个demo将这些记忆点都记录了下来而已。
分享到:
相关推荐
java语言反射与动态代理学习笔记
《Java JDK 7学习笔记》将IDE操作纳为教学内容之一,使读者能与实践结合,提供的视频教学能更清楚地帮助读者掌握操作步骤。 内容简介 书籍 计算机书籍 《java jdk 7学习笔记》是作者多年来教学实践经验的总结...
NULL 博文链接:https://whp0731.iteye.com/blog/343787
Java基础常识、如何安装Java工具、Java语言的基础组成、Java面向对象、Java多线程、Java常用类、集合(重点)、IO流、GUI图形界面、网络编程、正则表达式、反射、注解、类加载器、动态代理等等,另外还包括银行管理...
031505_【第15章:Java反射机制】_动态代理笔记.pdf 031506_【第15章:Java反射机制】_工厂设计模式笔记.pdf 031601_【第16章:Annotation】_系统内建Annotation笔记.pdf 031602_【第16章:Annotation】_自定义...
{13.8}java.util.Date与java.sql.Date比较}{200}{section.13.8} {13.9}Meta Data}{201}{section.13.9} {13.10}可滚动结果集}{201}{section.13.10} {13.11}Procedure}{201}{section.13.11} {14}xml}{204}{...
我的Java学习笔记 初步打造在线最佳的Java学习笔记,笔记内容主要是对一些基础特性和编程细节进行总结整理,适合了解Java基础语法,想进一步深入学习的人 含博客讲解和二进制实例,采用maven构建,分模块学习,涉及...
本课程是《 java就业班》系统课程的第24章,全套课程精细讲解,该课程超过其他机构30%的课程量,经过我们全套课程系统学习的同学,可轻松从事Java高级工程师或系统架构师岗位,课程提供全套代码笔记其它相关素材及...
构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。 如果觉得不错,请先在这个仓库上点个 star 吧,这也是对我的肯定和鼓励,谢谢了。 不定时进行调整和补充,需要关注更新的请 watch、star、fork ...
详细介绍java的各项技术以及设计模式,包括动态代理,反射机制,网络编程,多线程等等,里面有详细的实践代码和说明,欢迎下载学习
构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。 如果觉得不错,请先在这个仓库上点个 star 吧,这也是对我的肯定和鼓励,谢谢了。 不定时进行调整和补充,需要关注更新的请 watch、star、fork ...
构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。 如果觉得不错,请先在这个仓库上点个 star 吧,这也是对我的肯定和鼓励,谢谢了。 不定时进行调整和补充,需要关注更新的请 watch、star、fork ...
构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。 如果觉得不错,请先在这个仓库上点个 star 吧,这也是对我的肯定和鼓励,谢谢了。 不定时进行调整和补充,需要关注更新的请 watch、star、fork ...
构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。 如果觉得不错,请先在这个仓库上点个 star 吧,这也是对我的肯定和鼓励,谢谢了。 不定时进行调整和补充,需要关注更新的请 watch、star、fork ...
构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。 如果觉得不错,请先在这个仓库上点个 star 吧,这也是对我的肯定和鼓励,谢谢了。 不定时进行调整和补充,需要关注更新的请 watch、star、fork ...
构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。 如果觉得不错,请先在这个仓库上点个 star 吧,这也是对我的肯定和鼓励,谢谢了。 不定时进行调整和补充,需要关注更新的请 watch、star、fork ...
构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。 如果觉得不错,请先在这个仓库上点个 star 吧,这也是对我的肯定和鼓励,谢谢了。 不定时进行调整和补充,需要关注更新的请 watch、star、fork ...
构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。 如果觉得不错,请先在这个仓库上点个 star 吧,这也是对我的肯定和鼓励,谢谢了。 不定时进行调整和补充,需要关注更新的请 watch、star、fork ...