1.Spring 基础

  • 什么是 Spring 框架?

    Spring 是一款开源的轻量级 Java 开发框架,目的是提高开发人员的开发效率和系统的可维护性。它是很多模块的集合,使用这些模块可以很方便的让程序员进行高效的开发【比如:IOC 控制反转、AOP 面向切面编程等】

  • Spring 包含的模块有哪些?
    • Core Container【Spring 框架的核心模块,主要提供 IOC 依赖注入功能】

      • spring-core:Spring 框架基本的核心工具类
      • spring-beans:提供对 bean 的创建、配置和管理等功能的支持
      • spring-context:提供对事件传播、资源加载等功能的支持
      • spring-expression:提供对表达式语言 SpEL 的支持,只依赖于 core 模块,不依赖于其它模块,可以单独使用
    • AOP

      • spring-aspects:为了与 AspectJ 的集成提供支持
      • spring-aop:提供了面向切面的编程实现
      • spring-instrument:提供了为 JVM 添加代理功能
    • Data Access/Integration

      • spring-jdbc:提供对数据框访问的抽象 JDBC
      • spring-tx:提供对事务的支持
      • spring-orm:提供对 Hibernate、IBatis 等框架的支持
      • spring-oxm:提供了一个抽象层支持 OXM,目的是在 Java 对象和 XML 之间进行映射和转换操作
      • spring-jms:消息服务
    • Spring Web

      • spring-web:对 Web 功能的实现提供了一些最基础的支持
      • spring-webmvc:提供了对 Spring MVC 的实现
      • spring-websocket:提供了对 WebSocket 的支持,让客户端和服务端进行双向通信
      • spring-webflux:提供对 WebFlux 的支持,是 Spring 5.0 引入的新响应式框架,与 Spring MVC 不同,它不需要 Servlet API,是完全异步
    • Messaging

      是 spring-messaging 是从 Spring 4.0 加入的一个模块,主要负责是为 Spring 框架集成一些基础的报文传送应用

    • Spring Test

      单元测试

  • Spring、Spring MVC、SpringBoot 之间是什么关系

    Spring 包含了多个功能模块,其中最重要的是 Spring-Core 提供了 IOC 依赖注入功能的支持,Spring 中的其它模块比如 Spring MVC 的功能实现都需要依赖于该模块。Spring MVC 主要是赋予了 Spring 快速构架 MVC 架构的 Web 程序的能力。而当使用 Spring 进行开发的时候,各种配置过于麻烦,于是 SpringBoot 就诞生了,SpringBoot 是在简化 Spring 开发

2.Spring IOC

  • 谈谈自己对 Spring IOC 的了解

    IOC 控制反转是一种设计思想,IOC 的思想就是将原本在程序中手动创建对象的控制权,交给 Spring 框架来管理。控制指的是对象创建的控制权,反转指的是将控制权交给了外部环境。IOC 容器就像是一个工厂,当需要创建一个对象的时候,只需要配置好文件/注解就可以了,不用考虑对象是怎么被创建出来的

  • 什么是 Spring Bean?

    Bean 代指的就是那些被 IOC 容器所管理的对象,只需要告诉 IOC 容器帮助我们管理那些对象,这个是通过配置元数据来定义的【元数据可以是 XML 文件、注解或者是 Java 配置类】

  • 将一个类声明为 Bean 的注解有哪些?
    • @Component:通用注解,可以标注任意类为 Spring 组件,如果一个 bean 不知道是属于哪个层,就使用该注解来标注
    • @Repository:对应持久层,主要用于数据库相关的操作
    • @Service:对应服务层,涉及一些复杂的逻辑,会用到 Dao 层
    • @Controller:对应 Spring MVC 控制层,用于接收用户请求并调用 service 层返回数据给前端页面
  • @Component 和 @Bean 的区别是什么
    • @Component 注解作用于类,而 @Bean 注解作用与方法
    • @Component 通常是通过类路径扫描来自动检测以及自动装备到 Spring 容器,而 @Bean 注解通常是在标有该注解的方法中定义产生这个 bean,@Bean 告诉了 Spring 这是某个类的实例,当需要的时候拿给我
    • @Bean 注解比 @Component 注解的自定义性更强,而且很多地方只能通过 @Bean 注解来注册 bean
  • 注入 Bean 的注解有哪些?

    Spring 内置的 @Autowired 以及 JDK 内置的 @Resource 和 @Inject

  • @Autowired 和 @Resource 的区别是什么?

    @Autowired 属于 Spring 内置的注解,默认注入方式为 byType 根据类型进行匹配【当一个接口存在多个实现类的时候,byType 方式就无法正确注入对象,这种情况,注入方式会改为 byName 根据名称进行匹配,这个名称通常是首字母小写类名】,@Resource 是属于 JDK 提供的注解,默认注入方式为 byName,如果无法通过名称匹配到对应的 Bean ,注入方式会改为 byType【@Resource 存在两个属性 name 和 type,如果给定了 name 属性值,那么注入方式为 byName,如果指定 type 属性值,那么注入方式为 byType。如果同时给定两个值那么注入方式是 byType + byName (一般不会这么做)】

  • Bean 的作用域有哪些?
    • singleton:IOC 容器中只有唯一的 bean,Spring 中的 bean 默认都是单例的
    • prototype:每次获取都会创建一个新的 bean 实例
    • request:每一次 HTTP 请求都会产生一个新的 bean(请求 bean),该 bean 仅在当前 HTTP request 内有效
    • session:每一次新 session 的 HTTP 请求都会产生一个新的 bean(会话 bean),该 bean 仅在当前 HTTP session 内有效

    • application/global-session:每个 Web 应用在启动的时候创建一个 bean(应用 bean),该 bean 仅在当前应用启动时间内有效

    • websocket:每一次 WebSocket 会话都会产生一个新的 bean

    【如何配置 bean 的作用域?—— 通过 xml 方式,或者是注解 @Scope 的方式】

  • Bean 线程是安全的吗?

    Spring 框架中的 Bean 是否线程安全,取决于它的作用域和状态。比如在 prototype 作用域下,每次获取都会创建一个新的 bean 实例,不存在资源竞争问题,所以不存在线程安全问题。而 singleton 作用域下,IOC 容器中只有唯一的 bean 实例,就可能会存在资源竞争问题,也要取决于该 bean 是否有状态,有的话,那么就存在线程安全问题【有状态是指包含了可变的成员变量对象】。一般情况大部分 bean 都是无状态的

  • 对于有状态单例 Bean 的线程安全问题,解决方法有哪些?
    • 在 Bean 中尽量避免定义可变的成员变量
    • 在类中定义一个 ThreadLocal 成员变量,将需要的可变成员变量保存在 ThreadLocal 中
  • Bean 的生命周期了解吗?
    • Bean 容器找到配置文件中的 Spring Bean 的定义
    • 利用 Java Reflection API 创建一个 Bean 的实例
    • 如果设计到一些属性值,利用 set() 方法设置属性值
    • 如果 Bean 实现了 BeanNameAware 接口,则调用 setBeanName() 方法,传入 Bean 的名字
    • 如果 Bean 实现了 BeanClassLoaderAware 接口,则调用 setBeanClassLoader() 方法,传入 ClassLoader 对象的实例
    • 与这两个类似,如果实现了其它什么Aware的接口,就调用相应的方法
    • 如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,那么则执行 postProcessBeforeInitialization() 方法
    • 如果 Bean 实现了 InitializingBean 接口,则执行 afterPropertiesSet() 方法
    • 如果 Bean 在配置文件中的定义包含 init-method 属性,那么执行指定的方法
    • 如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行 postProcessAfterInitialization() 方法
    • 当要销毁 Bean 的时候,如果 Bean 实现了 DispoableBean 接口,那么执行 destroy() 方法
    • 当要销毁 Bean 的时候,如果 Bean 在配置文件中的定义包含 destroy-method 属性,那么执行指定的方法

3.Spring AOP

  • 谈谈自己对 AOP 的了解

    AOP 面向切面编程,能够吧与业务无关,却为业务模块所共同调用的逻辑(事务处理、日志管理、权限控制等)封装起来,减少系统的重复代码,降低模块间的耦合度,有利于之后的可扩展性和可维护性【Spring AOP 就是基于动态代理的】

  • AOP 切面编程设计到的一些专业术语
    • 目标(target):被通知的对象
    • 代理(Proxy):向目标对象应用通过之后创建的代理对象
    • 连接点(JoinPoint):目标对象的所属类中,定义的所有方法运维连接点
    • 切入点(Pointcut):被切面拦截/增强的连接点
    • 通知(Advice):增强的逻辑代码,就是拦截到目标对象的链接点后做的事情
    • 切面(Ascpet):切入点 + 通知
    • Weaving(织入):吧通知应用到目标堆笑,进而生成代理对象的过程
  • Spring AOP 和 AspectJ AOP 有什么区别?
    • Spring AOP 属于运行时增强,而 AspectJ 是编译时增强
    • Spring AOP 基于代理,而 AspcetJ 基于字节码操作
    • Spring AOP 目前已经集成了 AscpetJ,AspectJ 相比于 Spring AOP 功能更加强大,但 Spring AOP 相对更简单
  • AspectJ 定义的通知类型有哪些?
    • Before(前置通知):目标对象的方法调用之前触发
    • After(后置通知):目标对象的方法调用之后触发
    • AfterReturning(返回通知):目标对象的方法调用完成,在方法返回值之后触发
    • AfterThrowing(异常通知):目标对象的方法运行中抛出/触发异常后触发【AfterReturning 和 AfterThrowing 两者互斥,如果方法调用成功无异常,则会存在返回值,如果方法抛出了异常,则不会有返回值】
    • Around(环绕通知):编程式控制目标对象的方法调用,环绕通知是所有通知类型中操作范围最大的一种,因为可以直接拿到目标对象以及要执行的方法,环绕通知可以任意的在目标对象的方法调用前后做逻辑,甚至可以不调用目标对象的方法
  • 多个切面的执行顺序如何控制?
    • 通常是使用 @Order 注解,给定默认 value 值,值越小优先级越高
    • 实现 Ordered 接口重写 getOrder 方法,返回值越小优先级越高【不常用】

results matching ""

    No results matching ""