目录
4.什么是Spring IOC?什么是Spring IOC容器?有什么作用?
6.什么是Spring的依赖注入(DI)?IOC和DI有什么关系?
24.Spring容器启动时,为什么先加载BeanFactoryPostProcess?
26.@Component, @Controller, @Service ,@Repository, @Bean有何区别?
一、Spring
1.谈谈你对Spring的理解?/ 什么是Spring?
Spring是一个轻量级IOC(控制反转)和AOP(面向切面编程)的容器框架
2.Spring有什么特点?
(1)方便解耦,简化开发:通过Spring提供的IOC容器集中管理对象,降低了对象之间的耦合度
(2)AOP(面向切面编程):在不修改代码的前提下,可以对业务代码进行增强,提高开发效率
(3)声明事务:提高开发效率,只需 @Transactional 注解开启事务
(4)方便集成各种优秀框架
3.Spring 框架中都用到了哪些设计模式?
(1)工厂模式--创建Bean
(2)单例模式--单例Bean
(3)适配器模式--Spring MVC中的HandlerAdapter
(4)代理模式--AOP功能的实现
(5)观察者模式--Spring 事件监听
二、Spring IOC
4.什么是Spring IOC?什么是Spring IOC容器?有什么作用?
(1)Spring IOC,是一种控制反转的思想,将对象的控制权转移给Spring IOC容器
(2)Spring IOC容器:负责创建对象、管理对象。如果需要使用对象,则通过DI(依赖注入)@Autowired 自动注入,从而使用对象。
(3)作用:集中管理对象,降低对象之间的耦合度。
5.Spring IOC的实现机制是什么?
Spring IOC 的实现原理是工厂模式+反射机制
6.什么是Spring的依赖注入(DI)?IOC和DI有什么关系?
(1)DI允许Spring IOC容器将一个对象所需要的依赖注入(@Autowired),而不是让对象自己创建。
(2)IOC是一种控制反转的思想,DI是IOC的一种实现方式。
7.紧耦合和松耦合有什么区别?
(1)紧耦合:类之间高度依赖
(2)松耦合:通过促进单一职责、关注点分离、依赖倒置等设计原则来实现
8.BeanFactory 有什么作用?
是Bean的“工厂”,主要负责创建和管理Bean
9.BeanDefinition 有什么作用?
主要负责存储Bean的定义信息,决定Bean的生产方式。(BeanFactory会根据BeanDefinition创建Bean)
10.Spring IOC容器的加载过程?
(1)Spring IOC容器加载配置信息
(2)创建上下文:Spring IOC容器根据配置信息创建ApplicationContext(上下文)
(3)创建和管理Bean:Spring IOC容器根据配置信息创建Bean实例,然后根据Bean的定义创建依赖关系。
(4)初始化Bean
三、Spring Bean
11.什么是Spring Bean?
Bean是由Spring IOC容器管理的对象
12.配置Bean有哪些方式?
(1)XML配置:
(2)注解配置:@Component(@Controller 、@Service、@Repostory、@Configuration)
(3)JavaConfig:@Bean 可以控制实例化
13.Spring Bean的作用域有哪些?
(1)singleton(默认单例):在Spring IOC容器只存在一个Bean实例。
(2)prototype(开销大):每次从容器中调用Bean都会创建一个新实例。
(3)request:每次http请求都会创建一个Bean。(仅在基于web的Spring ApplicantionContext中有效)
(4)session:在一个http session中只存在一个Bean实例。(仅在基于web的Spring ApplicantionContext中有效)
(5)application:在Web应用中只存在一个Bean实例。(仅在基于web的Spring ApplicantionContext中有效)
14.单例Bean的优势是什么?
(1)减少创建实例的开销
(2)减少JVM垃圾回收
(3)快速获取Bean(除首次加载Bean,后续都是在缓存中获取)
15.Spring实例化Bean有哪些方式?
(1)构造方法实例化
(2)静态工厂实例化
(3)实例工厂实例化
(4)FactoryBean实例化
16.Spring中的单例Bean是线程安全的吗?
线程不安全。单例 bean 在 Spring 容器中只存在一个实例,并且会被多个线程共享。如果这个 bean 包含可变的共享状态,那么在多线程环境下可能会出现线程安全问题。
改变Bean的作用域,把"singleton"改为"prototype",prototype 每次调用都实例化Bean,保证了线程安全,但是开销大。
17.Spring如何处理线程并发问题?
(1)设置Bean的作用域为prototype
(2)设置无状态Bean,避免成员变量,或将成员变量设计为不可变(final)
(3)事务管理(@Transactional)
(4)并发控制(@Lock)
(5)异步处理(@Async)
18.什么是Bean的自动装配?
Spring IOC容器自动管理Bean之间的依赖关系
19.Bean的自动装配有哪些限制?
(1)模糊性问题:存在多个匹配的候选Bean,可能无法明确自动装配哪个
(2)基本数据类型和字符串无法自动装配
(3)非public修饰的字段和方法无法自动装配
(4)可能导致循环依赖问题
所以,更推荐手动注入依赖(@Autowired)
20.Spring自动装配Bean有哪些方式?
(1)no(默认):不进行自动装配。使用@Autowired手动注入依赖
(2)byName:通过Bean的名称自动装配
(3)byType:通过参数的数据类型进行自动装配
(4)constructor:通过构造函数进行自动装配,并且构造函数的参数通过byType进行自动装配
21.Bean的生命周期有哪些回调方法?
(1)初始化回调方法:@PostConstruct
(2)销毁回调方法:@PreDestroy
22.Bean的生命周期有哪些?
(1)实例化:通过构造方法、静态工厂、实例工厂实例化
(2)属性赋值:构造函数、set、依赖注入赋值
(3)初始化:调用初始化回调函数,@PostConstruct
(4)运行
(5)销毁:调用销毁回调函数,@PreDestroy
23.Spring 是如何解决Bean循环依赖?
三级缓存机制,有效解决Bean之间的循环依赖
(1)一级缓存:存放完全创建好的单例Bean。
Spring 获取Bean,首先从一级缓存查找,如果找到,则直接返回。
(2)二级缓存:存放早期Bean实例(Bean实例已创建,但还未完成属性赋值和初始化)
一级缓存没找到,查找二级缓存,如果找到,则返回早期Bean实例
(3)三级缓存:存放 ObjectFactory 对象(可获取早期Bean实例)
二级缓存没找到,Spring从三级缓存中获取 ObjectFactory对象,从而获取早期Bean实例,并将其放入二级缓存。Spring 继续完成该Bean的属性赋值和初始化等操作,最终将完全创建好的Bean放入一级缓存。
24.Spring容器启动时,为什么先加载BeanFactoryPostProcess?
先加载BeanFactoryPostProcess是为了在Spring IOC容器启动的早期阶段对BeanDefinition 进行修改和定制。这不仅提高了容器的灵活性和可扩展性,还优化了后续 bean 实例化和依赖注入,从而使容器更好地适应各种复杂的应用需求。
四、Spring 注解
25.JavaConfig如何进行Spring配置?
(1)@Configuration 配置类注解
(2)@Bean @Scope
(3)@PropertySource注解加载外部属性文件,并通过@Value注解来注入属性值
@Configuration
@PropertySource("classpath:application.properties")
public class SpringConfig {
@Value("${my.property}")
private String myProperty;
@Bean
public MyService myService() {
return new MyServiceImpl(myProperty);
}
}
26.@Component, @Controller, @Service ,@Repository, @Bean有何区别?
(1)@Component,注册为普通的业务 Bean
(2)@Controller,注册为Spring MVC 控制器 Bean
(3)@Service,注册为服务层 Bean
(4)@Repository,注册为数据库访问层 Bean
(5)@Bean,简化版的@Component,适用于配置类中定义Bean
27.@Autowired和@Resource有什么区别?
@Autowired | @Resource | |
来源 | Spring 注解 | Java 注解 |
注入方式 | 默认按照类型进行自动装配 | 默认先按照名称自动装配; 如果没匹配到名称,再按照类型进行自动装配 |
五、Spring AOP
28.什么是Spring AOP?有什么作用?
Spring AOP(面向切面编程),通过将横切关注点(作用:日志记录、事务管理、权限控制、性能监控、异常处理等)从业务逻辑中分离出来,以实现更清晰的代码结构和更高的可维护性。
29.解释一下Spring AOP里面的几个名词?
(1)切面(Aspect):定义横切关注点的类或接口
(2)连接点(Join point):指定要增强的业务方法
(3)通知(Advice):
前置通知(Before):目标方法调用之前通知
后置通知(After):目标方法调用之后通知(不管是否成功都通知)
返回通知(After-returning):目标方法执行成功之后通知
异常通知(After-throwing):目标方法抛出异常后通知
环绕通知(Around):目标方法调用之前和调用之后通知
(4)切入点(Pointcut):指定切面应该在哪些位置切入
(5)目标对象(Target Object):要增强的对象
(6)织入(Weaving):创建动态代理
30.Spring AOP的完整实现流程?
定义切面、切点、通知,注解开启AOP( @EnableAspectJAutoProxy )
/**
* 定义切面
*/
@Aspect
@Component
public class LoggingAspect {
// 定义切点,匹配以com.example.service..* 开头的方法
@Pointcut("execution(* com.example.service..*(..))")
public void logAllServiceMethods() {}
// 前置通知
@Before("logAllServiceMethods()")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Before executing: " + joinPoint.getSignature().getName());
}
// 返回通知
@AfterReturning("logAllServiceMethods()")
public void logAfterReturning(JoinPoint joinPoint) {
System.out.println("After returning from: " + joinPoint.getSignature().getName());
}
// 异常通知
@AfterThrowing("logAllServiceMethods()")
public void logAfterThrowing(JoinPoint joinPoint, Throwable throwable) {
System.out.println("After throwing from: " + joinPoint.getSignature().getName());
}
}
六、Spring 事务
31.事务的四大特性(ACID)
(1)原子性(Atomicity):事务的所有操作要么同时成功,要么同时失败。
(2)一致性(Consistency):事务操作前后,不能破坏数据库的完整性和一致性。
如:A转账给B,不可能因为A扣了钱,而B账户没有加钱
(3)隔离性(Isolation):多个事务之间,相互独立。
(4)持久性(Duration):当事务提交或回滚后,持久化到数据库。
32.Spring 事务的实现方式有哪些?
(1)编程式事务
(2)声明式事务(基于注解:@Transactional、基于XML配置)
33.说一下Spring 事务的传播行为?
事务传播行为 | 如果外部不存在事务 | 如果外部存在事务 |
REQUIRED(默认) | 开启新的事务 | 加入到外部事务 |
SUPPORTS | 不开启新的事务 | 加入到外部事务 |
REQUIRES_NEW | 开启新的事务 | 不用外部事务,创建新事物 |
NOT_SUPPORTED | 不开启新的事务 | 不用外部事务 |
NEVER | 不开启新的事务 | 抛出异常 |
MANDATORY | 抛出异常 | 加入到外部事务 |
NESTED | 开启新的事务 | 加入到外部事物,内外部事务互不影响 |
34.Spring 事务的隔离级别?
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
Read Uncommitted(读未提交) | √ | √ | √ |
Read Committed(读已提交) | × | √ | √ |
Repeatable Read(可重复读) (MySQL默认) | × | × | √ |
Serializable (串行化) | × | × | × |
35.多事务引发的问题?如何解决?
(1)脏读:一个事务,读到其他事务未提交的数据(读了脏数据)
解决方式:<1> 写操作加排他锁,直到事务提交才释放;
读操作加共享锁,直到读完才释放。
<2> 设置事务隔离级别为读已提交
(2)不可重复度:在同一个事务中,两次读的数据不一致
解决方式:<1> 写操作加排他锁,直到事务提交才释放;
读操作加共享锁,直到读完才释放。
<2> 设置事务隔离级别为可重复读
(3)幻读:在同一个事务中,用同样的操作查询的记录数不一致
解决方式:<1> 加范围锁
<2> 设置事务隔离级别为串行化
36. Spring 事务失效的原因?
(1)方法权限问题:private 方法会失效
解决方式:改为 public
(2)目标类未被Spring IOC容器管理
解决方式:配置为 Bean
(3)异常处理不当
解决方式:不要捕获异常
七、Spring MVC(web层框架)
37.请描述Spring MVC的工作流程?/ 描述一下DispatcherServlet的工作流程?
(1)客户端发送请求,DispatcherServlet(前端控制器)拦截请求,DispatcherServlet在HandlerMapping(处理器映射器)寻找对应的Handler(处理器)并返回。然后根据这个Handler去寻找对应的HandlerAdapter(处理器适配器);
(2)HandlerAdapter调用对应的Handler方法。即,执行我们的Controller来处理业务逻辑了,执行完返回ModeAndView;
(3)把ModeAndView返给ViewResolver(视图解析器),解析完返回对应的View(视图);
(4)最后渲染视图,返回给客户端。
八、Spring Boot
38.谈谈你对Spring Boot的理解,它有哪些特性?
Spring Boot是用来快速开发Spring应用的脚手架,旨在简化Spring应用的开发。
(1)Spring Boot提供了丰富的starter,对主流框架无配置集成、开箱即用
(2)Spring Boot内置Web服务器(Tomcat、Jetty)
(3)Spring Boot管理第三方依赖的版本,减少版本冲突
(4)Spring Boot自带监控功能,可以监控应用的运行状态(内存、线程池等)。
39.SpringBoot的核心注解
(1)@SpringBootApplication:标识这是一个Spring Boot工程启动类
(2)@SpringBootConfiguration:标识启动类也是一个配置类
(3)@EnableAutoConfiguration:开启自动配置
(4)@ComponentScan:扫描@Component、@Controller、@Service、@Repository类
(5)@Autowired:自动配置
40.为什么Spring Boot的jar可以直接运行?
(1)Spring Boot提供了spring-boot-maven-plugin插件将程序打成可执行jar包
(2)jar包中包含了应用所依赖的jar和相关类
(3)java -jar 在jar中找manifest文件,这里是jar的启动类
(4)启动类的main函数是JarLauncher,加载jar并以一个新线程启动main函数
41.Spring Boot的自动装配原理?
(1)@SpringBootApplication引入了@EnableAutoConfiguration(负责启动自动装配功能)
@EnableAutoConfiguration引入了@Import
(2)Spring容器启动时,IOC容器会解析@Import
(3)@Import 导入了一个deferredImportSelector(使SpringBoot的自动配置类的顺序在最后,方便扩展和覆盖)
(4)然后读取所有/META-INF/spring.factories文件
(5)过滤出所有AutoConfigurationClass
(6)最后通过@ConditionOnXXX排除无效的自动配置类
42.Spring Boot的启动原理?
(1)运行main方法:初始化SpringApplication,从spring.factories 读取 listener ApplicationContextInitializer
(2)运行run方法
(3)读取配置信息、环境变量
(4)创建上下文
(5)初始化上下文:将配置注册为BeanDefinition
(6)调用refresh刷新上下文
invokeBeanFactoryPostProcessor,解析@Import,加载所有的自动配置类
onRefresh 创建内置的Web服务器
(7)还会调用监听器对外扩展
43.Spring Boot内置Tomcat启动原理?
(1)spring-boot-starter-web 依赖会在SpringBoot添加ServletWebServerFactoryAutoConfiguration自动配置类
(2)该自动配置类通过@Import导入了一个Web容器工厂
(3)Web容器工厂默认使用内嵌的Tomcat,在Tomcat类中配置了一个TomcatServletWebFactory的Bean
(4)会在SpringBoot启动时,refresh刷新上下文加载Bean,调用OnRefresh创建内嵌的Tomcat并启动
44.如何自定义SpringBoot Starter?
(1)创建一个@Configuration配置类,定义Bean
(2)在 resource 下创建 META-INF 包,在包下创建 spring.factorie 文件
(3)spring.factories 开启自动配置
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.starter.tulingxueyuan.HelloAutoConfitguration
45.Spring和SpringBoot有什么区别和联系?
Spring是一个轻量级IOC(控制反转)和AOP(面向切面编程)的容器框架。
Spring Boot是Spring生态的产品,旨在简化Spring应用的开发。
联系:Spring Boot 依赖于 Spring 的核心功能,对 Spring 进一步优化和简化,提高开发效率。
标签:容器,面试题,Java,Spring,Boot,事务,Bean,IOC From: https://blog.csdn.net/qq_58159506/article/details/141217748