Spring——Proxy代理模式详解

有时候,不是因为你没有能力,也不是因为你缺少勇气,只是因为你付出的努力还太少,所以,成功便不会走向你。而你所需要做的,就是坚定你的梦想,你的目标,你的未来,然后以不达目的誓不罢休的那股劲,去付出你的努力,成功就会慢慢向你靠近。

导读:本篇文章讲解 Spring——Proxy代理模式详解,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

Spring-代理模式

学习视频:

B站 狂神说Java之Spring5教程:https://www.bilibili.com/video/BV1WE411d7Dv

代理模式

  1. 定义

    为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

  2. 组成:

    • 抽象角色:通过接口或抽象类声明真实角色实现的业务方法。
    • 代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
    • 真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用
  3. 代理模式类别

    • 静态代理
    • 动态代理

静态代理

静态代理:由程序员创建或特定工具自动生成源代码,也就是在编译时就已经将接口、被代理类、代理类等确定下来。在程序运行之前,代理类的.class文件就已经生成。

租房实例:

  1. Rent.java

    //抽象角色:租房
    public interface Rent {
        public void rent();
    }
    
  2. HouseMaster.java

    //真是角色,房主
    public class HouseMaster implements Rent{
        @Override
        public void rent() {
            System.out.println("房东:我要出租房屋");
        }
    }
    
  3. ProxyRent.java

    //代理角色:中介
    public class ProxyRent {
        private HouseMaster houseMaster;
    
        public ProxyRent(){
        }
        public ProxyRent(HouseMaster houseMaster){
            this.houseMaster = houseMaster;
        }
    
        //租房
        public void rent(){
            houseMaster.rent();
            watch();
            contract();
            getFee();
        }
    
        //看房
        public void watch(){
            System.out.println("看房");
        }
    
        //签合同
        public void contract(){
            System.out.println("签合同");
        }
    
        //收取中介费
        public void getFee(){
            System.out.println("交易成功,收取中介费");
        }
    }
    
  4. Client.java

    //客户类
    public class Client {
        public static void main(String[] args) {
            //房东出租房
            HouseMaster houseMaster = new HouseMaster();
            //中介代理房东去出租房子
            ProxyRent proxy = new ProxyRent(houseMaster);
            //客户找中介租房
            proxy.rent();
        }
    }
    
  5. 结果

在这里插入图片描述


静态代理的好处:

  • 可以使得我们的真实角色更加纯粹 . 不再去关注一些公共的事情 .
  • 公共的业务由代理来完成 . 实现了业务的分工 ,
  • 公共业务发生扩展时变得更加集中和方便 .

缺点 :

  • 类多了 , 多了代理类 , 工作量变大了 ,开发效率降低 .

我们想要静态代理的好处,又不想要静态代理的缺点,所以 , 就有了动态代理

动态代理

代理类在程序运行时创建的代理方式被成为动态代理。

  • 动态代理的角色和静态代理的相同

  • 动态代理的代理类是动态生成的 , 静态代理的代理类是我们提前写好的

  • 动态代理分为两类 : 一类是基于接口动态代理 , 一类是基于类的动态代理

    • 基于接口的动态代理—-JDK动态代理【主要使用】

    • 基于类的动态代理–CGLIB

JDK动态代理(基于反射实现):通过InvocationHandler接口和Proxy类生成JDK动态代理类和动态代理对象。

实例:

  1. Rent.java

    public interface Rent {
        public void rent();
    }
    
  2. HouseMaster.java

    public class HouseMaster implements Rent {
        @Override
        public void rent() {
            System.out.println("房东:我要出租房屋");
        }
    }
    
  3. ProxyInvocationHandler.java

    public class ProxyInvocationHandler implements InvocationHandler {
        //被代理的接口
        private Rent rent;
    
        public void setRent(Rent rent) {
            this.rent = rent;
        }
    
        //生成得到的代理类
        public Object getProxy(){
            return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(), this);
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object result = method.invoke(rent, args);
            watch();
            fee();
            return result;
        }
    
        public void watch(){
            System.out.println("中介带租客看房");
        }
    
        public void fee(){
            System.out.println("中介收取中介费");
        }
    }
    
  4. Client.java

    public class Client {
        public static void main(String[] args) {
            //真实角色
            HouseMaster houseMaster = new HouseMaster();
    
            //代理角色:需要创建
            ProxyInvocationHandler pih = new ProxyInvocationHandler();
            //将真实角色放置进去
            pih.setRent(houseMaster);
            //动态生产代理类
            Rent proxy = (Rent) pih.getProxy();
    		
            proxy.rent();
        }
    }
    
  5. 测试结果

在这里插入图片描述


业务实例:

  1. UserService.java

    public interface UserService {
        public void add();
        public void delete();
        public void update();
        public void query();
    }
    
  2. UserServiceImpl.java

    public class UserServiceImpl implements UserService {
        @Override
        public void add() {
            System.out.println("使用了add方法");
        }
    
        @Override
        public void delete() {
            System.out.println("使用了delete方法");
        }
    
        @Override
        public void update() {
            System.out.println("使用了update方法");
        }
    
        @Override
        public void query() {
            System.out.println("使用了query方法");
        }
    }
    
  3. ProxyInvocationHandler.java

    public class ProxyInvocationHandler implements InvocationHandler {
        private Object target;
    
        public void setTarget(Object target) {
            this.target = target;
        }
    
        //生产代理类
        public Object getProxy(){
            return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces() ,this);
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            log(method.getName());
            Object result = method.invoke(target, args);
            return result;
        }
    
        public void log(String str){
            System.out.println("调用了"+str+"方法");
        }
    }
    
  4. Client.java

    public class Client {
        public static void main(String[] args) {
            //真实角色
            UserServiceImpl userService = new UserServiceImpl();
            //代理对象的调用处理程序
            ProxyInvocationHandler pih = new ProxyInvocationHandler();
            //需要代理真实角色
            pih.setTarget(userService);
            //生产代理类
            UserService proxy = (UserService) pih.getProxy();
    
            proxy.add();
    //        proxy.delete();
    //        proxy.update();
    //        proxy.query();
        }
    }
    
  5. 测试结果

在这里插入图片描述


动态代理的好处

  • 可以使得我们的真实角色更加纯粹,不再去关注一些公共的事情
  • 公共的业务由代理来完成,实现了业务的分工
  • 公共业务发生扩展时变得更加集中和方便
  • 一个动态代理 , 一般代理某一类业务
  • 一个动态代理可以代理多个类,代理的是接口

知识点补充:

Method类方法功能:

  • invoke():实现对方法的动态调用

  • getName():返回方法对象的名称

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/147370.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!