Java面试题———Spring篇①

目录

一,谈谈你对SpringIOC的理解

二,Spring中有哪些依赖注入方式

三,你用过哪些Spring注解

四,SpringBean的作用域有几种

五,Spring中的bean线程安全吗

六,谈谈你对SpringAOP的理解

七,AOP的代理有几种方式


一,谈谈你对SpringIOC的理解

IOC,也叫控制反转,是Spring用来解耦的一种设计思想,它的做法就是将对象的控制权由程序员手中反转到Spring手中。具体来说呢就是,在没有IOC之前,对象都是程序员在类中主动去创建,需要哪个创建哪个;有了IOC之后,对象会交给Spring容器创建和管理,如果哪个对象中需要其它对象属性,Spring也会自动完成依赖注入。

总之一句话,IOC可以将对象的创建和对象之间依赖关系的维护交给Spring自动完成。

二,Spring中有哪些依赖注入方式

依赖注入指的是Spring给对象中属性进行赋值的过程,主要包括两种方式:

  1. **构造器依赖注入:**构造器注入是指容器调用一个类的构造器创建对象时,直接传入给属性赋值

  2. **Setter方法注入:**Setter方法注入是指容器在创建对象完成后,通过调用属性的Setter 方法,可以属性赋值

三,你用过哪些Spring注解

我们常用的Spring注解主要分类下面几大类:

1、创建对象:@Component、@Controller、@Service、@Repository

它们都可以标注在自己开发的类上,Spring会使用注解标注的类创建出对象,然后放入容器

2、依赖注入:@Autowired

标注在属性或者属性对应的set方法上,Spring会根据被标注属性的类型自动对属性进行赋值

3、依赖注入:@Qualifier和@Autowired

一块使用,在同一类型的bean有多个的情况下Spring会根据name进行选择注入

4、配置类:@Configuration、@Bean

主要标注在配置类中,用于声明配置类和向Spring容器中放入一些配置有关的对象

5、当然还有一些平时用的不是特别多的

比如:声明注解扫描的@ComponentScan,声明Bean的作用域的@Scope,用于切面编程的@Around,@Pointcut等等

四,SpringBean的作用域有几种

在Spring中作用域是用来对象的存活范围的,它支持5种作用域

  • 第一种是单例,配置为单例的对象会跟随Spring容器创建而创建,跟随Spring容器销毁而销毁,在Spring容器中无论获取多少次单例对象,得到的都是同一个,这也是Spring中的对象的默认作用域

  • 第二种是多例,配置为多例的对象在每次获取的时候才会创建,而且每次获取到的都不一样

  • 还有三种分别是request、session和application,目前已经基本不再使用

其实,在我们平时的开发过程中,对象基本上都是配为单例的,这样可以有效的节省资源,只有单例对象存在线程安全问题时,才考虑调整为多例。

五,Spring中的bean线程安全吗

Spring中的Bean主要分为单例和多例

  1. 多例对象每次获取都会创建新实例,也就是说线程之间不存在Bean共享问题,也就不存在线程安全问题

  2. 单例对象是所有线程共享一个实例,因此就可能会存在线程安全问题。但是单例对象又分为无状态和有状态。

    • 无状态Bean是指只对对象的成员变量进行查询操作,不会修改成员变量的值,因此不存在线程安全问题

    • 有状态Bean需要对Bean中的成员变量进行数据更新操作,因此就可能存在线程安全问题

所以,最终我们得出结论,在Spring中,只有有状态的单例Bean才会存在线程安全问题

处理有状态单例Bean的线程安全问题有以下两种方法:

  1. 将Bean的作用域由单例改为多例

  2. 将需要的可变成员变量保存在ThreadLocal中, ThreadLocal本身就具备线程隔离的特性,这就相当于为每个线程提供了一个独立的变量副本,每个线程只需要操作自己的线程副本变量,从而解决线程安全问题。

六,谈谈你对SpringAOP的理解

AOP,又叫面向切面编程,核心思想是将那些与业务无关,却为业务模块所共同调用的逻辑(例如事务处理、日志管理)封装起来,然后再动态插入到业务中的功能

使用AOP可以减少系统的重复代码,降低模块间的耦合度,并有利于扩展和维护,Spring AOP是基于动态代理的,它底层同时支持JDK和CGLIB的代理方式,并且会根据被代理类是否有接口自动选择最合适的代理方式我们在开发中用到AOP的主要使用场景有:事务管理、日志、性能监视、安全检查

七,AOP的代理有几种方式

AOP思想的实现一般都是基于代理模式,在Java中一般采用JDK动态代理模式和CGLIB动态代理模式

  1. JDK动态代理模式只能对有接口的类进行代理,而且效率较高

  2. CGLIB可以对任意的类进行动态代理,但是效率上不如JDK

因此在进行代理时,如果被代理类有接口,就用JDK;如果没有接口,就用CGLIB

使用Spring的AOP,底层会自动按照这个规则进行选择,开发者也无需关心

相关推荐
雾月554 分钟前
LeetCode 1292 元素和小于等于阈值的正方形的最大边长
java·数据结构·算法·leetcode·职场和发展
24k小善1 小时前
Flink TaskManager详解
java·大数据·flink·云计算
想不明白的过度思考者1 小时前
Java从入门到“放弃”(精通)之旅——JavaSE终篇(异常)
java·开发语言
天天扭码1 小时前
总所周知,JavaScript中有很多函数定义方式,如何“因地制宜”?(ˉ﹃ˉ)
前端·javascript·面试
.生产的驴2 小时前
SpringBoot 封装统一API返回格式对象 标准化开发 请求封装 统一格式处理
java·数据库·spring boot·后端·spring·eclipse·maven
猿周LV2 小时前
JMeter 安装及使用 [软件测试工具]
java·测试工具·jmeter·单元测试·压力测试
晨集2 小时前
Uni-App 多端电子合同开源项目介绍
java·spring boot·uni-app·电子合同
时间之城2 小时前
笔记:记一次使用EasyExcel重写convertToExcelData方法无法读取@ExcelDictFormat注解的问题(已解决)
java·spring boot·笔记·spring·excel
椰羊~王小美2 小时前
LeetCode -- Flora -- edit 2025-04-25
java·开发语言
凯酱2 小时前
MyBatis-Plus分页插件的使用
java·tomcat·mybatis