java中代理模式的简单理解

代理模式简单的讲就是创建一个代理对象,然后通过代理对象来访问目标对象,完成原来的任务。这样可以在不改变原有的代码的情况下,增加额外的功能,也就是扩展原来的目标对象的功能。

1.静态代理

在编译阶段就确定了代理目标对象,也就是专为一个类进行代理。

interface BookSell{ //代理接口

    void sellBook(int x);
}

class BookProducer implements BookSell{  //被代理类

    @Override
    public void sellBook(int x) {
        System.out.println("有"+x+"本书要卖。");
    }
}

class BookAgent implements BookSell{  //静态代理类
    private BookProducer bookProducer=new BookProducer(); //静态被代理类创建对象

    @Override
    public void sellBook(int x) {
        System.out.println("给每本书定价。");
        bookProducer.sellBook(x);
        System.out.println("计算卖了多少书及总金额。");
    }

    public void bookAdd(int s){
        System.out.println("增加了"+s+"本书");
    }
}
public class MyProxy {
    public static void main(String[] args) throws Throwable {
        //静态代理
        BookSell bookAgent = new BookAgent();
        bookAgent.sellBook(50);
        System.out.println("========================");

    }
}

2.动态代理

在运行阶段确定代理的对象,通用性更强。

  • JDK动态代理

    被代理的类需要实现代理接口,还需要一个代理处理器。

    interface BookSell{ //代理接口
    
        void sellBook(int x);
    }
    
    class BookProducer implements BookSell{  //被代理类
    
        @Override
        public void sellBook(int x) {
            System.out.println("有"+x+"本书要卖。");
        }
    }
    
    class theAgent implements InvocationHandler{  //实现InvocationHandler接口的代理处理器类
        private Object target;
    
        public theAgent(Object target) {
            this.target = target;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if (method.getName().equals("sellBook")){
                System.out.println("给每本书定价。");
                method.invoke(target, args);//使用反射执行代理对象方法
                System.out.println("计算卖了多少书及总金额。");
            }
            return null;
        }
    }
    
    public class MyProxy {
        public static void main(String[] args) throws Throwable {
            //JDK动态代理方法一
            BookProducer bookProducer = new BookProducer(); //被动态代理对象
            theAgent agentHandler = new theAgent(bookProducer); //创建代理处理器
            //构造实现指定接口的代理类的一个实例对象
            BookSell bookSell = (BookSell) Proxy.newProxyInstance(MyProxy.class.getClassLoader(), new Class[]{BookSell.class}, agentHandler);
            bookSell.sellBook(50); //代理对象实现方法
            /*实现细节
            Object invoke = agentHandler.invoke(bookProducer, BookProducer.class.getMethod("sellBook",int.class), new Integer[]{Integer.valueOf(50)});
            */
            System.out.println("=============================");
    
            //JDK动态代理方法二
            Class agentProxyClass = Proxy.getProxyClass(MyProxy.class.getClassLoader(), BookSell.class); //创建事先指定接口代理类
            BookSell bookSell1 = (BookSell) agentProxyClass.getConstructor(InvocationHandler.class).newInstance(agentHandler); //创建代理类对象
            bookSell1.sellBook(100);
            System.out.println("=======================");
    
        }
    }
    
  • CGLib动态代理

    被代理的类不需要实现代理接口,但需要实现MethodInterceptor接口,该接口需要引入cglib.jar。

    <!-- maven -->
    <dependency>
       <groupId>cglib</groupId>
       <artifactId>cglib</artifactId>
       <version>3.3.0</version>
    </dependency>
    
    class BookPrint{
        public void sellBook(int x) {
            System.out.println("有"+x+"本书要卖。");
        }
    }
    
    class BookPrintProxy implements MethodInterceptor{
        Object target;
    
        public BookPrintProxy(Object target) {
            this.target = target;
        }
    
        @Override
        public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            if (method.getName().equals("sellBook")){
                System.out.println("给每本书定价。");
                method.invoke(target, args);//使用反射执行代理对象方法
                System.out.println("计算卖了多少书及总金额。");
            }
            return null;
        }
    }
    public class MyProxy {
        public static void main(String[] args) throws Throwable {
    
            //CGLib代理模式(被代理类不需要继承接口)
            BookPrint bookPrint = new BookPrint();
            BookPrintProxy bookPrintProxy = new BookPrintProxy(bookPrint);
            BookPrint b= (BookPrint) Enhancer.create(BookPrint.class,bookPrintProxy);
            b.sellBook(200);
    
        }
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代理模式是一种结构型设计模式,它允许将对象的访问控制委托给另一个对象。在代理模式代理对象控制着原始对象的访问,并可以在原始对象的方法执行前或后添加自定义逻辑。以下是一个简单Java 代码示例,演示了如何使用代理模式: ```java // 定义一个接口 interface Image { void display(); } // 定义一个实现了 Image 接口的具体类 class RealImage implements Image { private String fileName; public RealImage(String fileName) { this.fileName = fileName; loadFromDisk(); } @Override public void display() { System.out.println("Displaying " + fileName); } private void loadFromDisk() { System.out.println("Loading " + fileName); } } // 定义一个代理类 class ProxyImage implements Image { private RealImage realImage; private String fileName; public ProxyImage(String fileName) { this.fileName = fileName; } @Override public void display() { if (realImage == null) { realImage = new RealImage(fileName); } realImage.display(); } } // 使用代理类访问实际对象 public class ProxyPatternDemo { public static void main(String[] args) { Image image = new ProxyImage("test_image.jpg"); // 在第一次访问时,会创建实际的对象并加载它 image.display(); // 在第二次访问时,不会创建实际的对象,而是直接访问代理对象 image.display(); } } ``` 在上面的示例,`Image` 是一个接口,包含 `display()` 方法。`RealImage` 是一个实现 `Image` 接口的具体类,它负责加载和显示图像。`ProxyImage` 是一个代理类,它也实现了 `Image` 接口,并在需要时创建实际的 `RealImage` 对象,以确保对其的访问受到控制。 在 `main()` 方法,我们创建了一个 `ProxyImage` 对象,并将其传递给 `Image` 接口的引用。在第一次调用 `display()` 方法时,代理类创建了实际的 `RealImage` 对象,并调用其 `display()` 方法。在第二次调用 `display()` 方法时,代理类直接调用实际对象的 `display()` 方法,而不需要再创建它。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值