动态代理的理解

来源:互联网 发布:linux查看请求url 编辑:程序博客网 时间:2024/06/07 02:02

    今天看了一下动态代理,谈一谈自己的理解。

    代理模式的含义是代理类的委托类都有同样的接口,代理类负责处理委托类的预处理消息,过滤消息,还有后处理消息等。代理类的本身并不去实现方法,而是调用委托类的方法去实现。

    代理类可以分为两种,静态代理和动态代理,两者的区别就是代理类的.class文件出现的先后问题。

    

    首先,先看一下静态代理:

1、eatable.java

package com.huajiu.proxy;public interface eatable {void eat();}


2、Dog.java

package com.huajiu.proxy;public class Dog implements eatable {@Overridepublic void eat() {System.out.println("狗吃骨头");}}

3、TestProxy

package com.huajiu.proxy;public class TestProxy implements eatable{public TestProxy(Dog d) {this.d = d;}Dog d;public void eat() {System.out.println("吃东西之前");d.eat();System.out.println("吃东西之后");}}

4、Test

package com.huajiu.proxy;public class Test {public static void main(String[] args) {Dog d = new Dog();TestProxy p = new TestProxy(d);p.eat();}}

    观察代码,可以发现,代理的好处就是不用访问Dog这一类的具体内容,实现它的eatable接口,然后传入一个Dog于代理方法里面,就可以对该方法进行预处理,过滤和后处理等操作,但是,这个代理的缺陷就是只能代理一个方法,不能代理其他的方法,假如又来了一个Cat,就要产生重复的代码,这就会产生重复的操作而降低效率,解决这一个问题的方法就是通过一个类实现所有的代理功能,这就是要用到动态代理这一方法,然后我们来看一下动态代理。

    在JDK中,首先是一个接口 InvocationHandler 里面有一个invoke(Object proxy,Method method,Object[] args) 其中proxy是被代理的实例,而method是代理实例上调用的接口方法,Object[] args是方法调用时所需要的参数。InvocationHandler实际上是一个代理实例的调用处理程序实现的接口。

    然后就是Proxy类,Proxy类是专门完成代理类和实例的静态方法,里面有一个 public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException 其中ClassLoader loader是一个类加载器,Class<?>[] interfaces则是一个得到的全部接口的组,InvocationHandler h是上面介绍的接口。

    动态代理的好处就是利用了java的反射机制动态的生成,无需程序员自己去一个一个的把代码写出来,这样提高了效率,又提高了程序的可扩展性。下面是动态代理的应用,proxy自动生成一个代理:

1、eatable.java

package com.huajiu.proxy;public interface eatable {void eat();}
2、Dog.java

package com.huajiu.proxy;public class Dog implements eatable {@Overridepublic void eat() {System.out.println("狗吃骨头");}}
3、DogHandler1.java
package com.huajiu.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class DogHandler1 implements InvocationHandler {private Object target;   public DogHandler1(Object target) {          this.target = target;       }@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {System.out.println("吃东西之前");method.invoke(target, args);System.out.println("吃东西之后");return null;}}
4、Client.java
package com.huajiu.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;public class Client {public static void main(String[] args) {Dog d = new Dog();InvocationHandler h = new DogHandler1(d);eatable e = (eatable)Proxy.newProxyInstance(d.getClass().getClassLoader(), d.getClass().getInterfaces(), h);e.eat();}}










0 0
原创粉丝点击