【附章6 反射的应用】反射的应用:动态代理

本文详细介绍了Java反射机制中的动态代理,包括其原理、相关API的使用、动态代理与AOP的对比,以及在实际开发中的应用场景。通过实例演示如何创建代理对象并调用方法,以及动态代理在AOP编程中的优势和改进方式。
摘要由CSDN通过智能技术生成

❤写在前面
❤博客主页:努力的小鳴人
❤系列专栏:JavaSE超详总结😋
❤欢迎小伙伴们,点赞👍关注🔎收藏🍔一起学习!
❤如有错误的地方,还请小伙伴们指正!🌹

对于【14章Java反射机制】Java Reflection 🔥的拓展

在这里插入图片描述


一、概述

指客户通过代理类来调用其它对象的方法,并且是在程序运行时根据需要动态创建目标类的代理对象

  1. 使用情况
    ●调试
    ●远程方法调用
  2. 相比静态代理优点:
    抽象角色中(接口)声明的所有方法都被转移到调用处理器一个集中的方法中处理

🔥相关API

  1. Proxy :专门完成代理的操作类,是所有动态代理类的父类
    通过此类为一个或多个接口动态地生成实现类
  2. 提供用于创建动态代理类和动态代理对象静态方法
    static Class<?> getProxyClass(ClassLoader loader, Class<?>… interfaces)
    创建一个动态代理类所对应的Class对象
    ●static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h)
    直接创建一个动态代理对象
    在这里插入图片描述

二、原理

使用一个代理将对象包装起来, 然后用该代理对象取代原始对象,任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象上

🔥动态代理步骤

  1. 创建一个实现接口InvocationHandler的类,它必须实现invoke方法,以完成代理的具体操作
public Object invoke(Object theProxy, Method method, Object[] params) throws Throwable{
try{
	Object retval = method.invoke(targetObj, params);
		// Print out the result
		System.out.println(retval);
		return retval;
	}catch (Exception exc){}
}

在这里插入图片描述

  1. 创建被代理的类以及接口

在这里插入图片描述

  1. 通过Proxy的静态方法
    newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
    创建一个Subject接口代理
RealSubject target = new RealSubject();
// Create a proxy to wrap the original implementation
DebugProxy proxy = new DebugProxy(target);
// Get a reference to the proxy through the Subject interface
Subject sub = (Subject) Proxy.newProxyInstance(
Subject.class.getClassLoader(),new Class[] { Subject.class }, proxy);
  1. 通过 Subject 代理调用RealSubject 实现类的方法
String info = sub.say(Peter", 24);
System.out.println(info);

三、动态代理与AOP

AOP代理可代替目标对象,AOP代理包含了目标对象的全部方法

AOP代理中的方法与目标对象的方法存在差异
AOP代理内的方法可以在执行目标方法之前、之后插入一些通用处理

下面介绍一种更实用的动态代理机制:
在这里插入图片描述

改进为
在这里插入图片描述
改进后:代码段1、代码段2、代码段3和深色代码段分离开了,但代码段1、2、3又和一个特定的方法A耦合了!最理想的效果是:代码块1、2、3既可以执行方法A,又无须在程序中以硬编码的方式直接调用深色代码的方法

public class DogUtil{
	public void method1(){
		System.out.println("===== 模拟通用方法一 =====");
	}
	public void method2(){
		System.out.println("===== 模拟通用方法二 =====");
	}
}
public class MyInvocationHandler implements InvocationHandler{
		// 需要被代理的对象
		private Object target;
		public void setTarget(Object target){
				this.target = target;}
// 执行动态代理对象的所有方法时,都会被替换成执行如下的invoke方法
		public Object invoke(Object proxy, Method method, Object[] args)
				throws Exception{
				DogUtil du = new DogUtil();
				// 执行DogUtil对象中的method1。
				du.method1();
				// 以target作为主调来执行method方法
				Object result = method.invoke(target , args);
				// 执行DogUtil对象中的method2。
				du.method2();
				return result;}}

public class MyProxyFactory{
		// 为指定target生成动态代理对象
		public static Object getProxy(Object target)
				throws Exception{
				// 创建一个MyInvokationHandler对象
				MyInvokationHandler handler =
				new MyInvokationHandler();
				// 为MyInvokationHandler设置target对象
				handler.setTarget(target);
				// 创建、并返回一个动态代理对象
				return
Proxy.newProxyInstance(target.getClass().getClassLoader()
		, target.getClass().getInterfaces() , handler);
		}
}
public class Test{
	public static void main(String[] args)
			throws Exception{
			// 创建一个原始的HuntingDog对象,作为target
			Dog target = new HuntingDog();
			// 以指定的target来创建动态代理
			Dog dog = (Dog)MyProxyFactory.getProxy(target);
			dog.info();
			dog.run();
	}
}

使用Proxy生成一个动态代理时,往往并不会凭空产生一个动态代理
通常都是为指定的目标对象生成动态代理
在这里插入图片描述

🎁总结:这动态代理要细细琢磨,看不懂了继续看
👌 作者算是一名Java初学者,文章如有错误,欢迎评论私信指正,一起学习~~
😊如果文章对小伙伴们来说有用的话,点赞👍关注🔎收藏🍔就是我的最大动力!
🚩不积跬步,无以至千里书接下回,欢迎再见🌹

  • 39
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 56
    评论
评论 56
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力的小鳴人

鳴人将永远记住您的恩惠

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值