@Autowired和@Resource两个注解的区别
@Autowired:
是Spring框架的注解,用于依赖注入。
默认按照类型(byType)注入,如果存在多个相同类型的Bean,则会报错。
可以通过@Qualifier指定具体的Bean名称。
如果没有匹配的Bean,会抛出BeanCreationException。
@Resource:
是Java标准注解(JSR-250),也用于依赖注入。
默认按照名称(byName)注入,如果没有指定名称,则按照类型注入。
如果没有匹配的Bean,不会报错,而是注入null。
总结:
@Autowired更灵活,支持按类型和按名称注入。
@Resource更符合Java标准,但功能相对简单。
2. Spring中是如何解决循环依赖问题的
Spring通过三级缓存机制解决循环依赖问题:
一级缓存(singletonObjects):存储完全初始化完成的Bean。
二级缓存(earlySingletonObjects):存储正在初始化的Bean的原始代理对象。
三级缓存(singletonFactories):存储Bean的ObjectFactory,用于延迟初始化。
当检测到循环依赖时,Spring会将尚未完全初始化的Bean放入二级缓存中,从而避免直接引用未初始化的Bean。
3. Spring中是如何解决构造注入的循环依赖问题的
Spring默认不支持构造注入的循环依赖。构造注入的循环依赖会导致无法解决的依赖问题,因为构造器注入的Bean必须在构造时完成依赖注入。Spring会在检测到构造注入的循环依赖时抛出异常,提示用户重新设计Bean的依赖关系。
4. Spring中的循环依赖为什么需要三级缓存
三级缓存的设计是为了在解决循环依赖时,能够灵活地处理Bean的初始化状态:
一级缓存确保完全初始化的Bean可以被安全使用。
二级缓存允许在Bean初始化过程中被其他Bean引用。
三级缓存提供了一种延迟初始化的机制,避免了直接引用未完成初始化的Bean。
5. Spring中Bean对象的生命周期
Spring Bean的生命周期包括以下阶段:
实例化:通过BeanDefinition创建Bean实例。
属性注入:通过Autowired或@Value注入依赖。
初始化:
调用BeanPostProcessor的postProcessBeforeInitialization方法。
调用InitializingBean的afterPropertiesSet方法或@PostConstruct注解的方法。
调用BeanPostProcessor的postProcessAfterInitialization方法。
使用:Bean可以被其他Bean引用。
销毁:
调用DisposableBean的destroy方法或@PreDestroy注解的方法。
调用BeanPostProcessor的postProcessBeforeDestruction方法
。
6. Spring中支持的作用域有几种
Spring支持以下几种作用域:
singleton:单例作用域,默认值。每个Spring容器中只有一个Bean实例。
prototype:原型作用域。每次请求都会创建一个新的Bean实例。
request:请求作用域。每个HTTP请求都会创建一个新的Bean实例。
session:会话作用域。每个HTTP会话都会创建一个新的Bean实例。
application:全局作用域。每个Servlet上下文创建一个Bean实例。
websocket:WebSocket作用域。每个WebSocket连接创建一个Bean实例。
7. Spring中事务的隔离级别介绍
Spring支持以下事务隔离级别:
READ_UNCOMMITTED:未提交读(最低隔离级别,允许脏读)。
READ_COMMITTED:提交读(不允许脏读,但允许不可重复读)。
REPEATABLE_READ:可重复读(默认隔离级别,允许幻读)。
SERIALIZABLE:串行化(最高隔离级别,避免所有并发问题,但性能最低)。
8. Spring中事务的隔离级别
Spring事务的隔离级别默认为REPEATABLE_READ,但可以通过@Transactional注解的isolation属性指定不同的隔离级别:
java
复制
@Transactional(isolation = Isolation.READ_COMMITTED)
public void someMethod() {
// ...
}
9. Spring中事务的实现方式
Spring事务的实现方式包括:
声明式事务:通过@Transactional注解或XML配置声明事务规则。
编程式事务:通过TransactionTemplate或PlatformTransactionManager手动管理事务。
10. Spring中事务的本质
Spring事务的本质是通过AOP(面向切面编程)动态代理实现的。Spring通过代理对象拦截方法调用,并在方法执行前后添加事务管理逻辑。事务的底层实现依赖于数据库的事务机制(如JDBC事务或JTA事务)。
11. BeanFactory和ApplicationContext的理解
BeanFactory:
是Spring的核心接口,用于管理Bean的生命周期和依赖注入。
是一个轻量级的容器,提供了基本的Bean管理功能。
按需加载Bean,性能较高,但功能相对简单。
ApplicationContext:
是BeanFactory的扩展,提供了更丰富的功能。
支持事件发布、国际化、资源访问等功能。
在启动时加载所有单例Bean,适合大型应用,但启动速度较慢。
12. BeanFactoryPostProcessor的理解
BeanFactoryPostProcessor是一个接口,用于在Spring容器加载Bean定义后、实例化Bean之前进行自定义处理。它允许修改BeanDefinition的属性或添加新的Bean定义。常见的实现包括PropertySourcesPlaceholderConfigurer(用于解析占位符)。
13. BeanPostProcessor的理解
BeanPostProcessor是一个接口,用于在Bean初始化前后进行自定义处理:
postProcessBeforeInitialization:在Bean初始化之前调用。
postProcessAfterInitialization:在Bean初始化之后调用。
它常用于AOP、事务代理等场景。
15. Spring和SpringMVC的关系
Spring是SpringMVC的基础,提供了依赖注入、事务管理等功能。SpringMVC是Spring在Web层的扩展,专注于Web请求处理。SpringMVC依赖于Spring的核心功能,同时提供了Web开发的便利性。
16. DelegatingFilterProxy的理解
DelegatingFilterProxy是一个Servlet过滤器,用于将Servlet的过滤器功能委托给Spring管理的Bean。它允许Spring管理的Bean实现Filter接口,并通过Spring的依赖注入功能增强过滤器的功能。
17. SpringBoot自动装配原理的理解
SpringBoot通过@SpringBootApplication注解启动自动装配:
@ComponentScan:扫描组件。
@EnableAutoConfiguration:启用自动配置。
@Conditional注解:根据条件加载特定的Bean。
@Configuration类:定义自动配置的规则。
@Bean方法:提供Bean的定义。
SpringBoot通过这些机制,结合META-INF/spring.factories文件,自动加载和配置所需的Bean,从而实现“零配置”的开发体验。
18.Spring Boot 能处理的最大请求数量
Spring Boot 的最大并发处理能力由 Tomcat 的线程池和连接池配置决定。默认情况下,Spring Boot 使用的 Tomcat 配置如下:
最大工作线程数 (server.tomcat.threads.max): 200
最小空闲线程数 (server.tomcat.threads.min-spare): 10
最大连接数 (server.tomcat.max-connections): 8192
最大等待队列长度 (server.tomcat.accept-count): 100
因此,默认情况下,Spring Boot 能同时处理的请求数量为 max-connections + accept-count = 8192 + 100 = 8292。
如何配置 Spring Boot 的并发处理能力
如果需要调整 Spring Boot 的并发处理能力,可以通过修改 application.yml 或 application.properties 文件中的相关配置来实现。例如:
server:
tomcat:
threads:
max: 300 # 最大工作线程数
min-spare: 20 # 最小空闲线程数
max-connections: 10000 # 最大连接数
accept-count: 200 # 最大等待队列长度
配置后的处理能力计算
根据上述配置,Spring Boot 能同时处理的请求数量为:
max-connections + accept-count = 10000 + 200 = 10200。
19.spring 事务失效原因
1. 方法调用方式问题
同一类中的方法调用:如果在同一个类中,通过 this 调用被 @Transactional 注解的方法,事务会失效。因为 Spring 的事务是通过动态代理实现的,直接调用 this 方法会绕过代理逻辑。
2. 方法修饰符问题
方法非 public:@Transactional 注解只能作用于 public 方法。如果方法是 private、protected 或默认访问级别,事务将失效。
3. 类未被 Spring 管理
如果类没有被 Spring 托管(例如缺少 @Service 或 @Component 注解),事务注解将不会生效。
解决方案:确保类被 Spring 管理,例如添加 @Service 或 @Component 注解。
4. 异常被捕获
如果在事务方法中捕获了异常,但没有重新抛出,Spring 事务管理器无法感知异常,从而不会触发事务回滚。
解决方案:在捕获异常后,重新抛出异常,或者在 @Transactional 注解中明确指定 rollbackFor 属性。
5. 事务传播机制问题
如果事务方法的传播机制设置不当(如 REQUIRES_NEW),可能会导致事务失效。
解决方案:根据业务需求合理选择事务传播机制,例如使用默认的 REQUIRED。
6. 多线程调用
如果事务方法在多线程环境中被调用,每个线程会获取独立的事务上下文,导致事务不生效。
解决方案:尽量避免在事务方法中使用多线程,或者使用分布式事务解决方案。