`
Surlymo
  • 浏览: 95954 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JAVA代理与反射学习笔记(一)

阅读更多
这几天,为了工作,重新学习了一下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语言反射与动态代理学习笔记

    Java JDK 7学习笔记(国内第一本Java 7,前期版本累计销量5万册)

     《Java JDK 7学习笔记》将IDE操作纳为教学内容之一,使读者能与实践结合,提供的视频教学能更清楚地帮助读者掌握操作步骤。 内容简介 书籍 计算机书籍  《java jdk 7学习笔记》是作者多年来教学实践经验的总结...

    java语言反射与动态代理学习笔记2(动态代理部分)

    NULL 博文链接:https://whp0731.iteye.com/blog/343787

    java基础学习总结笔记

    Java基础常识、如何安装Java工具、Java语言的基础组成、Java面向对象、Java多线程、Java常用类、集合(重点)、IO流、GUI图形界面、网络编程、正则表达式、反射、注解、类加载器、动态代理等等,另外还包括银行管理...

    Java开发详解.zip

    031505_【第15章:Java反射机制】_动态代理笔记.pdf 031506_【第15章:Java反射机制】_工厂设计模式笔记.pdf 031601_【第16章:Annotation】_系统内建Annotation笔记.pdf 031602_【第16章:Annotation】_自定义...

    Java学习笔记-个人整理的

    {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-learning:逐步打造在线最佳的Java学习笔记,包括博客讲解和源码实例,包括Java SE和Java Web

    我的Java学习笔记 初步打造在线最佳的Java学习笔记,笔记内容主要是对一些基础特性和编程细节进行总结整理,适合了解Java基础语法,想进一步深入学习的人 含博客讲解和二进制实例,采用maven构建,分模块学习,涉及...

    java反射、泛型、注解、代理精讲

    本课程是《 java就业班》系统课程的第24章,全套课程精细讲解,该课程超过其他机构30%的课程量,经过我们全套课程系统学习的同学,可轻松从事Java高级工程师或系统架构师岗位,课程提供全套代码笔记其它相关素材及...

    java8源码-java-learning-copy:java-学习-复制

    构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。 如果觉得不错,请先在这个仓库上点个 star 吧,这也是对我的肯定和鼓励,谢谢了。 不定时进行调整和补充,需要关注更新的请 watch、star、fork ...

    JavaSE学习笔记

    详细介绍java的各项技术以及设计模式,包括动态代理,反射机制,网络编程,多线程等等,里面有详细的实践代码和说明,欢迎下载学习

    java8源码-java-learning:java学习

    构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。 如果觉得不错,请先在这个仓库上点个 star 吧,这也是对我的肯定和鼓励,谢谢了。 不定时进行调整和补充,需要关注更新的请 watch、star、fork ...

    java8源码-java-learning:java练习库

    构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。 如果觉得不错,请先在这个仓库上点个 star 吧,这也是对我的肯定和鼓励,谢谢了。 不定时进行调整和补充,需要关注更新的请 watch、star、fork ...

    java8源码-sun:java相关知识

    构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。 如果觉得不错,请先在这个仓库上点个 star 吧,这也是对我的肯定和鼓励,谢谢了。 不定时进行调整和补充,需要关注更新的请 watch、star、fork ...

    java8源码-java-learning:java-learning.git

    构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。 如果觉得不错,请先在这个仓库上点个 star 吧,这也是对我的肯定和鼓励,谢谢了。 不定时进行调整和补充,需要关注更新的请 watch、star、fork ...

    java8源码-laowu-java-learning:java基础测试项目

    构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。 如果觉得不错,请先在这个仓库上点个 star 吧,这也是对我的肯定和鼓励,谢谢了。 不定时进行调整和补充,需要关注更新的请 watch、star、fork ...

    java8源码-test:仅供测试

    构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。 如果觉得不错,请先在这个仓库上点个 star 吧,这也是对我的肯定和鼓励,谢谢了。 不定时进行调整和补充,需要关注更新的请 watch、star、fork ...

    java8源码-j2se:j2se介绍

    构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。 如果觉得不错,请先在这个仓库上点个 star 吧,这也是对我的肯定和鼓励,谢谢了。 不定时进行调整和补充,需要关注更新的请 watch、star、fork ...

    java8源码-javaweb_learing:javaweb_learning

    构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。 如果觉得不错,请先在这个仓库上点个 star 吧,这也是对我的肯定和鼓励,谢谢了。 不定时进行调整和补充,需要关注更新的请 watch、star、fork ...

Global site tag (gtag.js) - Google Analytics