这几天,为了工作,重新学习了一下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的基础知识,包括面向对象、集合、IO流、多线程、反射与动态代理以及Java 8的新特性等方面,旨在帮助初学者或有经验的开发者巩固和提升Java编程技能。 1. 面向对象(OOP):Java的核心是...
### Java语言反射与动态代理深度解析 #### 一、Java反射机制详解 Java反射机制是Java编程语言的一个强大特性,允许程序在运行时检查和修改自身结构与行为。这一机制为开发人员提供了高度的灵活性,尤其是在框架...
这篇学习笔记主要关注动态代理部分,虽然没有提供具体的压缩包文件内容,但根据标题和描述,我们可以深入探讨这两个概念。 **反射(Reflection)** 反射是Java语言的一个强大工具,它允许程序在运行时检查类、接口...
【Java学习笔记(源码)】是一份详细记录了Java编程语言学习过程的资源集合,包含实际的源代码示例。这份笔记旨在帮助初学者和有一定经验的开发者深入理解和掌握Java语言的核心概念、语法以及常见应用。以下是笔记中...
Java反射是Java编程语言中的一个强大特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在“java反射笔记”这个主题中,我们将深入探讨反射的基础知识和常见用法。 首先,我们需要了解...
本笔记主要涵盖了四个核心知识点:Java反射机制、流(I/O流)、内存管理和Java学习的基础。以下是对这些主题的详细阐述: 一、Java反射机制 Java反射机制是Java语言的一个强大特性,允许程序在运行时检查类、接口、...
Java是一种广泛使用的面向对象的编程语言,以其跨平台、健壮性和安全性著称。这份《Java学习笔记》包含了丰富的知识内容,旨在帮助学习...总之,《Java学习笔记》是一份全面而实用的学习资源,适合Java初学者和进阶者。
Java公司培训经典学习笔记是针对Java编程语言进行深入学习的一份宝贵资料,涵盖了从基础到高级的诸多知识点,旨在帮助开发者提升技能,适应企业级项目开发的需求。以下将详细阐述这些笔记中的关键点: 1. **Java...
Java反射机制是Java编程语言中的一个强大特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性...通过阅读"JAVA私塾笔记整理——反射机制(Reflection)",你可以更全面地理解和掌握这一关键特性。
在深入探讨JAVA学习笔记之前,我们首先理解一下JAVA这一编程语言的重要性。JAVA,由Sun Microsystems公司(现已被Oracle收购)于1995年推出,是一种面向对象的、跨平台的编程语言,以其“一次编写,到处运行”的特性...
《Java JDK 7学习笔记》将IDE操作纳为教学内容之一,使读者能与实践结合,提供的视频教学能更清楚地帮助读者掌握操作步骤。 内容简介 书籍 计算机书籍 《java jdk 7学习笔记》是作者多年来教学实践经验的总结...
【良葛格Java学习笔记】 本笔记主要涵盖了Java编程语言的核心概念和技术,旨在帮助初学者以及有一定基础的开发者深入理解并掌握Java。Java作为一种广泛应用于企业级应用开发、移动开发(尤其是Android)以及大数据...
反射学习笔记是深入理解这一关键特性的重要资源。以下是对"反射学习笔记"中可能包含的知识点的详细阐述: 1. **什么是反射**:反射是Java提供的一种机制,能够在运行时获取类的信息(如类名、属性、方法等)并动态...
这份"个人Java学习过程中所有学习笔记"包含了作者在学习Java时积累的宝贵经验,旨在帮助初学者或有经验的程序员巩固基础,提升技能。 笔记内容可能涵盖以下几个主要部分: 1. **Java基础**:这部分通常包括Java的...
Java面试题及学习笔记概述 Java作为一种广泛应用的编程语言,其面试题库广泛且深入,涵盖了从基础语法到高级特性的各个层面。本篇将基于常见的Java面试问题,结合学习笔记,深入探讨Java的核心概念和技术。 一、...
### Java常用框架学习笔记 #### Hibernate ##### 1.1 Hibernate 实现数据库操作步骤 - **导入所需的Jar包**:为了使用Hibernate框架,首先需要在项目中导入Hibernate库。这通常意味着添加一系列与Hibernate相关的...
【标题】"良葛格Java学习笔记html.rar"是一份以HTML格式编写的Java学习资料,由知名在线教育人物“良葛格”所创建。这份压缩包文件包含了他对Java编程语言深入浅出的讲解,旨在帮助学习者提高Java编程技能。 【描述...
这份"Java-J2EE全部学习笔记 培训结构的学习资料"涵盖了从基础到高级的Java编程和J2EE应用开发的知识点,对于想要深入理解Java EE技术的人来说是一份宝贵的资源。 1. **Java基础知识**:这部分可能包括Java语言的...
Java JDK 6学习笔记是Java开发者入门和进阶的重要参考资料,由知名作者林信良编著。本笔记主要涵盖了JDK 6版本的核心特性和关键概念,为读者提供了全面而深入的学习路径。以下是对其中重要知识点的详细阐述: 1. **...
这份"Java学习笔记.zip"文件显然包含了一些关于Java编程的基础到高级的学习资料,特别聚焦于JDK 6版本。JDK(Java Development Kit)是Java开发环境的核心组件,包括了Java编译器、Java运行时环境、以及丰富的API库...