署理模式

  • 作用:在不改变原有代码的基础上,增添或扩展分外的功效
  • 静态署理
//1,被署理类需要实现的接口,署理类也要实现该接口,该接口对用户使用
interface FlightMachine{
    void fly();
}
//2,被署理类实现接口
class FlightMachineImpl implements FlightMachine{

    @Override
    public void fly() {
        System.out.println("我可以飞");
    }
}
//3,署理类实现接口
class FlightProxy implements FlightMachine{
    //4,署理类引用被署理工具
    private FlightMachine flightMachine;

    //5,写有参组织方式获得被署理工具实例
    public FlightProxy(FlightMachine flightMachine){
        super();
        this.flightMachine=flightMachine;
    }

    @Override
    public void fly() {
        //增添分外的功效
        System.out.println("我可以发射导弹");
        flightMachine.fly();
        //增添分外的功效
        System.out.println("我可以航拍");
    }
}
public class TestProxy {
    public static void main(String[] args) {
        FlightMachine flightMachine = new FlightMachineImpl();
        FlightMachine flightProxy = new FlightProxy(flightMachine);
        flightProxy.fly();
    }
}

console:
我可以发射导弹
我可以飞
我可以航拍

小结:署理类和被署理类都需要实现同一个接口,且署理类预先设定,造成服务单一,要是其他类需要署理则需要更多署理类,不易扩展,瑕玷对照显著,适用场景不广。

  • 动态署理
    • JDK署理
      • 使用JDK自带的署理类,制造署理工厂
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//1,被署理类实现的接口
interface FlightMachine{
    void fly();
}
//2,被署理类需要至少实现的一个接口
class FlightMachineImpl implements FlightMachine{
    @Override
    public void fly() {
        System.out.println("我可以飞");
    }
}
//3,确立动态署理的工厂类,用来动态天生署理类工具
class FlightProxyFactory{
    //4,需要引用被署理的工具
    private Object target;

    //5,写有参组织方式获得署理目的实例
    public FlightProxyFactory(Object target) {
        this.target = target;
    }

    //6,提供一个获取署理类工具的方式
    public Object getProxyInstance(){
        //用JDK自带的reflect包的Proxy确立署理类实例
        /*
        @Proxy.newProxyInstance(Param1,Param2,Param3){ }
        参数1:类加载器,一样平常一个项目只有一个类加载器,以是选取对照利便获取的类来getClassLoader()就行
        参数2:署理目的所实现的所有接口,通过.getClass().getInterfaces()获得
        参数3:方式挪用处理器
         */
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(), new InvocationHandler() {
                    /*
                    invoke(Param1,Param2,Param3){  }
                    参数1:署理类工具
                    参数2:被署理类(署理目的)需要执行的方式
                    参数3:执行方式需要的参数
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //增添分外的功效
                        System.out.println("我可以发射导弹");
                        //通过反射来挪用署理目的方式
                        Object procedure = method.invoke(target, args);
                        //增添分外的功效
                        System.out.println("我可以航拍");
                        return procedure;
                    }
                });
    }

}

public class TestProxy {
    public static void main(String[] args) {
        FlightMachine flightMachine = new FlightMachineImpl();
        FlightProxyFactory flightProxyFactory = new FlightProxyFactory(flightMachine);
        Object proxyInstance = flightProxyFactory.getProxyInstance();
        if (proxyInstance instanceof FlightMachine){
            FlightMachine machineProxy = (FlightMachine) proxyInstance;
            machineProxy.fly();
        }
    }
}
console:
我可以发射导弹
我可以飞
我可以航拍

小结:确立署理工厂,凭据需要的类动态天生署理类,虽然署理目的不牢固,然则需要实现至少一个接口,不是所有的类都实现了接口或者继续了某个类,以是还不够好,然则JDK署理在反射天生署理类方面是作用较好,和其他动态署理方式配合使用效果更好。

  • CGLIB署理
    • 使用第三方署理包,cglib和asm两个包需要引入,焦点接口是MethodInterceptor,焦点类是Enhancer,给被署理类动态天生一个子类来举行署理(子类对父类来说就相当于扩展了功效)
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;


//1,被署理类
class FlightMachineImpl {
    public void fly() {
        System.out.println("我可以飞");
    }
}
//2,确立cglib动态署理的工厂类,用来动态天生署理类、署理类工具,并实现MethodInterceptor接口
class CglibProxyInterceptor implements MethodInterceptor {
    //3,引用署理目的的工具
    private Object target;

    //4,写有参组织方式获得署理目的实例
    public CglibProxyInterceptor(Object target) {
        this.target = target;
    }

    //5,提供一个获取署理类工具的方式
    public Object getProxyInstance(){
        //6,用cglib包的Enhancer确立署理类,且该署理类需要继续署理目的成为其子类
        Enhancer enhancer = new Enhancer();
        //7,将署理目的设置为署理类的父类
        enhancer.setSuperclass(target.getClass());
        //8,设置回调函数
        enhancer.setCallback(this);
        //9,确立署理类工具
        return enhancer.create();
    }
    //6,实现intercept方式
    /*
        @intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy){ }
        参数1 o:被署理的工具
        参数2 method:署理工具的方式,这里是FlightMachineImpl的fly()方式
        参数3 objects:方式的参数
        参数4 methodProxy:方式署理,这里署理的是cglib署理的fly()方式
         */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("我可以发射导弹");
        Object result = method.invoke(target, objects);
        System.out.println("我可以航拍");
        //methodProxy的invokeSuper可以实现相同的效果
//        Object result = methodProxy.invokeSuper(o, objects);
        return result;
    }
}

public class TestProxy {
    public static void main(String[] args) {
        CglibProxyInterceptor cglibProxyInterceptor = new CglibProxyInterceptor(new FlightMachineImpl());
        Object proxyInstance = cglibProxyInterceptor.getProxyInstance();
        if (proxyInstance instanceof FlightMachineImpl){
            FlightMachineImpl flightMachine = (FlightMachineImpl) proxyInstance;
            flightMachine.fly();
        }
    }
}
console:
我可以发射导弹
我可以飞
我可以航拍

小结:使用cglib署理,署理目的不用实现接口或继续类,只需凭据该被署理类天生子类作为其署理类完成署理,和JDK署理一起在spring aop中使用普遍。

至此,若有纰漏,望列位不吝赐教

,

www.allbetgaming.net

欢迎进入欧博平台网站(www.aLLbetgame.us),www.aLLbetgame.us开放欧博平台网址、欧博注册、欧博APP下载、欧博客户端下载、欧博游戏等业务。

Allbet Gaming声明:该文看法仅代表作者自己,与阳光在线无关。转载请注明:allbet官网官方注册:设计模式之署理模式
发布评论

分享到:

宁波兼职:皮克看衰戴维斯杯远景:空场办赛很难 仍在等通知
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。