java实现三种代理

版权声明:本文为博主原创文章,未经博主允许不得转载。有问题可以留言或者邮箱shusheng52@126邮箱联系 https://blog.csdn.net/xiaoshusheng10/article/details/86492387

设计模式—代理模式java实现

  • 概念解释:

       代理是一种设计模式,提供了对目标对象另外的访问方式,即通过代理对象访问目标对象。可以不修改目标对象,对目标对象功能进行拓展

  • 代理模式的实现:

       代理模式的实现分为两大类:静态实现和动态实现,动态实现根据实现的方式分为:jdk 动态实现,cglib动态实现

 

  • 静态实现:
  •        组成部分:

              代理目标接口:定义代理类和目标实现类的基本模板,代理类和目标实现类都要实现这个接口

              目标对象: 实现代理目标接口的实现类

              代理类: 持有目标对象,根据不同的策略选择不同的方法调用目标对象的方法。

静态代理的优缺点:

       优点: 做到不修改目标对象的功能前提下,对目标功能扩展

       缺点: 因为代理对象需要与目标对象实现同样的接口,所以会有很多代理类,目标类,同时修改接口,目标类和代理类都要维护。

实现:

       代理目标接口:           

   public interface Person {

                  void say();

}

实现类:            

  public class LiudeHua implements Person {

             public void say() {

            System.out.println("hello,I`m 刘德华");

             }

}

 

实现类2:

       public class ZhangSan implements Person {

    public void say() {

        System.out.println("hello,I`m zhangSan");

    }

}

              工具类:虽然不是必须的,但是为了体现拓展性,所以还是要:                  

   public class MonitorUtil {

                  private static ThreadLocal<Long> threadLocal = new ThreadLocal<Long>();

                  public static  void  start(){

        System.out.println("开始调用" +System.currentTimeMillis());

        threadLocal.set(System.currentTimeMillis());

    }
 public static void finish(String methodName){

        System.out.println("调用结束" +System.currentTimeMillis());

        System.out.println(methodName + "方法耗时" + (System.currentTimeMillis() - threadLocal.get()) + "ms");

    }

}


    

 

       代理类:       

       public class PersonProxy implements Person {

    Person  liuDeHua  = new LiudeHua();

    Person  zhangSan = new ZhangSan();

    public void say() {

    }

   

public void say(String name){

        MonitorUtil.start();

        if("zhangsan".equals(name)){

            zhangSan.say();

        }else if("liudehua".equals(name)){

            liuDeHua.say();

        }

        MonitorUtil.finish(name);

}

 

方法调用:      

public static void main(String args[]){

        PersonProxy proxy = new PersonProxy();

        proxy.say("zhangsan");

        proxy.say("liudehua");

    }

 

 

结果:

      

 

 

Jdk动态代理:

       组成部分:

  1. 目标类接口
  2. 目标实现类
  3. Java.lang.reflect.Proxy类的Object newProxyInstance(ClassLoader loader,               Class<?>[] interfaces,                                        InvocationHandler h)
  4. InvocationHandler接口的实现类:实现调用目标类的扩展逻辑

JDK动态代理的优缺点:

              优点:动态实现了不改变目标对象逻辑的扩展

              缺点:目标必须实现接口,不然无法实现动态代理

Java代码实现:

       目标接口:          

    public interface Person {

    void say(String word);

}

       实现类:

              实现类1:                    

 public class Student implements Person {

    public void say(String word) {

        System.out.println("我是学生"+word);

        System.out.println("我是学生"+word);

        System.out.println("我是学生"+word);

    }

}

       实现类2:             

public class Teacher implements Person {

    public void say(String word) {

        System.out.println(word);

        System.out.println(word);

        System.out.println(word);

    }

}

 

InvocationHandler接口实现      

 public class ProxyInvocationHandler implements InvocationHandler {

    private Object target;

    public ProxyInvocationHandler(Object target){

        this.target = target;

    }

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

        MonitorUtil.start();

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

        MonitorUtil.finish(target.getClass().getName());

        return resultValue;

}

              Main类调用:

                    

public class Main {

    public  static void main(String args []){

        Person statudent = new Student();

        Person tearcher = new Teacher();

        InvocationHandler statudentInvocation = new ProxyInvocationHandler(statudent);

        InvocationHandler tearcherInvocation = new ProxyInvocationHandler(tearcher);

        Person studentProxy = (Person) Proxy.newProxyInstance(statudent.getClass().getClassLoader(),statudent.getClass().getInterfaces(),statudentInvocation);

        Person TearcherProxy = (Person) Proxy.newProxyInstance(tearcher.getClass().getClassLoader(),tearcher.getClass().getInterfaces(),tearcherInvocation);

        studentProxy.say("我要好好学习");

        TearcherProxy.say("我要带好学生");

    }

}

 

实现结果:

             

 

 

 

Cglib实现代理

              组成部分:

                     实现类:实现具体目标的逻辑

                     代理类:实现MethodInterceptor接口,扩展逻辑实现

                     Enhancer  设置代理类,并且生成代理对象,

            优点:

                     实现了不适用接口就可以实现动态代理

              缺点:  实现类没有统一的限定格式

       Java代码实现:

              目标类:       

       public class Student {

    public void say(){

        System.out.println("哈喽");

    }

}

 

代理类:          

    public class ProxyFactory implements MethodInterceptor {

    private Object target;



    public ProxyFactory(Object target) {

        this.target = target;

    }

 public Object getInstance(){

        Enhancer en = new Enhancer();

        en.setSuperclass(target.getClass());

        en.setCallback(this);

        return en.create();

    }



    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

        MonitorUtil.start();

        Object object = method.invoke(target,objects);

        MonitorUtil.finish("intercept");

        return object;

    }

}

   

 

 

 

启动类:public class Main {   

public static void main(String args []) {

        Student target = new Student();

        Student proxy = (Student) new ProxyFactory(target).getInstance();

        proxy.say();

    }

}

结果:

      

      

 

 

 

三种方法类的思维导图:

      

猜你喜欢

转载自blog.csdn.net/xiaoshusheng10/article/details/86492387