百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 文章教程 > 正文

掌握这 28 道 Spring 面试题,你离成功更近一步!

xsobi 2024-12-14 15:46 1 浏览

1. 什么是Spring框架?

答案:Spring框架是一个开源的Java企业级应用程序开发框架,旨在简化企业级应用程序的开发。它提供了一个全面的编程和配置模型,用于构建任何类型的应用程序。Spring框架的核心特性包括依赖注入(Dependency Injection,DI)、面向切面编程(Aspect-Oriented Programming,AOP)、事务管理、数据访问、Web应用支持等。


2. Spring框架的核心模块有哪些?

答案:Spring框架的核心模块主要包括:

(1)Core Container:包括Beans、Core、Context、SpEL等模块,提供了Spring的基本功能,如IoC容器、Bean管理、表达式语言等。

(2)Data Access/Integration:包括JDBC、ORM、OXM、JMS、Transaction等模块,提供了数据库访问和事务管理的支持。

(3)Web:包括Web-Servlet、Web-Struts、Web-Portlet等模块,提供了Web应用开发的支持。

(4)AOP and Instrumentation:提供了面向切面编程的支持,以及类的字节码操作和类的加载器支持。

(5)Test:支持单元测试和集成测试。


3. 什么是控制反转(IoC)?

答案:控制反转(Inversion of Control,IoC)是一种设计模式,用于减少代码间的耦合度。在传统编程中,对象的创建和管理是由程序员自己负责的,而在使用IoC的情况下,对象的创建和依赖关系的管理交给了容器,对象之间的依赖关系由容器在运行时动态地创建和管理,而不是在编译时静态地确定。


4. Spring中的依赖注入(DI)有哪些方式?

答案:Spring中的依赖注入主要有三种方式:

(1)构造器注入:通过构造函数来注入依赖。

(2)Setter方法注入:通过setter方法来注入依赖。

(3)字段注入:直接在字段上使用`@Autowired`注解来注入依赖。


5. 什么是AOP(面向切面编程)?

答案:AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,旨在提高模块化程度,特别是在处理横切关注点(如日志记录、事务管理、安全检查等)时。AOP允许开发者将这些横切关注点从业务逻辑中分离出来,从而减少代码重复,提高代码的可维护性和可扩展性。


6. Spring中的事务管理有哪些方式?

答案:Spring中的事务管理主要有两种方式:

(1)编程式事务管理:通过编程的方式手动管理事务的开始、提交和回滚。

(2)声明式事务管理:通过配置文件或注解(如`@Transactional`)来声明事务的边界,由Spring框架自动管理事务。


7. Spring中的Bean生命周期有哪些阶段?

答案:Spring中的Bean生命周期主要包括以下几个阶段:

(1)实例化:Spring容器创建Bean的实例。

(2)属性赋值:为Bean的属性赋值。

(3)初始化:调用初始化方法,如`@PostConstruct`注解的方法或`init-method`配置的方法。

(4)使用:Bean可以被其他Bean使用。

(5)销毁:当容器关闭时,调用销毁方法,如`@PreDestroy`注解的方法或`destroy-method`配置的方法。


8. Spring中的Bean作用域有哪些?

答案:Spring中的Bean作用域包括:

(1)singleton:单例模式,一个Spring容器中只有一个Bean实例。

(2)prototype:原型模式,每次请求都会创建一个新的Bean实例。

(3)request:每次HTTP请求都会创建一个新的Bean实例,仅在Web应用中有效。

(4)session:每个HTTP Session都会创建一个新的Bean实例,仅在Web应用中有效。

(5)global session:全局Session,通常在Portal应用中使用。


9. Spring中的BeanFactory和ApplicationContext有什么区别?

答案:`BeanFactory`和`ApplicationContext`都是Spring的IoC容器,但`ApplicationContext`提供了更多的企业级功能,如:

a.国际化的消息源支持。

b.事件传播。

c.应用层特定的上下文,如Web应用中的`WebApplicationContext`。

d.加载多个配置文件。

e.对AOP的支持。


10. Spring如何解决循环依赖问题?

答案:Spring通过三级缓存来解决循环依赖问题:

一级缓存(singletonObjects):存放完全初始化好的Bean。

二级缓存(earlySingletonObjects):存放未完全初始化的Bean(即只完成了实例化,但还未完成属性填充和初始化)。

三级缓存(singletonFactories):存放Bean的ObjectFactory,用于创建Bean实例。

当Spring检测到循环依赖时,它会尝试从二级或三级缓存中获取Bean,从而避免死锁。如果仍然无法解决,则会抛出异常。


11. Spring中的事务传播行为有哪些?

答案:

Spring中的事务传播行为定义了事务方法如何与调用者的方法交互。主要的传播行为包括:

(1)REQUIRED:如果当前存在事务,则加入该事务;否则,创建新的事务。

(2)REQUIRES_NEW:创建新的事务,如果当前存在事务,则暂停当前事务。

(3)SUPPORTS:如果当前存在事务,则加入该事务;否则,以非事务方式执行。

(4)NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,则暂停当前事务。

(5)MANDATORY:如果当前存在事务,则加入该事务;否则,抛出异常。

(6)NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。

(7)NESTED:如果当前存在事务,则在嵌套事务内执行;否则,创建新的事务。


12. Spring中的AOP通知类型有哪些?

答案:

Spring中的AOP通知类型包括:

(1)Before Advice:在方法调用之前执行。

(2)After Returning Advice:在方法成功返回之后执行。

(3)After Throwing Advice:在方法抛出异常后执行。

(4)After (Finally) Advice:无论方法是否成功返回或抛出异常,都会执行。

(5)Around Advice:在方法调用前后都执行,可以控制方法的执行。


13. Spring中的Bean生命周期回调方法有哪些?

答案:

Spring中的Bean生命周期回调方法包括:

(1)初始化回调:

`@PostConstruct` 注解的方法。

实现 `InitializingBean` 接口的 `afterPropertiesSet` 方法。

在配置文件中使用 `init-method` 属性指定的方法。

(2)销毁回调:

`@PreDestroy` 注解的方法。

实现 `DisposableBean` 接口的 `destroy` 方法。

在配置文件中使用 `destroy-method` 属性指定的方法。

14. Spring中的事务隔离级别有哪些?

答案:

Spring中的事务隔离级别包括:

READ_UNCOMMITTED:最低的隔离级别,允许脏读、不可重复读和幻读。

READ_COMMITTED:允许不可重复读和幻读,但不允许脏读。

REPEATABLE_READ:允许幻读,但不允许脏读和不可重复读。

SERIALIZABLE:最高的隔离级别,不允许脏读、不可重复读和幻读。


15. Spring中的Bean工厂后处理器(BeanFactoryPostProcessor)和Bean后处理器(BeanPostProcessor)有什么区别?

答案:

(1)BeanFactoryPostProcessor:在所有Bean定义加载完成后但在任何Bean实例化之前执行。常用于修改Bean定义,例如使用`PropertyPlaceholderConfigurer`来解析占位符。

(2)BeanPostProcessor:在Bean实例化后但在任何初始化回调(如`@PostConstruct`、`init-method`)之前执行。常用于自定义Bean的初始化逻辑,例如添加额外的属性或验证Bean的状态。


16. Spring中的事务管理器(PlatformTransactionManager)有哪些实现?

答案:

Spring中的事务管理器实现包括:

(1)DataSourceTransactionManager:用于管理JDBC数据源的事务。

(2)JpaTransactionManager:用于管理JPA的事务。

(3)HibernateTransactionManager:用于管理Hibernate的事务。

(4)JtaTransactionManager:用于管理全局事务,支持分布式事务。


17. Spring中的事件机制是如何工作的?

答案:

Spring中的事件机制包括以下几个步骤:

(1)发布事件:通过 `ApplicationEventPublisher` 发布事件,通常在Bean中注入 `ApplicationEventPublisher` 并调用 `publishEvent` 方法。

(2)定义事件:创建一个继承自 `ApplicationEvent` 的类,表示具体的事件。

(3)监听事件:创建一个实现 `ApplicationListener` 接口的类,或者使用 `@EventListener` 注解的方法来监听事件。

(4)处理事件:当事件被发布时,Spring会调用相应的监听器方法来处理事件。


18. Spring中的异步任务是如何实现的?

答案:

Spring中的异步任务可以通过以下几种方式实现:

(1)@async? 注解:在方法上使用 `@Async` 注解,使该方法异步执行。需要在配置类中启用异步支持,例如使用 `@EnableAsync` 注解。

(2)TaskExecutor:通过 `TaskExecutor` 接口来执行异步任务,可以在配置文件中定义 `TaskExecutor` 的实现类。

(3)Future 和 `CompletableFuture:可以使用 `Future` 或 `CompletableFuture` 来获取异步任务的结果。


19. Spring中的AOP如何实现?

答案:

Spring AOP的实现主要基于代理模式。Spring AOP使用两种代理方式:

(1)JDK动态代理:适用于实现了接口的类。通过`Proxy.newProxyInstance`方法生成代理对象。

(2)CGLIB代理:适用于没有实现接口的类。通过CGLIB库生成目标类的子类作为代理对象。


20. Spring中的事务管理如何实现?

答案:

Spring事务管理的实现主要通过AOP和事务管理器(`PlatformTransactionManager`)来完成。具体步骤如下:

(1)事务管理器:`PlatformTransactionManager`接口负责管理事务的开始、提交和回滚。常见的实现有`DataSourceTransactionManager`、`JpaTransactionManager`等。

(2)事务拦截器:Spring使用`TransactionInterceptor`来拦截事务方法,根据事务属性(如传播行为、隔离级别等)来管理事务。

(3)事务同步管理:Spring通过`TransactionSynchronizationManager`来管理事务同步,确保在事务的不同阶段(如提交前、提交后、回滚前、回滚后)执行相应的操作。


21. Spring中的`@Transactional`注解如何生效?

答案:

`@Transactional`注解通过以下步骤生效:

(1)元数据解析:Spring容器在启动时解析带有`@Transactional`注解的方法和类,提取事务属性。

(2)代理生成:Spring为带有`@Transactional`注解的类生成代理对象。如果类实现了接口,使用JDK动态代理;如果没有实现接口,使用CGLIB代理。

(3)事务拦截:生成的代理对象包含事务拦截器(`TransactionInterceptor`),在方法调用前后插入事务管理逻辑。

(4)事务管理:事务拦截器根据事务属性(如传播行为、隔离级别等)管理事务的开始、提交和回滚。


22 . Spring中的`@Configuration`和`@Bean`注解有什么作用?

答案:

(1)@Configuration:标记一个类为配置类,该类中的方法可以用来定义Bean。配置类替代了传统的XML配置文件。

(22)@Bean:标记在一个方法上,表示该方法返回的对象将被注册为Spring容器中的Bean。`@Bean`方法可以定义Bean的生命周期、作用域等属性。


23. Spring中的`@Profile`注解如何使用?

答案:

`@Profile`注解用于根据环境激活不同的Bean。常见用法包括:

(1)类级别:标记一个配置类或Bean类,只有在指定的环境激活时,该类才会被加载。

@Configuration

@Profile("dev")

public class DevConfig {

@Bean

public DataSource dataSource() {

// 返回开发环境的数据源

}

}

(2)方法级别:标记在`@Bean`方法上,只有在指定的环境激活时,该方法才会被调用。

@Configuration

public class AppConfig {

@Bean

@Profile("prod")

public DataSource dataSource() {

// 返回生产环境的数据源

}

}


24. Spring中的`@Conditional`注解如何使用?

答案:

`@Conditional`注解用于根据条件决定是否创建Bean。常见的条件注解包括:

(1)@ConditionalOnClass:当类路径中存在指定类时,创建Bean。

(2)@ConditionalOnMissingClass:当类路径中不存在指定类时,创建Bean。

(3)@ConditionalOnProperty:当配置文件中存在指定属性时,创建Bean。

(4)@ConditionalOnBean:当容器中存在指定Bean时,创建Bean。

(5)@ConditionalOnMissingBean:当容器中不存在指定Bean时,创建Bean。


25. Spring中的`@Transactional`注解在哪些情况下不会生效?

答案:

`@Transactional`注解在以下情况下可能不会生效:

(1)自我调用:同一个类中的方法调用另一个带有`@Transactional`注解的方法时,事务不会生效,因为代理对象无法拦截到内部调用。

(2)事务管理器未配置:如果没有正确配置`PlatformTransactionManager`,事务管理将无法正常工作。

(3)异常类型:默认情况下,只有未捕获的`RuntimeException`和`Error`会触发事务回滚,捕获的异常或`CheckedException`不会触发回滚,除非显式配置。

(4)代理问题:如果使用了非标准的代理方式(如CGLIB代理),可能会导致事务管理失效。


26. Spring中的`@Value`和`@Autowired`有什么区别?

答案:

(1)@Value:用于注入基本类型和String类型的值,也可以注入属性文件中的值。支持SpEL表达式。

@Value("${app.name}")

private String appName;

(2)@Autowired:用于注入其他Bean,支持按类型和按名称注入。默认按类型注入,如果多个Bean匹配,可以使用`@Qualifier`指定名称。

@Autowired

private DataSource dataSource;


17. Spring中的`@RestController`和`@Controller`有什么区别?

答案:

(1)@Controller:标记一个类为Spring MVC控制器,通常用于处理HTTP请求。返回值通常是ModelAndView对象,需要经过视图解析器解析。

(2)@RestController:是`@Controller`和`@ResponseBody`的组合注解,标记一个类为RESTful控制器。返回值直接作为响应体返回,不需要经过视图解析器。


28. Spring中的`@Scheduled`注解如何使用?

答案:

`@Scheduled`注解用于定时任务的调度。使用步骤如下:

(1)启用定时任务:在配置类中使用`@EnableScheduling`注解启用定时任务。

@Configuration

@EnableScheduling

public class SchedulingConfig {

}

(2)定义定时任务:在方法上使用`@Scheduled`注解,指定定时任务的执行规则。

@Component

public class ScheduledTasks {

@Scheduled(fixedRate = 5000)

public void performTask() {

System.out.println("Task executed at " + new Date());

}

}


#JAVA#?#spring#?#spring框架#?#spring面试题#?#面试题#?#技术干货#

欢迎评论区留言讨论!??

相关推荐

js向对象中添加元素(对象,数组) js对象里面添加元素

一、添加一个元素对象名["属性名"]=值(值:可以是一个值,可以是一个对象,也可以是一个数组)这样添加进去的元素,就是一个值或对象或数组...

JS小技巧,如何去重对象数组?(一)

大家好,关于数组对象去重的业务场景,想必大家都遇到过类似的需求吧,这对这样的需求你是怎么做的呢。下面我就先和大家分享下如果是基于对象的1个属性是怎么去重实现的。方法一:使用.filter()和....

「C/C++」之数组、vector对象和array对象的比较

数组学习过C语言的,对数组应该都不会陌生,于是这里就不再对数组进行展开介绍。模板类vector模板类vector类似于string,也是一种动态数组。能够在运行阶段设置vector对象的长度,可以在末...

如何用sessionStorage保存对象和数组

背景:在工作中,我将[{},{}]对象数组形式,存储到sessionStorage,然后ta变成了我看不懂的形式,然后我想取之用之,发现不可能了~记录这次深刻的教训。$clickCouponIndex...

JavaScript Array 对象 javascript的array对象

Array对象Array对象用于在变量中存储多个值:varcars=["Saab","Volvo","BMW"];第一个数组元素的索引值为0,第二个索引值为1,以此类推。更多有...

JavaScript中的数组Array(对象) js array数组

1:数组Array:-数组也是一个对象-数组也是用来存储数据的-和object不同,数组中可以存储一组有序的数据,-数组中存储的数据我们称其为元素(element)-数组中的每一个元素都有一...

数组和对象方法&数组去重 数组去重的5种方法前端

列举一下JavaScript数组和对象有哪些原生方法?数组:arr.concat(arr1,arr2,arrn);--合并两个或多个数组。此方法不会修改原有数组,而是返回一个新数组...

C++ 类如何定义对象数组?初始化数组?linux C++第43讲

对象数组学过C语言的读者对数组的概念应该很熟悉了。数组的元素可以是int类型的变量,例如int...

ElasticSearch第六篇:复合数据类型-数组,对象

在ElasticSearch中,使用JSON结构来存储数据,一个Key/Value对是JSON的一个字段,而Value可以是基础数据类型,也可以是数组,文档(也叫对象),或文档数组,因此,每个JSON...

第58条:区分数组对象和类数组对象

示例设想有两个不同类的API。第一个是位向量:有序的位集合varbits=newBitVector;bits.enable(4);bits.enable([1,3,8,17]);b...

八皇后问题解法(Common Lisp实现)

如何才能在一张国际象棋的棋盘上摆上八个皇后而不致使她们互相威胁呢?这个著名的问题可以方便地通过一种树搜索方法来解决。首先,我们需要写一个函数来判断棋盘上的两个皇后是否互相威协。在国际象棋中,皇后可以沿...

visual lisp修改颜色的模板函数 怎么更改visual studio的配色

(defunBF-yansemokuai(tuyuanyanse/ss)...

用中望CAD加载LISP程序技巧 中望cad2015怎么加载燕秀

1、首先请加载lisp程序,加载方法如下:在菜单栏选择工具——加载应用程序——添加,选择lisp程序然后加载,然后选择添加到启动组。2、然后是添加自定义栏以及图标,方法如下(以...

图的深度优先搜索和广度优先搜索(Common Lisp实现)

为了便于描述,本文中的图指的是下图所示的无向图。搜索指:搜索从S到F的一条路径。若存在,则以表的形式返回路径;若不存在,则返回nil。...

两个有助于理解Common Lisp宏的例子

在Lisp中,函数和数据具有相同的形式。这是Lisp语言的一个重大特色。一个Lisp函数可以分析另一个Lisp函数;甚至可以和另一个Lisp函数组成一个整体,并加以利用。Lisp的宏,是实现上述特色的...