代理设计模式

来源:互联网 发布:php的视频教程下载 编辑:程序博客网 时间:2024/05/16 17:27

    代理设计模式:主要分为两种,静态代理和动态代理两种设计模式。并且还分jdk代理和cglib代理。这次在一个开源的项目中,查看源码的时候遇到了,就想看一看,有很多都是从别人的博客上面摘抄过来的,但是还是想写出来。哈哈哈,真任性,在以后的文章中,其他的设计模式我还会给出来的。。。


1、Subject是委托类和代理类的接口

2、RealSubject是委托类,Proxy是代理类

3、request是公共方法

静态代理没什么说的,一个委托类对应一个代理类,代理类在编译期间就已经完全确定下来

    动态代理:代理类是在运行时自动生成,不用自己单独创建一个代理类。动态代理可以对委托的代理方法进行处理,比如添加方法,在之前或之后调用其他方法等等,同时这种设计模式在很多插件或者框架中都有用到,比如spring中面向切面编程就有用到。动态代理分为jdk动态代理和cglib动态代理。

jdk动态代理

1、定义业务逻辑

public interface Service{ 

    //目标方法

    public abstract void add(); 

}

 

public class UserServiceImplimplements Service { 

    public void add() { 

        System.out.println("This is addservice"); 

    } 

}

2、利用java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口定义代理类的实现。

class MyInvocatioHandlerimplements InvocationHandler {

    private Object target;

 

    public MyInvocatioHandler(Object target) {

        this.target = target;

    }

 

    @Override

    public Object invoke(Object proxy, Methodmethod, Object[] args) throws Throwable {

        System.out.println("-----before-----");

        Object result = method.invoke(target,args);

       System.out.println("-----end-----");

        return result;

    }

}

3、使用动态代理

public class ProxyTest {

    public static void main(String[] args) {

        Service service = new UserServiceImpl();

        MyInvocatioHandler handler = newMyInvocatioHandler(service);

        Service serviceProxy =        (Subject)Proxy.newProxyInstance(service.getClass().getClassLoader(),service.getClass().getInterfaces(),handler);   

serviceProxy.add();

    }

}

执行结果:

-----before-----

This is addservice

-----end-----

使用代理模式流程:

1、生成一个实现InvocationHandler(是代理实例的调用,处理程序实现的接口)接口的类

2、重写invoke(Object proxy, Method method,Object[] args)方法;返回Object result =method.invoke(target, args)对象;invoke是在实例上处理方法调用并返回结果。

3、使用Proxy.newProxyInstance()生成一个代理类;其中有三个参数:

   Loader:定义代理类的类加载器

   Interfaces:代理类要实现的接口列表

   H:指派方法调用的调用处理程序

 

jdk动态代理使用的局限性

  通过反射类ProxyInvocationHandler回调接口实现的jdk动态代理,要求委托类必须实现一个接口,但事实上并不是所有类都有接口,对于没有实现接口的类,便无法使用该方方式实现动态代理。

CGLib动态代理:

  JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要CGLib了。CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。JDK动态代理与CGLib动态代理均是实现Spring AOP的基础。

具体地址:http://blog.csdn.net/yakoo5/article/details/9099133/

 

接下来我会学习装饰模式,并且会讲明两者之间的区别

 

 参考:http://www.cnblogs.com/chinajava/p/5880870.html