设计模式-动态代理

 

通过代理模式 ,代理类可以在被代理类的基础上做前置和后置的操作。---- 代理类就好比 房产中介或者代购,买方只要通过中介,就可以购买到房子或者想要的东西。中介提供 售前和售后的服务。

静态代理

通过封装被代理的类的方法,在方法前后增加增强的代码。缺点是,每次扩展一个方法 ,都需要修改代理类。

例如

public class Lison {
    
    AaFactory aaFactory = new AaFactory();
    BbFactory bbFactory = new BbFactory();
    
    public void getManToolsFactroy(){
        System.out.println("我是getManToolsFactroy方法前置增强");
        aaFactory.saleManTools(20);
        System.out.println("我是getManToolsFactroy方法后置增强");
    }
    public void getWomanToolsFactroy(){
        System.out.println("我是getWomanToolsFactroy方法前置增强");
        bbFactory.saleWomanTools(20);
        System.out.println("我是getWomanToolsFactroy方法后置增强");
    }
  //...... }

 又或者

public class Lison2 implements ManToolsFactory,WomanToolsFactory {
    
    public ManToolsFactory factory = new AaFactory();
    public WomanToolsFactory wFactory  = new BbFactory();
    
    public Lison2() {
    }
    
    @Override
    public void saleManTools(int size) {
        System.out.println("我是saleManTools方法前置增强");
        factory.saleManTools(20);
        System.out.println("我是saleManTools方法后置增强");
    }
    @Override
    public void saleWomanTools(int size) {
        // TODO Auto-generated method stub
        System.out.println("我是saleWomanTools方法前置增强");
        wFactory.saleWomanTools(20);
        System.out.println("我是saleWomanTools方法后置增强");
    }
}

这两种方法区别不大,一个是通过自己新增方法,实现代理其他类。一个是通过实现接口的方法

动态代理

符合开闭原则,只要扩展被代理类的接口和实现类,然后直接 动态 提供代理服务

这是代理类

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

public class LisonCompany1 implements InvocationHandler {
    
    //被代理的对象
    Object factory;
    public Object getFactory() {
        return factory;
    }
    public void setFactory(Object factory) {
        this.factory = factory;
    }
    //获取动态代理对象实例
    //,调度员工
    //通过Proxy 获取动态代理的对象
    //第一个参数,类加载器。因为factory和 LisonCompany 是在同一个类里面,所以就用factory.getClass().getClassLoader()
    //第二个参数,指定的接口
    public Object getProxyInstance(){
        return Proxy.newProxyInstance(factory.getClass().getClassLoader(), factory.getClass().getInterfaces(), this);
    }
    
    public LisonCompany1() {
    }
    public LisonCompany1( Object factory) {
        this.factory = factory;
    }
    @Override
    //通过代理对象,将方法争强
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("前置增强,售前服务,市场调研");
        Object ret = method.invoke(factory, args);
        System.out.println("后置增强,精美包装");
        return ret;
    }
}

 这是被代理的接口:

public interface ManToolsFactory {
    
    void saleManTools(int size);

}

 这是被代理的实现类:

public class AaFactory implements ManToolsFactory {

    @Override
    public void saleManTools(int size) {
        System.out.println("定制size="+size+"女模特");
    }

}

 这是测试的main方法

import test.designpatterns.proxy.dynamic.LisonCompany1;
import test.designpatterns.proxy.staticc.AaFactory;
import test.designpatterns.proxy.staticc.BbFactory;
import test.designpatterns.proxy.staticc.Lison;
import test.designpatterns.proxy.staticc.Lison2;
import test.designpatterns.proxy.staticc.ManToolsFactory;
import test.designpatterns.proxy.staticc.WomanToolsFactory;
import test.designpatterns.proxy.util.ProxyUtil;

public class Client  {
    public static void main(String[] args) {
        
        System.out.println("-----------------------------静态代理1");
        //每次增加需求,不仅需要增加某工厂类,例如化妆品工厂类,Lison对象需要做修改,违背了 面向对象设计原则(单一职责原则),和下面静态代理2一样的问题
        //静态代理不符合开闭原则
        Lison lison = new Lison();
        lison.getManToolsFactroy();
        lison.getWomanToolsFactroy();
        System.out.println("-----------------------------静态代理2");
        Lison2 lison2 = new Lison2();
        lison2.saleManTools(100);
        lison2.saleWomanTools(200);
        
        System.out.println("-----------------------------动态代理");
        ManToolsFactory aFactory = new AaFactory();
        WomanToolsFactory bFactory = new BbFactory();
        //LisonCompany对象不用修改,直接增加Factory类 用动态代理Proxy就可以或者对应的方法
        LisonCompany1 lisonCompany = new LisonCompany1();
        lisonCompany.setFactory(aFactory);
        LisonCompany1 lisonCompany2 = new LisonCompany1();
        lisonCompany2.setFactory(bFactory);
        //委派一号员工
        ManToolsFactory lison0 = (ManToolsFactory) lisonCompany.getProxyInstance();
        WomanToolsFactory lison1 = (WomanToolsFactory) lisonCompany2.getProxyInstance();
        lison0.saleManTools(60);
        lison1.saleWomanTools(40);
        
        ProxyUtil.generateClassFile(aFactory.getClass(), lison0.getClass().getSimpleName());
        
        
    }

}

控制台打印的输出:

-----------------------------静态代理1
我是getManToolsFactroy方法前置增强
定制size=20女模特
我是getManToolsFactroy方法后置增强
我是getWomanToolsFactroy方法前置增强
定制size=20男模特
我是getWomanToolsFactroy方法后置增强
-----------------------------静态代理2
我是saleManTools方法前置增强
定制size=20女模特
我是saleManTools方法后置增强
我是saleWomanTools方法前置增强
定制size=20男模特
我是saleWomanTools方法后置增强
-----------------------------动态代理
前置增强,售前服务,市场调研
定制size=60女模特
后置增强,精美包装
前置增强,售前服务,市场调研
定制size=40男模特
后置增强,精美包装

 

posted @ 2019-10-23 11:10  wullll  阅读(255)  评论(0编辑  收藏  举报