静态代理和动态代理

一、静态代理

代理模式(Proxy Pattern)是一种结构型设计模式,它的概念很简单,它通过创建一个代理对象来控制对原始对象的访问。代理模式主要涉及两个角色:代理角色和真实角色。代理类负责代理真实类,为真实类提供控制访问的功能,真实类则完成具体的业务逻辑。这样,当我们不方便或者不能直接访问真实对象时,可以通过代理对象来间接访问。是一种AOP编程思想。

静态代理和动态代理_第1张图片

下面,我们以购买火车票为例,我们可以通过火车站去买票,当一些人不方便时候,可能会通过代售点买票,那么代售点其实可以理解为火车站的代理类,只不过代售点提供了火车站的服务,当然也会收取一定的服务费。

代码如下:

public class hook {
    /**
     * 售票服务接口
     */
    public interface TicketService {

        //售票
        public void sellTicket();

    }

    /**
     * 售票服务接口实现类,车站
     */
    public static class Station implements TicketService {

        @Override
        public void sellTicket() {
            System.out.println("\n\t售票.....\n");
        }
    }

    /**
     * 车票代售点
     *
     */
    public static class StationProxy implements TicketService {

        private final Station station;

        public StationProxy(Station station){
            this.station = station;
        }

        @Override
        public void sellTicket() {

            // 1.做真正业务前,提示信息
            System.out.println("××××您正在使用车票代售点进行购票,每张票将会收取5元手续费!××××");
            // 2.调用真实业务逻辑
            station.sellTicket();
            // 3.后处理  println
            System.out.println("××××欢迎您的光临,再见!××××\n");
        }
    }


    public static void main(String[] args) {
        Station changchun = new Station();

        StationProxy proxy = new StationProxy(changchun);

        proxy.sellTicket();

    }


}

通过以上的代码,还是很容易理解静态代理了,通过代理类去控制实体类的行为,并可以灵活加上之自己的行为~ 

二、动态代理

在Java中,动态代理是通过InvocationHandler接口,重写invoke函数实现的。

还是以火车站售票为例,

代码如下:

package com.tiancity.dom.lib;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class dynamic {
    /**
     * 售票服务接口
     */
    public interface TicketService {

        //售票
        public void sellTicket();

    }

    /**
     * 售票服务接口实现类,车站
     */
    public static class Station implements TicketService {

        @Override
        public void sellTicket() {
            System.out.println("\n\t售票.....\n");
        }
    }

    /**
     * 车票代售点
     *
     */
    public static class StationProxy implements InvocationHandler {

        private final TicketService station;

        public StationProxy(TicketService station){
            this.station = station;
        }

        //com.sun.proxy.$Proxy0 cannot be cast to
        //getInterfaces 获取的是接口,不是类,所以要用TicketService
        public Object getProxy(){
            return (Object) Proxy.newProxyInstance(this.getClass().getClassLoader(),
                    station.getClass().getInterfaces(),this);
        }


        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object result = null;
           if(method.getName().equals("sellTicket")){
               // 1.做真正业务前,提示信息
               System.out.println("××××您正在使用车票代售点进行购票,每张票将会收取5元手续费!××××");
               // 2.调用真实业务逻辑
               result=method.invoke(station, args);
               // 3.后处理  println
               System.out.println("××××欢迎您的光临,再见!××××\n");
           }
            return result;
        }
    }


    public static void main(String[] args) {
        TicketService dalian = new Station();

        StationProxy proxy = new StationProxy(dalian);

        TicketService p = (TicketService) proxy.getProxy();

        p.sellTicket();

    }

}

三、总结

代理模式可以在不修改真实类代码的情况下,实现对真实类的访问控制、性能优化等功能。Java 中有两种实现代理模式的方法:静态代理和动态代理。静态代理需要在编译之前手动编写代理类,而动态代理可以在运行时动态生成代理类。

你可能感兴趣的:(Java基础,java,开发语言)