浅谈JAVA动态代理

1.静态代理

public class StaticProxy {
    public static void main(String[] args) {
        //我们无法直接使用被代理对象,只能使用代理对象 
        //使用代理对象一样可以实现 被代理对象的功能 不过还会额外的增加代理对象的功能
        YellowCattle yellowCattle = new YellowCattle();
        yellowCattle.salePhone();
    }
}


//目标对象(被代理对象)
class PhoneFactory implements Phone {
    public int salePhone() {
        int price = 200;
        System.out.println("手机价格是" + price);
        return price;
    }
}

//代理对象
class YellowCattle extends PhoneFactory implements Phone {
    //这里想调用 被代理对象 有许多方法,不仅仅可以通过继承,也可以把 被代理对象 当成成员属性 关联进来
    @Override
    public int salePhone() {
        //调用目标对象 实现基本功能
        int newPrice = super.salePhone();
        //自己增强的功能
        newPrice += 500;
        System.out.println("黄牛哥哥加价之后" + newPrice);
        return newPrice;
    }
}

//只是编写规范,没有特殊意义
interface Phone {
    int salePhone();
}
#######
控制台打印
手机价格是200
黄牛哥哥加价之后700
#######

从上面简单的demo可以感受到,当我们想为一个功能增强,但是又不可以直接在上面修改代码时,就可以使用代理模式去实现。做到代码的相对解耦,既不会影响被代理对象的逻辑,还可以 增加自己额外的功能。但是弊端也非常的明显。如果我现在要对一个新的对象进行代理,那么代理对象也要创建一个全新的进行匹配。比如我有一个卖手机的目标对象,就需要一个卖手机的代理对象,有一个卖橘子的就需要在来一个卖橘子的代理对象。当需要代理的对象很庞时,就会出现代码冗余难以维护,于是动态代理就诞生了。

2.动态代理

动态代理有两种实现方式,第一个是基于java的动态代理,他要求必须有接口才可以实现。第二个是基于cglib的动态代理,他是基于继承实现的,这里先聊聊java的动态代理。
前面我们已经了解到了,静态代理会出现一个问题,就是被代理对象需要一对一的绑定一个代理对象。并且当需要代理的功能发生变化,被代理对象以及代理对象都要修改相关代码,十分难以维护。那么我们的想法就是,可不可以动态的告诉我你需要代理的是那个对象,以及需要代理的是那个方法,我们通过反射来调用呢?于是基于前面的静态代理我们做出调整。

public class DynamicProxy {
    public static void main(String[] args) {
        //调用者核心代码
        //1.首先要有被代理对象
        IPhoneSale target = new Target();
        //2.其次需要代理对象 并将被代理对象传入代理对象
        MyProxy myProxy = new MyProxy(target);
        //3.核心代码 必须这样写
        // 参数1是  被代理对象的类加载器  参数二是 被代理对象实现的接口信息 参数三是 代理对象
        IPhoneSale proxyTarget = (IPhoneSale)Proxy.newProxyInstance(
        target.getClass().getClassLoader(), 
        target.getClass().getInterfaces(),
        myProxy);
        //这里调用salePhone反法时,调用的是  代理对象中的invoke方法 从而实现功能增强
        int sale = proxyTarget.salePhone();
        System.out.println(sale);
    }
}

//jdk的动态必须有接口
interface IPhoneSale{
    int salePhone();
}
//被代理对象(目标对象)
class Target implements  IPhoneSale{
    @Override
    public int salePhone() {
        System.out.println("我是目标方法");
        return 100;
    }
}

//代理对象必须实现这个接口
class MyProxy implements InvocationHandler{

    //被代理对象声明为成员属性 依靠调用者动态传入
    Object target = null;
    public MyProxy(Object target){
        this.target = target;
    }

   @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //核心代码  利用反射会调用目标对象的方法 具体调用那个 是由调用者发起的
        Object invoke = method.invoke(target, args);
        //增强代码
        System.out.println("我是代理对象,我要涨价100!");
        if (invoke != null) {
            Integer sale = (Integer) invoke + 100;
            return sale;
        }
        return null;
    }
}
########
控制台打印:
我是目标方法
我是代理对象,我要涨价100200
########

动态代理可以实现代码的解耦,增强灵活度。比如我现在接口中需要代理一个新的方法,那么只需要修改被代理对象的实现以及调用者调用的方法即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java的BorderLayout是一种常用的布局管理器,它将容器分为5个区域:北、南、东、西和间。在使用BorderLayout时,我们可以通过设置组件的位置来确定它们在容器的位置。 下面是一个简单的例子,演示如何使用BorderLayout: ``` import java.awt.BorderLayout; import javax.swing.JButton; import javax.swing.JFrame; public class BorderLayoutExample { public static void main(String[] args) { JFrame frame = new JFrame("BorderLayout Example"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JButton button1 = new JButton("North"); JButton button2 = new JButton("South"); JButton button3 = new JButton("East"); JButton button4 = new JButton("West"); JButton button5 = new JButton("Center"); frame.add(button1, BorderLayout.NORTH); frame.add(button2, BorderLayout.SOUTH); frame.add(button3, BorderLayout.EAST); frame.add(button4, BorderLayout.WEST); frame.add(button5, BorderLayout.CENTER); frame.pack(); frame.setVisible(true); } } ``` 在这个例子,我们创建了一个JFrame,并在其添加了5个JButton。使用BorderLayout将它们放置在窗口的不同位置。在上面的代码,我们将button1放置在北面,button2放置在南面,button3放置在东面,button4放置在西面,button5放置在心。 需要注意的是,当我们在使用BorderLayout时,如果某个位置没有被占用,那么它将自动被设置为空。另外,如果我们在同一个位置添加了多个组件,那么后添加的组件将覆盖先添加的组件。 总之,BorderLayout是一个非常常用的布局管理器,可以帮助我们轻松地将组件放置在容器的不同位置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值