摘要:紧接着上节,为了解决静态代理的问题,出现了动态代理,假设动态代理是一个代购公司,私有变量为动态生成的具体的真实对象,可代购对应的产品。这个注释是说提供个一个静态方法来创建代理类和代理实例,它也是所有由此方法创建的代理类的父类。
紧接着上节,为了解决静态代理的问题,出现了动态代理, 假设动态代理是一个代购公司,私有变量Object factory为动态生成的具体的真实对象,可代购对应的产品 。代码:
/**
* 动态代理
*/
public class DynamicProxyCompanyC implements InvocationHandler {
// 被代理的对象,即真实对象
private Object factory;
public Object getFactory() {
return factory;
}
public void setFactory(Object factory) {
this.factory = factory;
}
// 通过proxy获取动态代理的对象
public Object getProxyInstance() {
//第三个参数是InvocationHandler,传入自身说明此proxy对象是和自身的invoke方法合作的,代理对象方法调用会经过下面invoke的增强
return Proxy.newProxyInstance(factory.getClass().getClassLoader(), factory.getClass().getInterfaces(), this);
}
@Override
/**通过动态代理对象对方法进行增强
* @param proxy 代理对象
* @param method 要增强的方法(拦截的方法)
* @param args 方法参数
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
dosomeThingBefore();
Object ret = method.invoke(factory, args);// 通过反射机制调用方法
dosomeThingAfter();
return ret;
}
public void dosomeThingBefore() {
System.out.println("售前服务,负责产品调研,兴趣爱好");
}
public void dosomeThingAfter() {
System.out.println("售后服务,包装丶送货上门一条龙服务");
}
}
测试类:
public class Proxytest {
public static void main(String[] args) {
// 代购公司C,负责代购所有产品
DynamicProxyCompanyC proxy = new DynamicProxyCompanyC();
// 日本有家A公司生产男性用品
ManToolFactory dogToolFactory = new AManFactory();
// 代购A公司的产品
proxy.setFactory(dogToolFactory);
// 创建A公司的代理对象
ManToolFactory proxyObject = (ManToolFactory) proxy.getProxyInstance();
// 代理对象完成代购男性用品
proxyObject.saleManTool("D");
System.out.println("--------------");
// 日本有家B公司生产女性用品
WomanToolFactory womanToolFactory = new BWomanFactory();
// 代购B公司的产品
proxy.setFactory(womanToolFactory);
// 创建B公司的代理对象
WomanToolFactory proxyObject1 = (WomanToolFactory) proxy.getProxyInstance();
// 代理对象完成代购女性用品
proxyObject1.saleWomanTool(1.8);
}
}
// 售前服务,负责产品调研,兴趣爱好
// A工厂出售男性用品,D罩杯
// 售后服务,包装丶送货上门一条龙服务
// --------------
// 售前服务,负责产品调研,兴趣爱好
// B工厂生产女性用品,长度1.8米
// 售后服务,包装丶送货上门一条龙服务
动态代理解决了上节说的开闭原则,那么接下来我们要解密动态代理的原理,重点类DynamicProxyCompanyC
1.实现了InvocationHandler接口;
2.通过proxy获取动态代理的对象。
根据我们此例子里面来说,动态代理就类似一个代购公司,可代购所有产品,需要购买哪个产品的时候就实例化一个真实对象(如测试类需要男性用品则将接口引用指向真实对象AManFactory),根据真实对象创建代理对象来执行具体的方法,图解如下:
Proxy:接下来我们先初步看一下JDK里面的Proxy这个源码。
这个注释是说Proxy提供个一个静态方法来创建代理类和代理实例,它也是所有由此方法创建的代理类的父类。
静态方法创建代理实例即方法newProxyInstance(ClassLoader loader,Class>[]interfaces,InvocationHandler h);
InvocationHandler 是一个接口,定义了invoke(Object proxy, Method method, Object[] args)方法
总的来说Proxy专门负责new一个实例(真实对象),而具体方法做什么,业务怎样增强就由InvocationHandler(抽象对象)的invoke方法(抽象对象即接口定义的方法)来决定。
接下来我们要搞清楚动态代理的底层原理,首先我们调试一下test类,会发现 ManToolFactory proxyObject = (ManToolFactory) proxy.getProxyInstance()中创建的proxyObject 对象类名是$Proxy0,是ManToolFactory接口的实现类。但是我们项目工程里面却没有$Proxy0这个类,那它究竟是怎么出现的,下节讲解。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/73671.html
摘要:值得一提的是由于采用动态创建子类的方式生成代理对象,所以不能对目标类中的方法进行代理。动态代理中生成的代理类是子类,调试的时候可以看到,打开源码可看到实现了和也就实现方法。 前面讲到了动态代理的底层原理,接下来我们来看一下aop的动态代理.Spring AOP使用了两种代理机制:一种是基于JDK的动态代理,一种是基于CGLib的动态代理. ①JDK动态代理:使用JDK创建代理有一个限制...
摘要:对象什么时候被回收答可达性分析,当发现某个类不被引用,类会被回收类的生命周期与动态代理关系动态代理是没有源文件,直接生成字节码的,加载到上面的。 上节讲到动态代理生成的类为$Proxy0,但是在我们项目里面却不存在,实际我们是用了这个实现类调用了方法,想要知道这个问题,首先要理解类的完整生命周期. 类的完整生命周期 showImg(https://segmentfault.com/im...
摘要:总结动态代理的相关原理已经讲解完毕,接下来让我们回答以下几个思考题。 【干货点】 此处是【好好面试】系列文的第12篇文章。文章目标主要是通过原理剖析的方式解答Aop动态代理的面试热点问题,通过一步步提出问题和了解原理的方式,我们可以记得更深更牢,进而解决被面试官卡住喉咙的情况。问题如下 SpringBoot默认代理类型是什么 为什么不用静态代理 JDK动态代理原理 CGLIB动态代理...
摘要:修饰者模式设计模式中的修饰者模式能动态地给目标对象增加额外的职责。修饰者模式调用的时序图如下图所示。的实现原理和修饰者模式类似。 在上边一篇文章中我们介绍了Spring AOP的基本概念,今天我们就来学习一下与AOP实现相关的修饰者模式和Java Proxy相关的原理,为之后源码分析打下基础。 修饰者模式 Java设计模式中的修饰者模式能动态地给目标对象增加额外的职责(Respon...
阅读 1485·2021-11-17 09:33
阅读 3943·2021-09-28 09:42
阅读 3793·2021-09-13 10:35
阅读 3292·2021-09-06 15:00
阅读 2721·2021-08-27 13:12
阅读 3892·2021-07-26 23:38
阅读 2277·2019-08-30 15:55
阅读 797·2019-08-30 15:53