首页 > 其他分享 >Spring - IoC相关面试题

Spring - IoC相关面试题

时间:2023-09-09 16:36:33浏览次数:52  
标签:面试题 Resource Spring Bean bean 注解 IoC

什么是IoC?

Spring IoC有什么好处呢? - 看看依赖倒置原则

IoC (Inversion of control )控制反转。他是一种解耦的设计思想。IoC的思想就是将原本在程序中手动创建对象的控制权,交给Spring框架来管理,从而实现具有依赖关系的对象之间的解耦(IOC 容器管理对象,你只管使用即可),降低代码之间的耦合度。

  • 控制:指的是对象创建(实例化,管理)的权力
  • 反转:控制权交给外部环境(Spring框架、IoC容器)

IoC 图解

在实际项目中一个Service类如果有几百甚至上千个类作为他的底层,我们需要实例化这个Service,可能每次都要高清这个Service所有底层类的构造函数。但是利用IoC的话,只需要配置好,在需要的地方引用就行了。

img

IoC和DI一样吗?

DI(Dependency Inject,依赖注入)是实现控制反转的一种设计模式,依赖注入就是将实例变量传入到一个对象中去。

可以有三种方式:

  • 构造函数传入
  • Setter传递
  • 接口传递

什么是Spring Bean?

简单来说,Bean代指的就是那些被IoC容器管理的对象。

我们需要告诉 IoC 容器帮助我们管理哪些对象,这个是通过配置元数据来定义的。配置元数据可以是 XML 文件注解或者 Java 配置类

<!-- Constructor-arg with 'value' attribute -->
<bean id="..." class="...">
   <constructor-arg value="..."/>
</bean>

类声明为Bean的注解

  • @Component:通用的注解,可标注任意类为 Spring 组件。如果一个 Bean 不知道属于哪个层,可以使用@Component 注解标注。
  • @Repository : 对应持久层即 Dao 层,主要用于数据库相关操作。
  • @Service : 对应服务层,主要涉及一些复杂的逻辑,需要用到 Dao 层。
  • @Controller : 对应 Spring MVC 控制层,主要用于接受用户请求并调用 Service 层返回数据给前端页面。

@Component 和 @Bean 的区别

  • 用途不同:@Component用于标识普通的类,而@Bean是在配置类中声明和配置Bean对象。
  • 使用方式不同:@Component通过类级别的注解使用,Spring通过@ComponetScan注解扫描并注册为Bean;@Bean通过方法级别的注解使用,在配置类中手动声明和配置Bean。
  • 控制权不同:@Component注解修饰的类是由Spring框架来创建和初始化的;@Bean注解允许开发人员手动控制Bean的创建和配置过程,所以@Bean注解在配置上会更加灵活。

注入 Bean 的注解有

Spring 内置的 @Autowired 以及 JDK 内置的 @Resource@Inject 都可以用于注入 Bean。

Annotaion Package Source
@Autowired org.springframework.bean.factory Spring 2.5+
@Resource javax.annotation Java JSR-250
@Inject javax.inject Java JSR-330

@Autowired@Resource使用的比较多一些。

@Autowired 和 @Resource 的区别

Autowired 属于 Spring 内置的注解,默认的注入方式为byType(根据类型进行匹配),也就是说会优先根据接口类型去匹配并注入 Bean (接口的实现类)。

可以配合 @Qualifier 注解来显式指定名称。

@Autowired
@Qualifier(value = "smsServiceImpl1")
private SmsService smsService;

@Resource属于 JDK 提供的注解,默认注入方式为 byName。如果无法通过名称匹配到对应的 Bean 的话,注入方式会变为byType

@Resource 有两个比较重要且日常开发常用的属性:name(名称)、type(类型)。如果仅指定 name 属性则注入方式为byName,如果仅指定type属性则注入方式为byType,如果同时指定nametype属性(不建议这么做)则注入方式为byType+byName

@Resource(name = "smsServiceImpl1")
private SmsService smsService;

总结

  • @Autowired 是 Spring 提供的注解,@Resource 是 JDK 提供的注解。
  • Autowired 默认的注入方式为byType(根据类型进行匹配),@Resource默认注入方式为 byName(根据名称进行匹配)。
  • 当一个接口存在多个实现类的情况下,@Autowired@Resource都需要通过名称才能正确匹配到对应的 Bean。Autowired 可以通过 @Qualifier 注解来显式指定名称,@Resource可以通过 name 属性来显式指定名称。
  • @Autowired 支持在构造函数、方法、字段和参数上使用。@Resource 主要用于字段和方法上的注入,不支持在构造函数或参数上使用。

Bean 的作用域

Spring 中 Bean 的作用域通常有下面几种:

  • singleton : IoC 容器中只有唯一的 bean 实例。Spring 中的 bean 默认都是单例的,是对单例设计模式的应用。
  • prototype : 每次获取都会创建一个新的 bean 实例。也就是说,连续 getBean() 两次,得到的是不同的 Bean 实例。
  • request (仅 Web 应用可用): 每一次 HTTP 请求都会产生一个新的 bean(请求 bean),该 bean 仅在当前 HTTP request 内有效。
  • session (仅 Web 应用可用) : 每一次来自新 session 的 HTTP 请求都会产生一个新的 bean(会话 bean),该 bean 仅在当前 HTTP session 内有效。
  • application/global-session (仅 Web 应用可用):每个 Web 应用在启动时创建一个 Bean(应用 Bean),该 bean 仅在当前应用启动时间内有效。
  • websocket (仅 Web 应用可用):每一次 WebSocket 会话产生一个新的 bean。

如何配置 bean 的作用域呢?

xml 方式:

<bean id="..." class="..." scope="singleton"></bean>

注解方式:

@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public Person personPrototype() {
    return new Person();
}

Bean 是线程安全的吗?

Spring 框架中的 Bean 是否线程安全,取决于其作用域和状态。

我们这里以最常用的两种作用域 prototype 和 singleton 为例介绍。几乎所有场景的 Bean 作用域都是使用默认的 singleton ,重点关注 singleton 作用域即可。

prototype 作用域下,每次获取都会创建一个新的 bean 实例,不存在资源竞争问题,所以不存在线程安全问题。singleton 作用域下,IoC 容器中只有唯一的 bean 实例,可能会存在资源竞争问题(取决于 Bean 是否有状态)。如果这个 bean 是有状态的话,那就存在线程安全问题(有状态 Bean 是指包含可变的成员变量的对象)。

不过,大部分 Bean 实际都是无状态(没有定义可变的成员变量)的(比如 Dao、Service),这种情况下, Bean 是线程安全的。

对于有状态单例 Bean 的线程安全问题,常见的有两种解决办法:

  1. 在 Bean 中尽量避免定义可变的成员变量。
  2. 在类中定义一个 ThreadLocal 成员变量,将需要的可变成员变量保存在 ThreadLocal 中(推荐的一种方式)。

Bean 的生命周期

聊透 Spring Bean 的生命周期

对 Prototype Bean 来说,当用户 getBean 获得 Prototype Bean 的实例后,IOC 容器就不再对当前实例进行管理,而是把管理权交由用户,此后再 getBean 生成的是新的实例。

所以我们描述 Bean 的生命周期,都是指的 Singleton Bean。

Spring的生命周期大致分为:创建 -> 属性填充 -> 初始化bean -> 使用 -> 销毁 几个核心阶段。我们先来简单了解一下这些阶段所做的事情:

  • 创建阶段:主要是创建对象,这里我们看到,对象的创建权交由Spring管理了,不再是我们手动new了,这也是IOC的概念。
  • 属性填充阶段:主要是进行依赖的注入,将当前对象依赖的bean对象,从Spring容器中找出来,然后填充到对应的属性中去。
  • 初始化bean阶段:做的事情相对比较复杂,包括回调各种Aware接口、回调各种初始化方法、生成AOP代理对象也在该阶段进行,该阶段主要是完成初始化回调,后面我们慢慢分析。
  • 使用bean阶段:主要是bean创建完成,在程序运行期间,提供服务的阶段。
  • 销毁bean阶段:主要是容器关闭或停止服务,对bean进行销毁处理。

当然,bean的生命周期中还包括其他的流程,比如暴露工厂对象等,只是相对而言都是为其他功能做伏笔和准备的。

标签:面试题,Resource,Spring,Bean,bean,注解,IoC
From: https://blog.51cto.com/coderge/7420005

相关文章

  • Spring - AOP常见面试题
    Spring-AOP推荐阅读:动态代理(JDKProxy&cjlib)AOP(Aspect-OrientedProgramming:面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维......
  • Spring boot与Spring cloud 之间的关系
    Springboot与Springcloud之间的关系Springboot是Spring的一套快速配置脚手架,可以基于springboot快速开发单个微服务,SpringBoot,看名字就知道是Spring的引导,就是用于启动Spring的,使得Spring的学习和使用变得快速无痛。不仅适合替换原有的工程结构,更适合微服务开发。Spring......
  • Spring boot与Spring cloud 之间的关系
    Springboot与Springcloud之间的关系Springboot是Spring的一套快速配置脚手架,可以基于springboot快速开发单个微服务,SpringBoot,看名字就知道是Spring的引导,就是用于启动Spring的,使得Spring的学习和使用变得快速无痛。不仅适合替换原有的工程结构,更适合微服务开发。Spri......
  • Spring,SpringMVC,SpringBoot,SpringCloud有什么区别?
    讲一讲Spring、SpringMVC、SpringBoot、SpringCloud之间的关系?Spring是核心,提供了基础功能;SpringMVC是基于Spring的一个MVC框架;SpringBoot是为简化Spring配置的快速开发整合包;SpringCloud是构建在SpringBoot之上的服务治理框架。Spring一般说Spring框架指......
  • SpringBoot框架实现一个简单的管理系统
    当然,我可以提供一个简单的示例代码,用SpringBoot框架实现一个简单的管理系统。以下是一个用户管理系统的示例代码:创建SpringBoot项目:使用SpringInitializr(https://start.spring.io/)创建一个新的SpringBoot项目,选择相应的依赖(如SpringWeb、SpringDataJPA、Thymeleaf等)。创建......
  • springboot 框架国际化 + thymeleaf
    项目目录结构注意:导入thymeleaf,web的pom依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency><dependency> <groupId>org.springframework.boot&l......
  • Android虚拟机原理面试题汇总(含详细解析 一)
    Android并发编程高级面试题汇总最全最细面试题讲解持续更新中......
  • SpringCloud - Feign
    目录Feign入门Feign入门先看RestTemplate发起远程调用的代码:Stringurl="http://userservice/user/"+order.getUserId();Useruser=restTemplate.getForObject(url,User.class);存在以下问题:代码可读性差,编程体验不统一参数复杂URL难以维护......
  • 一、SpringCloud Alibaba之普通应用
    1.1、创建一个maven项目新建项目操作路径:File->new->project输入相关的配置:Name:项目名称Location:项目所在位置ArtifactCoordinates:项目坐标(制品坐标)更改配置文件在项目中指定了打包方式为pom方式,此时项目目录下就不需要src目录,只保留一个pom.xml文件就行。创......
  • vue常见面试题
    1.vue优点?答:轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十kb;简单易学:国人开发,中文文档,不存在语言障碍,易于理解和学习;双向数据绑定:保留了angular的特点,在数据操作方面更为简单;组件化:保留了react的优点,实现了html的封装和重用,在构建单页面应用方面有着独特的优......