代理就像个中介,最外层操作代理对象,代理对象再调用委托对象
当需要在调用前后做一些处理,但是这些处理与业务逻辑无关的时候,如果把无关代码写在业务逻辑里面,代码就会变得很乱,这时候用代理就再好不过了。
就像spring的aop编程,也是用了代理,在调用前后做一些校验、日志记录等无关业务流程的事
因为要通过代理对象去调用委托对象,所以代理对象需要持有委托对象的引用,而且代理类中需要实现委托对象的各种方法
代理有两种一种是静态代理、一种是动态代理
静态代理是由自己编写代理类,但是代理类都相差无几,而且要每一个类都编写一个代理类的话,就会有太多的类了
动态代理是由反射技术,自动生成代理类,运行期才生成class文件
动态代理有两种实现方法,一种是java.lang.reflect、一种是cglib
jdk自带的实现方法,委托类只能实现接口,不能继承类,所有具有一定的局限性
cglib,委托类既可以实现接口也可以继承类
下面通过一个例子来说明代码
一个Book接口,接口有read方法,有一个EBook类实现Book接口
//Book接口 public interface Book { public void read(); } //委托类 class EBook implements Book { @Override public void read() { System.out.println("读电子书"); } }
静态代理
比原本的代码多了一个BookProxy
//代理类 public class BookProxy implements Book{ //持有Book委托实例 private Book book; //绑定Book委托实例并返回代理对象 public Book bind(Book book){ this.book=book; return this; } //委托book调用read public void read(){ try{ //前置代码 book.read(); //后置代码 }catch(Exception e){ //异常代码 }finally{ //finall代码 } } }
可以看到,代理的本质就是,代理类持有委托对象,通过代理对象去调用委托对象,在调用的时候就可以添加一些额外代码
jdk实现动态代理
这里的BookProxy,是使用反射,在运行期自动生成的
重要的是InvocationHandler,调用反射对象的时候,实际上是调用了InvocationHandler.invoke()
所以需要实现InvocationHandler接口,让实现类持有委托类引用,并且重写invoke方法
//代理类 public class BookInvocationHandler implements InvocationHandler { //委托类 private Object target; //绑定委托类 并 返回一个代理对象 public Object bind(Object target){ this.target=target; return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } //调用委托对象 //proxy是代理对象,method是要调用的方法,arg是方法的参数 @Override public Object invoke(Object proxy, Method method, Object[] arg) throws Throwable { Object result = null; try{ //前置代码 result=method.invoke(proxy,arg); //后置代码 }catch(Exception e){ //异常代码 }finally{ //finally代码 } return result; } }
这里需要注意两个地方
- Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)通过newProxyInstance拿到代理对象,主要参数,loader:委托类的类加载器,interfaces实现的接口,h调用处理程序
- InvocationHandler.invoke(Object proxy, Method method, Object[] arg)这里的参数proxy是代理对象!所以调用委托对象的时候不能是method.invoke(proxy,arg),不然会循环调用invoke的,要invoke绑定的委托类对象
jdk不能代理继承的类,要代理继承的类,要用cglib去实现
cglib实现动态代理
这里和jdk实现方法差不多,就是InvocationHandler换成了MethodInterceptor
proxy还是用反射在运行期生成,只是他用Enhancer.create()
public class BookInterceptor implements MethodInterceptor { private Object target; public Object bind(Object target) { this.target = target; Enhancer enhancer = new Enhancer(); //设置父类 enhancer.setSuperclass(this.target.getClass()); // 回调方法 enhancer.setCallback(this); // 创建代理对象 return enhancer.create(); } //obj委托对象 mehtod要拦截的方法 args参数 proxy也是要拦截的方法(更快) @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { method.invoke(target, args); return null; } }
相关推荐
1:静态代理出现的实际背景,静态代理时如何演化成动态代理 2: 动态代理demo 举例实际应用场景(载入数据库驱动的时候,使用AIDL与系统Servic进行通信) 3: 动态代理使用到基础理论:ClassLoader 加载.class字节码...
结合spring框架实现的动态代理代理,spring,Proxy
JDK动态代理,关于jdk动态代理的问题!详细的说明!JDK动态代理JDK动态代理
动态代理及其生成的代理类,可以反编译查看其类的结构。
动态代理设计模式 日志和源码 动态代理设计模式 日志和源码
通过动态代理,在单元格中添加spinbox,checkbox,combobox。
对jdk中的动态代理执行过程进行了详细跟踪,并反编译了动态代理调用自动生成的代理类,并对其进行了详细讲解。
jdk 的动态代理和CGLIB代理
spring之AOP(动态代理),包括jdk动态代理和CGLib动态代理
java静态代理 jdk动态代理 cglib动态代理 代理原理
动态代理是使用jdk的反射机制,创建对象的能力, 创建的是代理类的对象。 而不用你创建类文件。不用写java文件。 动态:在程序执行时,调用jdk提供的方法才能创建代理类的对象。jdk动态代理,必须有接口,目标类必须...
主要对Spring AOP的相关概念和简单的静态代理、动态代理以及常见的几种AOP配置方式做总结学习。主要包括:1. AOP的常见概念 2. 静态代理 3. jdk动态代理 4. Aspectj and Aspectjweaver 5. **aop-config** 6. CGLIB ...
动态代理动态代理动态代理动态代理动态代理动态代理动态代理动态代理动态代理动态代理动态代理动态代理动态代理动态代理
Java实现动态代理的两种方式。 相对来说cglib更加方便。可以实现为实现接口的类(非final类)
java动态代理 public class HireProxy implements InvocationHandler { //被代理的真实角色 private Object obj; public HireProxy(Object obj) { super(); this.obj = obj; } //第二个参数method,被...
动态代理和静态代理demo
java动态代理 完整版 java动态代理 完整版 java动态代理 完整版 java动态代理 完整版 java动态代理 完整版
java代理机制 JDK动态代理和cglib代理 详解
java动态代理例子,这里面有两个例子,一个是jdk的动态代理,一个是cglib的动态代理,让你明白什么是动态代理,动态代理可以做什么。
JAVA静态代理和动态代理