第一章 Java基础之JDK动态代理
来源:互联网 发布:数字滤波算法快速滤波 编辑:程序博客网 时间:2024/05/16 11:48
最近在找工作,许多面试官都比较喜欢问Spring AOP,
面试官:Spring AOP的原理是什么?
答:动态代理。
面试官:动态代理的是怎么实现的?
答:......................
工资还想到12K,做梦吧!
回去后鄙人痛定思痛,冥思苦想一朝悟得何为“动态代理”。各位道友请听我一一道来
=========================================================================================================================
何为代理?代理的作用是啥?
代理其实就是将自己实现的功能交给A,A对这个功能做了一些包装,当B在调用这个功能其实最终还是调用到了自己的。代理的作用就是就是在原有的功能上加上其他的功能。
何为动态代理?
提到动态代理之前先说一下静态代理,静态代理就是在代码编译之前代理类已经写好了,就是已经存在Java源文件了;动态代理类是不需要你去手动书写Java源文件,是在程序运行的时候根据你所传参数生成的类生成相应的字节码,再通过字节码去创建代理对象。我们一般写代码就是如果想实现某个功能,就得新建一个java文件,在这个java文件中创建类,在类里面声明属性和方法。但是动态代理却不需要我们去新建java文件就能创建出一个类,在这个类里面就能实现我们想要的功能。
在动态代理中有两个很重要的接口和类
接口InvocationHandler,它是代理处理器类,被代理类的方法和增强效果就是在实现了这个接口的类中执行的,在InvocationHandler中有个方法
Object invoke(Object proxy, Method method, Object[] args) throws Throwable
这个方法的作用就是通过反射调用被代理对象的方法 , proxy就是创建动态代理实例的对象,proxy在这里感觉没啥作用。method就是被代理类要执行的方法,args就是这个方法的参数。
类Proxy,它的作用就是创建动态代理实例。我们主要调用Proxy的newProxyInstance方法来创建动态代理实例。
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
参数loader就是被代理类的类加载器,加载代理对象;参数interfaces,就是被代理对象锁实现的接口,proxy创建的代理对象也要实现这个接口;参数h代理处理器类,将增强的方法传给proxy,让proxy创建出的动态代理对象里面有增强的效果。
动态代理代码实现
/** * 照相机接口 * @author user * */public interface Camera {public void photo();}
/** * 索尼相机 * @author user * */public class CameraImp implements Camera{ /** * 照相 */public void photo() {System.out.println("给如花照了一张像");}}
代理处理器
import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;/** * 自动ps 其实就是给被代理对象的一些方法进行增强处理 * @author user * */public class AutoPs implements InvocationHandler{ private Object camera = null;public AutoPs(Object camera){this.camera = camera;}/** * 当Camera的实例类在调用photo方法时, * 实际上是将photo方法中功能是由invoke这个方法来完成的, * 在完成的时候还带上了附加功能 */public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {System.out.println("自动给照片美白,使得每张照片都貌美如花"+method.getName());method.invoke(camera, args);return null;}}
测试类
/** * 照相机代理,在照相的同时将美白功能加上 * @author user * */public class CameraProxyTest {public static void main(String[] args){//被代理对象CameraImp camera = new CameraImp();//代理对象处理器,动态代理对象调执行方法的时候,实际就是调用处理器的invoke方法AutoPs ps = new AutoPs(camera);/* * 生成动态代理对象cameraPs,创建的这个动态代理实例实现了被代理接口 * 被代理接口就是别代理对象实现了的接口,在这里就是Camera接口 */Camera cameraPs = (Camera)Proxy.newProxyInstance(camera.getClass().getClassLoader(), camera.getClass().getInterfaces(), ps);/* * 动态代理对象由于实现了被代理接口 * 动态代理对象在执行方法的时候是由代理对象处理器的invoke方法在执行 * invoke方法里面不仅执行了被代理对象的方法,而且还带上了一些额外功能。 */cameraPs.photo();}}
自动给照片美白,使得每张照片都貌美如花photo给如花照了一张像
Camera cameraPs = (Camera)Proxy.newProxyInstance(camera.getClass().getClassLoader(), camera.getClass().getInterfaces(), ps);这段代码就是创建出动态代理对象,这个对象继承了Proxy和实现了Carema接口。我们其实可以通过通过反编译工具查看cameraPs的代码的,这里我就模拟写出一个caremaPs的主要代码。
public class CameraPs extends Proxy implements Camera{private static Method m; protected CameraPs(InvocationHandler h) {super(h);}public void photo() {try {super.h.invoke(this, m, null);} catch (Throwable e) {// TODO Auto-generated catch blocke.printStackTrace();}} static { try { m = Class.forName("Camera").getMethod("photo", new Class[0]); } catch(NoSuchMethodException nosuchmethodexception) { throw new NoSuchMethodError(nosuchmethodexception.getMessage()); } catch(ClassNotFoundException classnotfoundexception) { throw new NoClassDefFoundError(classnotfoundexception.getMessage()); } } }上面这段代码我调用里面的photo方法会出错,晕,这个类是为了更好地理解proxy创建的动态代理对象是什么样的啊
总结
1.创建被代理接口Camera和被代理对象CamearaImp;- 第一章 Java基础之JDK动态代理
- Java动态代理之JDK动态代理
- Java动态代理之JDK
- java之jdk动态代理
- Java代理之JDK动态代理
- Java基础:JDK动态代理源码分析
- java基础之动态代理
- Java之代理(jdk静态代理,jdk动态代理,cglib动态代理,aop,aspectj)
- Java之代理(jdk静态代理,jdk动态代理,cglib动态代理,aop,aspectj)
- Java之代理(jdk静态代理,jdk动态代理,cglib动态代理,aop,aspectj)
- Java之代理(jdk静态代理,jdk动态代理,cglib动态代理,aop,aspectj)
- Java之代理(jdk静态代理,jdk动态代理,cglib动态代理,aop,aspectj)
- Java之代理(jdk静态代理,jdk动态代理,cglib动态代理,aop,aspectj)
- Java代理之(jdk静态代理/jdk动态代理/cglib动态代理/aop/aspectj)
- Java进阶之 JDK动态代理与Cglib动态代理
- java动态代理模式Proxy之JDK动态代理机制
- java动态代理之jdk的动态代理
- 大话java之JDK动态代理和CGLIB动态代理
- HDOJ 2031 进制转换
- opencv2 反向投影直方图检测特定图像内容
- Redis 3.0 cluster 集群环境搭建
- Druid连接池 一个设置 removeAbandonedTimeout
- ListView的简单使用
- 第一章 Java基础之JDK动态代理
- mybatis 批量增加 Parameter '__frch_item_0' not found. Available parameters are [lis
- Mybatis的批量更新 bug
- mybatis批量操作
- com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in
- word 文档中嵌入和链接OLE 对象|Packager-对象包装程序
- 崩溃统计
- Jenkins入门系列之——02第二章 Jenkins安装与配置
- ListenableFuture demo