面试6_Spring

面试2_Spring

参考资料

  1. CSDN_Spring面试题
  2. 简书_Spring常见面试题
  3. 知乎_Spring面试题IOC系列
  4. CSDN_面试题 Spring IOC相关
  5. 有道云_面试3_Spring
  6. SpringBoot自动配置注解原理解析
  7. Cglib和jdk动态代理的区别

一、spring概述

1. Spring组成模块

  1. 核心容器(Core Container)
  2. AOP(Aspect Oriented Programming)和设备支持(Instrmentation)
  3. 数据访问与集成(Data Access/Integeration)
  4. Web
  5. 消息(Messaging)
  6. Test

2. Spring使用的设计模式

  1. 工厂模式:BeanFactory,用来创建对象的实例;
  2. 单例模式:Bean默认为单例模式。
  3. 代理模式:AOP功能
  4. 模板方法:解决代码重复的问题
  5. 观察者模式

3. Spring事件类型

  1. 上下文更新事件:在调用ConfigurableApplicationContext 接口中的refresh()方法时被触发。
  2. 上下文开始事件:当容器调用ConfigurableApplicationContext的Start()方法开始/重新开始容器时触发该事件。
  3. 上下文停止事件:当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。
  4. 上下文关闭事件:当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。
  5. 请求处理事件:在Web应用中,当一个http请求(request)结束触发该事件。

4. 核心容器模块详情

BeanFactory 是 任何以spring为基础的应用的核心。是工厂模式的一个实现,提供了控制反转功能。


二、IOC

1. IOC、DI

  1. IOC是 控制反转依赖对象的创建及维护是由外部容器负责的
  2. DI也就是 依赖注入实现IOC的方式之一。运行期间由外部容器动态地将依赖对象注入到组件

2. IOC作用

  1. 管理对象的创建依赖关系的维护
  2. 解耦,由容器去维护具体的对象
  3. 托管类产生过程
  • 容易测试,单元测试不再需要单例和JNDI查找机制
  • 支持加载服务时的饿汉式初始化懒加载

3. IOC支持的功能

  1. 依赖注入
  2. 依赖查找
  3. 自动装配
  4. 支持集合
  5. 指定初始化方法和销毁方法

4. IOC实现原理

**工厂模式 + 反射机制


5. IOC初始化

  1. Resource 定位
  2. Bean 注册
    1. BeanDefinitionReader 读取、解析bean的配置信息
    2. 將bean的配置信息转换为 BeanDefinition 对象,并保存在内存中
    3. registerBeanDefinition 将 BeanDefinition 注入到 Bean定义注册表
  3. Bean 实例化
    1. 遍历Bean定义注册表,调用getBean方法拿出Class对象通过反射机制进行实例化,保存在Bean缓存池中。

6. DI实现方式、区别

  1. 接口注入
  2. Setter方法注入
  3. 构造器注入
区别 构造函数注入 setter 注入
部分注入 没有
覆盖 setter 属性 不会
任意修改会创建新实例 会 不会
适用范围 适用于设置很多属性 适用于设置少量属性

7. BeanFactory、 FactoryBean区别

  1. BeanFactory是IOC的底层容器,用于管理Bean,通过getBean进行依赖查找,若 Bean 未初始化,则从底层查找或构建。
  2. FactoryBean是特殊的 Bean,需注册到 IoC 容器,通过容器的getBean 获取 FactoryBean#getObject()方法的内容,作用主要是自定义实际Bean的产生过程

8. BeanFactory、ApplicationContext区别

  1. ApplicationContext实现BeanFactory接口,提供更多功能:

    1. 提供国际化的消息访问, MessageSource
    2. 统一的资源文件访问方式, ResourceLoader
    3. 事件传递:通过实现ApplicationContextAware接口。消息发送、响应机制(ApplicationEventPublisher)
    4. Bean的自动装配
    5. 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次。各种不同应用层的Context实现
  2. 区别

区别 BeanFactory ApplicationContext
·加载方式· 懒加载,使用时才被实例化 启动时实例化
可以为Bean配置lazy-init=true来让Bean延迟实例化
能尽早的发现系统中的配置问题
·创建方式· 编程式 编程式 + 声明式
·注册方式·
BeanPostProcessor、BeanFactoryPostProcessor的使用
手动注册 自动注册

9. Bean 自动装配

自动装配类型

  1. no:默认的方式是不进行自动装配的,通过手工设置ref属性来进行装配bean。
  2. byName:通过bean的名称进行自动装配,如果一个bean的 property 与另一bean 的name 相同,就进行自动装配。
  3. byType:通过参数的数据类型进行自动装配。
  4. constructor:利用构造函数进行装配,并且构造函数的参数通过byType进行装配。
  5. autodetect:自动探测,如果有构造方法,通过 construct的方式自动装配,否则使用 byType的方式自动装配。

自动装配注解原理

  • @SpringBootApplication:启动类
    • @EnableAutoConfiguration:开启自动配置类
      • @AutoConfigurationPackage:自动配置包
        • 返回当前主程序类的同级以及子级的包组件
      • @Import:导入自动配置的组件
        • 继承了 ImportSelector,来加载 **META-INF/spring.factories**外部文件

10. Bean 生命周期

面试6_Spring

  1. bean实例化
  2. 属性填充:将值和bean的引用注入到bean对应的属性中;
  3. 检查Aware相关接口并设置相关依赖
  4. BeanPostProcessor前置处理
  5. 调用InitializingBean接口的afterPropertiesSet()方法;
  6. BeanPostProcessor后置处理
  7. bean准备就绪
  8. 销毁bean
    1. 调用DisposableBean的destroy()方法。
    2. 调用定制的销毁方法

11. Bean 作用域

  • bean标签里面有scope属性 用于设置单实例还是多实例
  1. singleton 加载 spring 配置文件时就会创建单实例对象
  2. prototype 在调用getBean 方法时创建多实例对象
作用域 说明
singleton 在 Spring 容器中仅存在一个 bean 的实例,bean 以单例形式存在。
这是99默认的作用域99
prototype 每次从容器中获取 bean 时,都将生成一个新的实例,
即相当于每次都执行 new xxxBean()
request 在 HTTP 请求 (request) 的完整生命周期中,将创建并使用单个实例。
该作用域仅适用于 WebApplicatonContext 环境
session 在 HTTP 会话 (session) 的完整生命周期中,将创建并使用单个实例。
该作用域仅适用于 WebApplicationContext 环境
global-Session 在全局的 HTTP 会话 (session) 的完整生命周期中,将创建并使用单个实例。
该作用域仅适用于 WebApplicationContext 环境,且通常只能用在 Portlet 环境中。

12. 单例bean线程安全?

  1. 单例bean不是线程安全的
  2. 大部分时候 spring bean 无状态的,某种程度上来说 bean 也是安全的
  3. bean 有状态的话,要开发者去保证线程安全,改变 bean 的作用域,把“singleton”变更为“prototype”
    1. 有状态就是有数据存储功能。
    2. 无状态就是不会保存数据。

12. 如何保证 Controller 并发的安全

  • Controller对象是单例的,Spring 多线程请求过来调用的Controller对象都是同一个
    • 使用ThreadLocal来保存类变量
    • 添加注解@Scope(“prototype”)让Controller以多实例形式创建

13. 如何解决循环依赖

  • Spring三个缓存区
  • setter方法注入形成的单例循环依赖能够解决
  • 通过ObjectFactory提前曝光,放到三级缓存

14. 为什么需要三个缓存,而不是直接两个缓存?

  • 保证单例
  • 使用AOP情况下,只使用一级、三级缓存无法解决循环依赖的问题
    • 每次从三级缓存中拿到singleFactory对象,在执行getObject()时会产生新的代理对象
    • 产生的代理对象放到二级缓存中。然后把这个三级缓存删除掉,这样以后就使用二级缓存的同一个对象。

15. MVC 的工作原理


三、AOP

1. AOP的实现原理

  1. 静态代理的代表为 AspectJ
  2. 动态代理则以 Spring AOP 为代表

2. JDK动态代理、cglib动态代理

  1. JDK动态代理,拦截器+反射 生成一个代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理,只能对实现了接口的类生成代理。
  2. cglib动态代理,通过修改其字节码生成子类来处理,覆盖其中的方法。

四、Spring事务

Spring 事务管理机制
Spring 事务传播行为及其作用


五、Spring注解

1. @Component, @Controller, @Repository, @Service

将 java 类标记为 bean,@Component为父接口

2. @Required

bean的属性必须在配置时设置,通过一个bean定义的显式的属性值或通过自动装配

3. @Autowired、@Resource的区别

  1. @Autowired可用于:构造函数、成员变量、Setter方法

  2. @Autowired默认按类型装配注入,默认情况下它要求依赖对象必须存在(可以设置它required属性为false)。

  3. @Resource默认按名称装配注入,找不到才按类型装配注入。

4. @Qualifier

创建多个相同类型的 bean 并希望仅使用属性装配其中一个 bean 时,使用@Qualifier 注解和 @Autowired 通过指定应装配确切的 bean 来消除歧义

5. @RequestMapping

  1. 将特定 HTTP 请求方法映射到将处理相应请求的控制器中的特定类/方法。
上一篇:Spring系列-SpringBase+IOC


下一篇:吴裕雄--天生自然--SPRING--Spring IoC