代理模式

一、知识点和用法案例

1.概念

代理模式简介:
代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。

作用:
中介的作用,当调用者不能或不方便调用某个对象时,代理起到中介的作用,帮助调用者间接的调用对象。

分类:
静态代理(运行前)和动态代理(运行后反射调用)

静态代理步骤:
1)代理者和被代理者都实现相同的接口
2)代理者包含被代理者的对象
3)创建代理对象时传入被代理对象
4)代理者执行方法时,会调用被代理者的方法,同时扩展新的功能

动态代理:
分类:JDK代理和CGLib动态代理

JDK代理步骤:
1) 实现InvocationHandler接口
2)实现invoke方法
3)通过Proxy.newProxyInstance方法返回代理对象

CGLib动态代理步骤:
1)引入cglib
2)实现MethodInterceptor接口
3)实现intercept方法
4)通过Ehancer返回代理对象

2.代码案例

静态代理:

package com.hp.staticproxy;

public interface CellphoneSalary {
    void sell(String brand);
}

package com.hp.staticproxy;

public interface ComputerSalary {
    void sell(String brand);
}

package com.hp.staticproxy;

public class CellphoneFactory implements CellphoneSalary{
    public void sell(String brand) {
        System.out.printf("工厂卖%s牌子手机\n",brand);
    }
}

package com.hp.staticproxy;

public class CellphoneShop implements CellphoneSalary{
    //被代理的工厂对象
    private CellphoneSalary factory;

    //创建代理者对象时传入被代理对象

    public CellphoneShop(CellphoneSalary factory) {
        this.factory = factory;
    }

    public void sell(String brand) {
        //扩展
        System.out.printf("为%s手机打广告\n",brand);
        //调用被代理者原来的功能
        factory.sell(brand);
        System.out.printf("为%s手机做售后\n",brand);
    }
}

package com.hp.staticproxy;

public class ComputerFactory implements ComputerSalary{

    public void sell(String brand) {
        System.out.printf("工厂卖%s牌子的电脑\n",brand);
    }
}

package com.hp.staticproxy;

public class ComputerShop implements ComputerSalary{
    //被代理的工厂对象
    private ComputerSalary factory;

    //创建代理者对象时传入被代理对象


    public ComputerShop(ComputerSalary factory) {
        this.factory = factory;
    }

    public void sell(String brand) {
        //扩展
        System.out.printf("为%s电脑打广告\n",brand);
        //调用被代理者原来的功能
        factory.sell(brand);
        System.out.printf("为%s电脑做售后\n",brand);
    }
}

测试:

package com.hp.staticproxy;

public class TestProxy {
    public static void main(String[] args) {
        CellphoneSalary factory = new CellphoneFactory();
        ComputerFactory factory1 = new ComputerFactory();
        ComputerSalary shop1 = new ComputerShop(factory1);
        CellphoneSalary shop = new CellphoneShop(factory);
        factory.sell("华为");
        shop.sell("华为");
        factory1.sell("华硕");
        shop1.sell("华硕");
    }
}

JDK动态代理:

package com.hp.jdknamicproxy;

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

/*
* 万能代理商
* */
public class JdkShop implements InvocationHandler {

    //定义一个被代理的对象
    private Object target;

    public Object newProxyInstance(Object target){
        this.target=target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),this);
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //功能扩展
        System.out.println("商店帮忙打广告!!");
        //调用被代理者方法
        Object invoke = method.invoke(target, args);
        System.out.println("商店帮忙做售后!!");
        return invoke;
    }
}

测试:

package com.hp.jdknamicproxy;

import com.hp.staticproxy.CellphoneFactory;
import com.hp.staticproxy.CellphoneSalary;
import com.hp.staticproxy.ComputerFactory;
import com.hp.staticproxy.ComputerSalary;

public class TestShop {
    public static void main(String[] args) {
        CellphoneSalary factory = new CellphoneFactory();
        ComputerSalary factory1 = new ComputerFactory();
        JdkShop shop = new JdkShop();
        CellphoneSalary o = (CellphoneSalary) shop.newProxyInstance(factory);
        o.sell("华为");
        ComputerSalary o1 = (ComputerSalary) shop.newProxyInstance(factory1);
        o1.sell("华硕");
    }
}

CGLib动态代理:

package com.hp.cglib;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/*
* CGlib动态代理
* */
public class CGlibProxy implements MethodInterceptor {

    //被代理对象
    private Object target;

    public Object createProxy(Object target){
        this.target=target;
        Enhancer enhancer = new Enhancer();
        //设置父类
        enhancer.setSuperclass(this.target.getClass());
        //设置方法回调MethodInterceptor实现
        enhancer.setCallback(this);
        //返回代理对象
        return enhancer.create();
    }


    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        //扩展
        System.out.println("CGLib商店打广告!");
        //调用原来方法
        Object invoke = method.invoke(target, objects);
        System.out.println("CGLib商店做售后!");
        return invoke;
    }
}

测试:

package com.hp.cglib;

import com.hp.staticproxy.CellphoneFactory;
import com.hp.staticproxy.CellphoneSalary;

public class TestCGLib {
    public static void main(String[] args) {
        CellphoneSalary factory = new CellphoneFactory();
        CGlibProxy proxy = new CGlibProxy();
        CellphoneSalary o = (CellphoneSalary) proxy.createProxy(factory);
        o.sell("华为");
    }
}

总结

以上就是代理模式相关的所有知识和用法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值