IOC和AOP以及spring框架的面试宝典

追求适度,才能走向成功;人在顶峰,迈步就是下坡;身在低谷,抬足既是登高;弦,绷得太紧会断;人,思虑过度会疯;水至清无鱼,人至真无友,山至高无树;适度,不是中庸,而是一种明智的生活态度。

导读:本篇文章讲解 IOC和AOP以及spring框架的面试宝典,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

一、Spring控制反转(IOC)

1.什么是IOC

控制反转,把创建对象的权利交给spring


2.什么是Spring IOC 容器?

控制反转即IOC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容
器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转
移,从程序代码本身转移到了外部容器。
Spring IOC 负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,并且管理这
些对象的整个生命周期。
2.2 控制反转(IOC)有什么作用
管理对象的创建和依赖关系的维护。对象的创建并不是一件简单的事,在对象关系比较复杂时,如
果依赖关系需要程序猿来维护的话,那是相当头疼的
解耦,由容器去维护具体的对象
托管了类的产生过程,比如我们需要在类的产生过程中做一些处理,最直接的例子就是代理,如果
有容器程序可以把这部分处理交给容器,应用程序则无需去关心类是如何完成代理的
2.3 IOC的优点是什么?
IOC 或 依赖注入把应用的代码量降到最低。
它使应用容易测试,单元测试不再需要单例和JNDI查找机制。
最小的代价和最小的侵入性使松散耦合得以实现。
IOC容器支持加载服务时的饿汉式初始化和懒加载。
2.4 Spring IOC 的实现机制

Spring 中的 IOC 的实现原理就是工厂模式加反射机制


3.Spring 的 IOC支持哪些功能

  • Spring 的 IOC 设计支持以下功能:
  • 其中,最重要的就是依赖注入,从 XML 的配置上说,即 ref 标签。对应 Spring
    RuntimeBeanReference 对象。
  • 对于 IOC 来说,最重要的就是容器。容器管理着 Bean 的生命周期,控制着 Bean 的依赖注入。

4.BeanFactory 和 ApplicationContext有什么区别?

  • BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当做Spring的容器。其中
    ApplicationContext是BeanFactory的子接口。
  • 依赖关系
    • BeanFactory:是Spring里面最底层的接口,包含了各种Bean的定义,读取bean配置文档,
      管理bean的加载、实例化,控制bean的生命周期,维护bean之间的依赖关系。
  • ApplicationContext接口作为BeanFactory的派生,除了提供BeanFactory所具有的功能外,还提
    供了更完整的框架功能:
    • 继承MessageSource,因此支持国际化。
    • 统一的资源文件访问方式。
    • 提供在监听器中注册bean的事件。
    • 同时加载多个配置文件。
    • 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的
      web层。
  • 加载方式
    • BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用
      getBean()),才对该Bean进行加载实例化。这样,我们就不能发现一些存在的Spring的配置
      问题。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用
      getBean方法才会抛出异常。
    • ApplicationContext,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动
      时,我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入。
      ApplicationContext启动后预载入所有的单实例Bean,通过预载入单实例bean ,确保当你需
      要的时候,你就不用等待,因为它们已经创建好了。

相对于基本的BeanFactory,ApplicationContext 唯一的不足是占用内存空间。当应用程序配置Bean较多
时,程序启动较慢。

  • 创建方式
    • BeanFactory通常以编程的方式被创建,ApplicationContext还能以声明的方式创建,如使用
      ContextLoader。
  • 注册方式
  • BeanFactory和ApplicationContext都支持BeanPostProcessor、
    BeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory需要手动注册,而
    ApplicationContext则是自动注册。

5.ApplicationContext通常的实现是什么?

  • FileSystemXmlApplicationContext :此容器从一个XML文件中加载beans的定义,XML Bean
    配置文件的全路径名必须提供给它的构造函数。
  • ClassPathXmlApplicationContext:此容器也从一个XML文件中加载beans的定义,这里,你
    需要正确设置classpath因为这个容器将在classpath里找bean配置。
  • WebXmlApplicationContext:此容器加载一个XML文件,此文件定义了一个WEB应用的所有
    bean。

6.什么是Spring的依赖注入?

  • 控制反转IOC是一个很大的概念,可以用不同的方式来实现。其主要实现方式有两种:依赖注入和
    依赖查找依赖注入:相对于IOC而言,依赖注入(DI)更加准确地描述了IOC的设计理念。所谓依赖注
    入(Dependency Injection),即组件之间的依赖关系由容器在应用系统运行期来决定,也就是
    由容器动态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中。组件不做
    定位查询,只提供普通的Java方法让容器去决定依赖关系。

7.依赖注入有什么优势

  • 依赖注入之所以更流行是因为它是一种更可取的方式:让容器全权负责依赖查询,受管组件只需要
    暴露JavaBean的setter方法或者带参数的构造器或者接口,使容器可以在初始化时组装对象的依赖
    关系。其与依赖查找方式相比,主要优势为:
    • 查找定位操作与应用代码完全无关。
    • 不依赖于容器的API,可以很容易地在任何容器以外使用应用对象。
    • 不需要特殊的接口,绝大多数对象可以做到完全不必依赖容器。

8.有哪些不同类型的依赖注入实现方式?

  • 依赖注入是时下最流行的IOC实现方式,依赖注入分为接口注入(Interface Injection),Setter方
    法注入(Setter Injection)和构造器注入(Constructor Injection)三种方式。其中接口注入由于
    在灵活性和易用性比较差,现在从Spring4开始已被废弃。
  • 构造器依赖注入:构造器依赖注入通过容器触发一个类的构造器来实现的,该类有一系列参数,每
    个参数代表一个对其他类的依赖。
  • Setter方法注入:Setter方法注入是容器通过调用无参构造器或无参static工厂 方法实例化bean之
    后,调用该bean的setter方法,即实现了基于setter的依赖注入。

9.构造器依赖注入和 Setter方法注入的区别

构造函数注入 setter 注入
没有部分注入 有部分注入
不会覆盖 setter 属性 会覆盖 setter 属性
任意修改都会创建一个新实例 任意修改不会创建一个新实例
适用于设置很多属性 适用于设置少量属性
  • 两种依赖方式都可以使用,构造器注入和Setter方法注入。最好的解决方案是用构造器参数实现强
    制依赖,setter方法实现可选依赖。

10.什么是DI

属性的依赖注入,spring在通过IOC创建对象的时候,如果对象还有属性,就一并给赋值进去DI是在IOC的基础上进行对象的属性       注入

    1.依赖注入的三种实现方式?

构造器注入,Setter方法注入,接口注入

    2.解释Spring支持的几种bean的作用域

a、singleton : bean在每个Spring ioc 容器中只有一个实例。b、prototype:一个bean的定义可以有多个实例。

c、request:每次http请求都会创建一个bean,该作用域仅在基于web的Spring ApplicationContext情形下有效。

d、session:在一个HTTP   Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring    ApplicationContext情形下有效。

e、global-session:在一个全局的HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。

缺省的Spring bean 的作用域是Singleton.




二、Spring面向切面编程(AOP)

1 什么是AOP

  • OOP(Object-Oriented Programming)面向对象编程,允许开发者定义纵向的关系,但并适用于定
    义横向的关系,导致了大量代码的重复,而不利于各个模块的重用。
  • AOP(Aspect-Oriented Programming),一般称为面向切面编程,作为面向对象的一种补充,用于
    将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模
    块,这个模块被命名为“切面”(Aspect),减少系统中的重复代码,降低了模块间的耦合度,同时
    提高了系统的可维护性。可用于权限认证、日志、事务处理等。

2.解释AOP

在软件业,AOP为Aspect   Oriented    Programming的缩写,意味:面向切面编程.通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术,AOP是OOP的延续.将一些共性的内容进行抽取,在需要用到的地方,以动态代理的方式进行插入.在不修       改源码的基础上,还能对源码进行前后增强。


3.Spring AOP and AspectJ AOP 有什么区别?AOP 有哪些实现方式?

  • AOP实现的关键在于 代理模式,AOP代理主要分为静态代理和动态代理。静态代理的代表为
    AspectJ;动态代理则以Spring AOP为代表。
    (1)AspectJ是静态代理的增强,所谓静态代理,就是AOP框架会在编译阶段生成AOP代理
    类,因此也称为编译时增强,他会在编译阶段将AspectJ(切面)织入到Java字节码中,运行的
    时候就是增强之后的AOP对象。
    (2)Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次
    运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在
    特定的切点做了增强处理,并回调原对象的方法。

  • 3 JDK动态代理和CGLIB动态代理的区别

  • Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理:

    • JDK动态代理只提供接口的代理,不支持类的代理。核心InvocationHandler接口和Proxy
      类,InvocationHandler 通过invoke()方法反射来调用目标类中的代码,动态地将横切逻辑和
      业务编织在一起;接着,Proxy利用 InvocationHandler动态创建一个符合某一接口的的实
      例, 生成目标类的代理对象。
    • 如果代理类没有实现 InvocationHandler 接口,那么Spring AOP会选择使用CGLIB来动态代
      理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动
      态的生成指定类的一个子类对象,并覆盖其中特定方法并添加增强代码,从而实现AOP。
      CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用
      CGLIB做动态代理的。
  • 静态代理与动态代理区别在于生成AOP代理对象的时机不同,相对来说AspectJ的静态代理方式具
    有更好的性能,但是AspectJ需要特定的编译器进行处理,而Spring AOP则无需特定的编译器处
    理。
    InvocationHandler 的 invoke(Object proxy,Method method,Object[] args):proxy是最终生成
    的代理实例; method 是被代理目标实例的某个具体方法; args 是被代理目标实例某个方法的具体
    入参, 在方法反射调用时使用。


4.解释一下Spring AOP里面的几个名词

(1)切面(Aspect):切面是通知和切点的结合。通知和切点共同定义了切面的全部内容。 在
Spring AOP中,切面可以使用通用类(基于模式的风格) 或者在普通类中以 @AspectJ 注解来实
现。
(2)连接点(Join point):指方法,在Spring AOP中,一个连接点 总是 代表一个方法的执行。
应用可能有数以千计的时机应用通知。这些时机被称为连接点。连接点是在应用执行过程中能够插
入切面的一个点。这个点可以是调用方法时、抛出异常时、甚至修改一个字段时。切面代码可以利
用这些点插入到应用的正常流程之中,并添加新的行为。
(3)通知(Advice):在AOP术语中,切面的工作被称为通知。
(4)切入点(Pointcut):切点的定义会匹配通知所要织入的一个或多个连接点。我们通常使用
明确的类和方法名称,或是利用正则表达式定义所匹配的类和方法名称来指定这些切点。
(5)引入(Introduction):引入允许我们向现有类添加新方法或属性。
(6)目标对象(Target Object): 被一个或者多个切面(aspect)所通知(advise)的对象。
它通常是一个代理对象。也有人把它叫做 被通知(adviced) 对象。 既然Spring AOP是通过运行
时代理实现的,这个对象永远是一个 被代理(proxied) 对象。
(7)织入(Weaving):织入是把切面应用到目标对象并创建新的代理对象的过程。在目标对象
的生命周期里有多少个点可以进行织入:

  • 编译期:切面在目标类编译时被织入。AspectJ的织入编译器是以这种方式织入切面的。
  • 类加载期:切面在目标类加载到JVM时被织入。需要特殊的类加载器,它可以在目标类被引
    入应用之前增强该目标类的字节码。AspectJ5的加载时织入就支持以这种方式织入切面。
  • 运行期:切面在应用运行的某个时刻被织入。一般情况下,在织入切面时,AOP容器会为目
    标对象动态地创建一个代理对象。SpringAOP就是以这种方式织入切面。

5. Spring在运行时通知对象

  • 通过在代理类中包裹切面,Spring在运行期把切面织入到Spring管理的bean中。代理封装了目标
    类,并拦截被通知方法的调用,再把调用转发给真正的目标bean。当代理拦截到方法调用时,在
    调用目标bean方法之前,会执行切面逻辑。
  • 直到应用需要被代理的bean时,Spring才创建代理对象。如果使用的是ApplicationContext的
    话,在ApplicationContext从BeanFactory中加载所有bean的时候,Spring才会创建被代理的对
    象。因为Spring运行时才创建代理对象,所以我们不需要特殊的编译器来织入SpringAOP的切面。

6. Spring只支持方法级别的连接点

  • 因为Spring基于动态代理,所以Spring只支持方法连接点。Spring缺少对字段连接点的支持,而且
    它不支持构造器连接点。方法之外的连接点拦截功能,我们可以利用Aspect来补充。

7.在Spring AOP 中,关注点和横切关注的区别是什么?在 springaop 中 concern 和 cross-cutting concern 的不同之处

  • 关注点(concern)是应用中一个模块的行为,一个关注点可能会被定义成一个我们想实现的一个
    功能。
  • 横切关注点(cross-cutting concern)是一个关注点,此关注点是整个应用都会使用的功能,并影
    响整个应用,比如日志,安全和数据传输,几乎应用的每个模块都需要的功能。因此这些都属于横
    切关注点。

8.Spring通知有哪些类型?

在AOP术语中,切面的工作被称为通知,实际上是程序执行时要通过SpringAOP框架触发的代码段。
Spring切面可以应用5种类型的通知:

  1. 前置通知(Before):在目标方法被调用之前调用通知功能;
  2. 后置通知(After):在目标方法完成之后调用通知,此时不会关心方法的输出是什么;
  3. 返回通知(After-returning ):在目标方法成功执行之后调用通知;
  4. 异常通知(After-throwing):在目标方法抛出异常后调用通知;
  5. 环绕通知(Around):通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为。

9.什么是切面 Aspect?

  • aspect 由 pointcount 和 advice 组成,切面是通知和切点的结合。 它既包含了横切逻辑的定义,
    也包括了连接点的定义. Spring AOP 就是负责实施切面的框架, 它将切面所定义的横切逻辑编织到
    切面所指定的连接点中. AOP 的工作重心在于如何将增强编织目标对象的连接点上, 这里包含两个
    工作:
    • 如何通过 pointcut 和 advice 定位到特定的 joinpoint 上
    • 如何在 advice 中编写切面代码.
  • 可以简单地认为, 使用 @Aspect 注解的类就是切面
    在这里插入图片描述

10.解释基于XML Schema方式的切面实现

在这种情况下,切面由常规类以及基于XML的配置实现。


11.什么是通知?有哪五种类型的通知?

通知是个在方法执行前或执行后要做的动作,实际上是程序执行时要通过SpringAOP框架触发的代码段。Spring切面可以应用五种类型的通知:

a、before:前置通知,在一个方法执行前被调用。

b、after: 在方法执行之后调用的通知,无论方法执行是否成功。c、after-returning: 仅当方法成功完成后执行的通知。

d、after-throwing: 在方法抛出异常退出时执行的通知。e、around: 在方法执行之前和之后调用的通知。




三、spring框架

1.Spring两大核心概念:

  • IOC控制翻转):
    控制翻转,也叫依赖注入,他就是不会直接创建对象,只是把对象声明出来,在代码 中不直
    接与对象和服务进行连接,但是在配置文件中描述了哪一项组件需要哪一项服 务,容器将他
    们组件起来。在一般的IOC场景中容器创建了所有的对象,并设置了必 要的属性将他们联系
    在一起,等到需要使用的时候才把他们声明出来,使用注解就跟 方便了,容器会自动根据注
    解把对象组合起来
  • AOP面对切面编程
    面对切面编程,这是一种编程模式,他允许程序员通过自定义的横切点进行模块 化,将那些
    影响多个类的行为封装到课重用的模块中。 例子:比如日志输出,不使用AOP的话就需要把
    日志的输出语句放在所有类中,方法 中,但是有了AOP就可以把日志输出语句封装一个可重
    用模块,在以声明的方式将他 们放在类中,每次使用类就自动完成了日志输出。

 2.spring的作用

方便解耦,简化开发,AOP编程支持,声明式事务支持,集成Junit更加方便的进行分层测试,方便集成各种优秀框架


 3.Spring支持的事务管理类型

a、编程式事务管理:这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。

b、声明式事务管理:这意味着你可以将业务代码和事务管理分离,你只需用注解和XML配置来管理事务。


4.Spring框架的设计目标,设计理念,和核心是什么:

  • Spring设计目标:Spring为开发者提供一个一站式轻量级应用开发平台;
  • Spring设计理念:在JavaEE开发中,支持POJO和JavaBean开发方式,使应用面向接口开发,充分
    支持OOP(面向对象)设计方法;Spring通过IOC容器实现对象耦合关系的管理,并实现依赖反
    转,将对象之间的依赖关系交给IOC容器,实现解耦;
  • Spring框架的核心:IOC容器和AOP模块。通过IOC容器管理POJO对象以及他们之间的耦合关系;
    通过AOP以动态非侵入的方式增强服务。
  • IOC让相互协作的组件保持松散的耦合,而AOP编程允许你把遍布于应用各层的功能分离出来形成
    可重用的功能组件。

 5.Spring的优缺点是什么?

优点

  • 方便解耦,简化开发
    Spring就是一个大工厂,可以将所有对象的创建和依赖关系的维护,交给Spring管理。
  • AOP编程的支持
    Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能。
  • 声明式事务的支持
    只需要通过配置就可以完成对事务的管理,而无需手动编程。
  • 方便程序的测试
    Spring对Junit4支持,可以通过注解方便的测试Spring程序。
  • 方便集成各种优秀框架
    Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架的直接支持(如:Struts、
    Hibernate、MyBatis等)。
  • 降低JavaEE API的使用难度
    Spring对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使
    这些API应用难度大大降低。

缺点

  • Spring明明一个很轻量级的框架,却给人感觉大而全
  • Spring依赖反射,反射影响性能
  • 使用门槛升高,入门Spring需要较长时间

6.Spring有哪些应用场景

应用场景:JavaEE企业应用开发,包括SSH、SSM等

  1. Spring价值:

  2. Spring是非侵入式的框架,目标是使应用程序代码对框架依赖最小化;
  3. Spring提供一个一致的编程模型,使应用直接使用POJO开发,与运行环境隔离开来;
  4. Spring推动应用设计风格向面向对象和面向接口开发转变,提高了代码的重用性和可测试性;

7.Spring由哪些模块组成?

Spring 总共大约有 20 个模块, 由 1300 多个不同的文件构成。 而这些组件被分别整合在 核心容
器(Core Container) 、 AOP(Aspect Oriented Programming)和设备支持
(Instrmentation) 、 数据访问与集成(Data Access/Integeration) 、 Web 、 消息
(Messaging) 、 Test 等 6 个模块中。 以下是 Spring 5 的模块结构图:
在这里插入图片描述

  • spring core:提供了框架的基本组成部分,包括控制反转(Inversion of Control,IOC)和依赖
    注入(Dependency Injection,DI)功能。
  • spring beans:提供了BeanFactory,是工厂模式的一个经典实现,Spring将管理对象称为Bean。
  • spring context:构建于 core 封装包基础上的 context 封装包,提供了一种框架式的对象访问方法。
  • spring jdbc:提供了一个JDBC的抽象层,消除了烦琐的JDBC编码和数据库厂商特有的错误代码解析, 用于简化JDBC。
  • spring aop:提供了面向切面的编程实现,让你可以自定义拦截器、切点等。
  • spring Web:提供了针对 Web 开发的集成特性,例如文件上传,利用 servlet listeners 进行 ioc容器初始化和针对 Web 的 ApplicationContext。
  • spring test:主要为测试提供支持的,支持使用JUnit或TestNG对Spring组件进行单元测试和集成测试。

8.Spring 框架中都用到了哪些设计模式

  1. 工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例;
  2. 单例模式:Bean默认为单例模式。
  3. 代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术;
  4. 模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。
  5. 观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的
    对象都会得到通知被制动更新,如Spring中listener的实现–ApplicationListener。

9. Spring框架中有哪些不同类型的事件

Spring 提供了以下5种标准的事件:

  1. 上下文更新事件(ContextRefreshedEvent):在调用ConfigurableApplicationContext 接
    口中的refresh()方法时被触发。
  2. 上下文开始事件(ContextStartedEvent):当容器调用ConfigurableApplicationContext的
    Start()方法开始/重新开始容器时触发该事件。
  3. 上下文停止事件(ContextStoppedEvent):当容器调用ConfigurableApplicationContext
    的Stop()方法停止容器时触发该事件。
  4. 上下文关闭事件(ContextClosedEvent):当ApplicationContext被关闭时触发该事件。容
    器被关闭时,其管理的所有单例Bean都被销毁。
  5. 请求处理事件(RequestHandledEvent):在Web应用中,当一个http请求(request)结
    束触发该事件。如果一个bean实现了ApplicationListener接口,当一个ApplicationEvent 被
    发布以后,bean会自动被通知。

10.详细讲解一下核心容器(spring context应用上下文) 模块

这是基本的Spring模块,提供spring 框架的基础功能,BeanFactory 是 任何以spring为基础的应
用的核心。Spring 框架建立在此模块之上,它使Spring成为一个容器。
Bean 工厂是工厂模式的一个实现,提供了控制反转功能,用来把应用的配置和依赖从真正的应用
代码中分离。最常用的就是org.springframework.beans.factory.xml.XmlBeanFactory ,它根据
XML文件中的定义加载beans。该容器从XML 文件读取配置元数据并用它去创建一个完全配置的
系统或应用。


11. Spring 应用程序有哪些不同组件?

Spring 应用一般有以下组件:

  • 接口 – 定义功能。
  • Bean 类 – 它包含属性,setter 和 getter 方法,函数等。
  • Bean 配置文件 – 包含类的信息以及如何配置它们。
  • Spring 面向切面编程(AOP) – 提供面向切面编程的功能。
  • 用户程序 – 它使用接口。

12.使用 Spring 有哪些方式?

使用 Spring 有以下方式:

  • 作为一个成熟的 Spring Web 应用程序。
  • 作为第三方 Web 框架,使用 Spring Frameworks 中间层。
  • 作为企业级 Java Bean,它可以包装现有的 POJO(Plain Old Java Objects)。
  • 用于远程使用。

13. spring DAO 有什么用?

Spring DAO(数据访问对象) 使得 JDBC,Hibernate 或 JDO 这样的数据访问技术更容易以一种
统一的方式工作。这使得用户容易在持久性技术之间切换。它还允许您在编写代码时,无需考虑捕
获每种技术不同的异常。

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

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

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

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