性冷淡风小结常用设计模式(八)------代理模式

1. 几种常见的代理模式

代理模式定义:为其他对象提供一种代理以控制这个对象的访问。

代理模式结构:

    Subject:抽象主题类,声明真实主题与代理的共同接口方法。
    RealSubject:真实主题类,定义了代理所表示的真实对象,客户端通过代理类间接的调用真实主题类的方法。
    ProxySubject:代理类,持有对真实主题类的引用,在其所实现的接口方法中调用真实主题类中相应的接口方法执行。
    Client:客户端类。

代理模式分类:

  1. 静态代理:在代码运行前就已经存在了代理类的class编译文件。
  2. 动态代理:动态代理则是在代码运行时通过反射来动态的生成代理类的对象,并确定到底来代理谁。
  3.  Cglib代理:Cglib代理,也叫作子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能的扩展.

2.静态代理模式
场景:订外卖(不自己买外卖,让同事帮忙订外卖)

订外卖接口( Subject:抽象主题类)

public interface ITakeaway {
    //订外卖
    void order();
}

代理类(ProxySubject:代理类)

public class OrderProxy implements ITakeaway {
    private ITakeaway mTake;
    public OrderProxy (ITakeaway take){
        mTake=take;
    }

    @Override
    public void order() {
        mTake.order();
    }
}

被代理类( RealSubject:真实主题类)

public class Author implements ITakeaway {
    @Override
    public void order() {
        System.out.println("订外卖");
    }
}

调用类( Client:客户端类)

public class Test {
    public static void main(String[] args){
        //创建author
        ITakeaway author=new Author ();
        //创建代购者并将author作为构造函数传参
        ITakeaway ordering=new OrderProxy (author);
        ordering.buy();
    }
}

小结:代理类包含了被代理类,最终调用的都是被代理类实现的方法

3.动态代理模式
Java提供了动态的代理接口InvocationHandler,实现该接口需要重写invoke()方法。

动态代理类

public class DynamicOrdering implements InvocationHandler{
    private Object obj;
    public DynamicOrdering (Object obj){
        this.obj=obj;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result=method.invoke(obj, args);
        return result;
    }
}

调用类

public class Test {
    public static void main(String[] args){
        //创建author
        ITakeaway author=new Author ();
        //创建动态代理
        DynamicOrdering mDynamicOrdering=new mDynamicOrdering(author);
        //创建Author的ClassLoader
        ClassLoader loader=author.getClass().getClassLoader();
        //动态创建代理类
        ITakeaway ordering= (ITakeaway ) Proxy.newProxyInstance(loader,new Class[]{ITakeaway .class},mDynamicOrdering);
        ordering.buy();
    }
}

4.cglib代理模式

为何使用cglib: JDK的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口,如果想代理没有实现接口的类,就可以使用Cglib实现。Cglib包的底层是通过使用一个小而块的字节码处理框架ASM来转换字节码并生成新的类。

Cglib子类代理实现的注意事项: 代理的类不能为final,否则报错

代码场景:使用cglib模拟spring的AOP事务管理

被代理类( RealSubject:真实主题类)

public class PayDao {

    public void savePayRecord() {
        System.out.println("----支付成功,已经保存数据!----");
    }
}

Cglib代理工厂:ProxyFactory.java(动态代理类:ProxySubject)

public class ProxyFactory implements MethodInterceptor{
    //维护目标对象
    private Object target;

    public ProxyFactory(Object target) {
        this.target = target;
    }

    //给目标对象创建一个代理对象
    public Object getProxyInstance(){
        //1.工具类
        Enhancer en = new Enhancer();
        //2.设置父类
        en.setSuperclass(target.getClass());
        //3.设置回调函数
        en.setCallback(this);
        //4.创建子类(代理对象)
        return en.create();
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("开始事务...");
        //执行目标对象的方法
        Object returnValue = method.invoke(target, args);
        System.out.println("提交事务...");
        return returnValue;
    }
}

测试类(客户端类:Client)

public class App {

    @Test
    public void test(){
        //目标对象
        PayDao target = new PayDao ();

        //代理对象
        PayDao proxy = (PayDao )new ProxyFactory(target).getProxyInstance();

        //执行代理对象的方法
        proxy.savePayRecord();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值