面试问到AOP就该这样回答-阿里云开发者社区

开发者社区> 开发与运维> 正文

面试问到AOP就该这样回答

简介: 相信各位小伙伴在准备面试的时候,AOP都是无法绕过的一个点,经常能看到动态代理、JDK动态代理、CGLIB动态代理这样的字眼。其实动态代理是代理模式的一种。代理模式有静态代理、强制代理、动态代理。所以在认识AOP之前需要了解代理模式。

前言

  相信各位小伙伴在准备面试的时候,AOP都是无法绕过的一个点,经常能看到动态代理、JDK动态代理、CGLIB动态代理这样的字眼。其实动态代理是代理模式的一种。代理模式有静态代理、强制代理、动态代理。所以在认识AOP之前需要了解代理模式。

代理模式定义

  代理模式(Proxy Pattern):为其他对象提供一种代理以控制这个对象的访问。

  • Subject抽象主题角色,也叫做抽象主题类。可以是抽象类也可以是接口,是一个最普通的业务类型定义,无特殊要求。
  • RealSubject具体主题角色,也叫做被委托角色,被代理角色,是业务逻辑的具体执行者。
  • Proxy代理主题角色,也叫做委托类、代理类。他负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并且在真实主题角色处理完毕前后做到预处理和善后工作。

代理模式的优点

  • 职责清晰
  • 高扩展性
  • 智能化

UML

image

我的理解

  跳板机不管是对于运维老哥还是对于我们来讲,都是日常的工作中不可或缺的一个工具。为了保证生产服务器的安全,我们是无法通过xshell等工具直接进行连接的。如果需要操作生产的服务器,则需要通过跳板机。并且跳板机还能记录我们的操作,用来做安全审计。防止出现,某位老哥一气之下反手就是个sudo rm -rf /*直接凉凉。


  我们回过头看看代理模式的定义:为其他对象提供一种代理以控制这个对象的访问。实际上跳板机就是生产服务器的一个代理Proxy,为了实现控制生产服务器的访问权限。你需要通过跳板机来操作生产服务器。

  • 为其他对象提供一种代理以控制这个对象的访问
  • 给你提供一个跳板机来访问生产服务器,目的是来控制生产服务器的访问

  Proxy的职责:Proxy是对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现。并且在真实主题角色处理完毕前后做到预处理善后工作。你通过操作跳板机。跳板机将你输入的命令在生产服务器上进行执行。并且能记录下执行的命令和执行的结果。

代码演示

Server

public interface Server {

    /**
     * 执行
     * @param command 命令
     */
    void exec(String command);

}

ProdServer

public class ProdServer implements Server {

    @Override
    public void exec(String command){
        System.out.println(command + ":执行成功");
    }

}

JumpServer

public class JumpServer {

    private Server server;

    public JumpServer(Server server) {
        this.server = server;
    }

    public void exec(String command){
        System.out.println("xxx在:" + LocalDateTime.now() + " 执行了:" + command);
        server.exec(command);
        System.out.println("xxx在:" + LocalDateTime.now() + " 执行完了:"+ command + " 结果是XXX");
    }

}

Client

public class Client {

    public static void main(String[] args) {
        JumpServer jumpServer = new JumpServer();
        jumpServer.exec("pwd");
    }
}

运行结果

xxx在:2020-04-04T16:43:19.277 执行了:pwd
pwd:执行成功
xxx在:2020-04-04T16:43:19.278 执行完了:pwd 结果是XXX

  通过上面的代码,简单的实现了代理模式。在网络上代理服务器设置分为透明代理普通代理

  • 透明代理就是用户不用设置代理服务器地址,就可以直接访问.也就是说代理服务器对用户来说是透明的,不用知道它存在的。
  • 普通代理则是需要用户自己设置代理服务器的IP地址,用户必须知道代理的存在。

  当运维老哥给了一台服务器的账号和密码,你成功登录,并完成了相应的操作。你以为给你的是生产的服务器。实际就可能是个跳板机。为了安全起见,是不可能将实际服务器的IP让你知道的。很显然跳板机对你来讲就是透明的。

所以我们调整一下代码,将其变成普通代理

JumpServer

public class JumpServer {

    private Server server;

    public JumpServer(Server server) {
        this.server = server;
    }

    public void exec(String command){
        server.exec(command);
    }

}

Client

public class Client {

    public static void main(String[] args) {
        ProdServer prodServer = new ProdServer();
        JumpServer jumpServer = new JumpServer(prodServer);
        jumpServer.exec("pwd");
    }
    
}

执行结果

xxx在:2020-04-04T16:52:23.282 执行了:pwd
pwd:执行成功
xxx在:2020-04-04T16:52:23.283 执行完了:pwd 结果是XXX

强制代理

  对于现实情况,我们可以通过不开放公网访问的权限来实现,强制使用代理操作服务器。我们可以用代码简单的模拟下。

JumpServer

public class ProdServer implements Server {

    private JumpServer jumpServer;

    @Override
    public void exec(String command){
        hasProxy();
        System.out.println(command + ":执行成功");
    }

    private void hasProxy(){
        if(jumpServer == null){
            throw new RuntimeException("请使用跳板机!");
        }
    }

    public JumpServer setJumpServer() {
        this.jumpServer = new JumpServer(this);
        return this.jumpServer;
    }
}

Client未设置跳板机

public class Client {

    public static void main(String[] args) {
        ProdServer prodServer = new ProdServer();
        prodServer.exec("pwd");
    }

}

这个时候需要访问生产服务器,就需要先设置跳板机了,才能进行操作。

动态代理

  对静态代理来说,我们需要手动生成代理类。但是如果需要代理的类太多了,那这个肯定是不可取的。所以我们可以使用JDK动态代理来帮我们完成工作。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章