Java面试之-Spring全家桶面试题

本文详细介绍了Spring框架在面试中常问的若干问题,包括IoC和DI的概念、AOP原理、AOP的动态代理实现方式、Bean的注入方式、Bean的创建方式、Bean的生命周期、BeanFactory和FactoryBean的区别、@Transactional注解的原理、事务的隔离级别和传播机制、Spring的三级缓存机制、延迟加载原理、Mybatis的#和$的区别、Mybatis的缓存和延迟加载以及Mapper接口调用实现。文章深入探讨了SpringCloud的相关组件,如Eureka、Feign、Hystrix、Zuul等,并对比了Spring Cloud与Dubbo的区别。此外,还讨论了JPA、微服务和Spring Boot的核心特性。
摘要由CSDN通过智能技术生成

Spring全家桶

1.Spring的Ioc和DI?

Ioc(Inversion of Control):控制反转
将原本在代码中直接操控的对象的调用权交给容器来控制,以解耦代码,提高程序的可扩展性和可维护性。在Spring框架中,IoC容器负责管理应用程序中的对象及其依赖关系,它负责创建对象,装配对象之间的依赖关系,并控制这些对象的生命周期。

DI(Dependency Injection):依赖注入
DI是IoC的一种具体实现方式,它是指将对象所依赖的其他对象通过构造函数、Setter方法或其他方式注入到对象中,从而消除了对象之间的耦合关系。

IoC和DI的关系是相辅相成的。IoC是一个大的概念,是Spring框架的核心思想,而DI是IoC的一种具体实现方式。

2.Spring的AOP?

AOP:Aspect Oriented Programming,面向切面编程,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。AOP利用一种称为横切的技术,剖开对象的封装,并将影响多个类的公共行为封装到一个可重用模块,组成一个切面,即Aspect。

3.Spring AOP的动态代理的两种实现方式?

Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是在内存中临时为方法生成一个 AOP 对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。它的动态代理主要有两种方式,JDK 动态代理和CGLIB 动态代理

  • JDK 动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。JDK 动态代理的核心是 InvocationHandler 接口和Proxy类。
  • 如果目标类没有实现接口,那么Spring AOP 会选择使用CGLIB来动态代理目标类。CGLIB是一个代码生成的类库,可以在运行时动态的生成某个类的子类,CGLIB 动态代理的两个核心接口(类)分别是 MethodInterceptor 和 Enhancer。跟JDK 动态代理很相似,用法也差不多。
    但 CGLIB可以代理类和接口。注意:不能代理final类。

4.Spring的注入方式有什么?

构造函数注入(Constructor Injection):这是最常用的注入方式。在构造函数中,我们将需要的依赖项作为参数传递,然后在创建对象时,由IoC容器负责提供这些依赖项。这种方式可以保证依赖项在对象创建时就被正确初始化,并且对象内部可以保持依赖项的私有性,防止外部修改。
属性注入(Property Injection):通过为类的属性提供setter方法,IoC容器可以在对象创建后,通过调用这些setter方法来注入依赖项。这种方式更加灵活,可以在对象创建后的任何时间进行注入,但也可能导致对象在部分依赖项未注入的情况下被使用。
方法注入(Method Injection):通过调用类的某个方法来注入依赖项。这种方式不如前两种方式常用,因为它需要额外的方法调用,并且可能破坏对象的封装性。

注解注入:Spring支持多种注解来简化依赖注入,如@Autowired、@Inject、@Resource等。这些注解可以应用于字段、构造函数或setter方法上,以指示Spring容器进行依赖注。

XML配置注入
在早期的Spring版本中,XML配置是主要的注入方式。通过在XML配置文件中使用、等元素,可以定义和注入Bean的依赖项。尽管现在注解注入更加流行,但XML配置仍然是一种可选的方式。

5.Spring Bean的创建方式?

使用默认构造函数创建Bean:Spring IoC容器默认使用Java反射机制来创建Bean实例。它会调用Bean类的无参构造函数来创建Bean对象,并将该对象保存在容器中。

使用静态工厂方法创建Bean:除了使用默认构造函数,Spring还允许使用静态工厂方法来创建Bean。在这种情况下,需要定义一个静态方法,并在该方法中创建并返回Bean实例。在Spring配置文件中,通过指定静态方法的名称和所在的类来告诉Spring如何创建Bean。

使用实例工厂方法创建Bean:除了静态工厂方法,Spring还支持使用实例工厂方法来创建Bean。这种方法与静态工厂方法类似,但不同之处在于实例工厂方法属于某个类的实例成员方法。在Spring配置文件中,需要首先创建一个工厂Bean的实例,然后使用该实例调用其成员方法来创建目标Bean。

使用Java配置类创建Bean:从Spring 3.0开始,引入了Java配置的概念,允许使用Java类来替代传统的XML配置文件。在Java配置类中,可以通过使用@Bean注解来声明和创建Bean。这种方式更加灵活和类型安全,因为Bean的类型在编译时就已经确定。

使用注解创建Bean:Spring支持使用注解来简化Bean的创建和配置。通过在类上使用@Component@Service@Repository@Controller等注解,可以将类标记为Spring容器管理的Bean。Spring会自动扫描带有这些注解的类,并将它们作为Bean创建和注册到容器中。

6.Spring Bean的生命周期?

  1. 实例化:通过构造函数创建一个对象。
  2. 属性赋值:通过field属性等进行赋值。
  3. BeanNameAware:如果Bean实现了BeanNameAware接口,执行setBeanName方法。
  4. BeanFactoryAware或ApplicationContextAware:如果Bean实现了BeanFactoryAware或ApplicationContextAware接口,执行setBeanFactory方法,可以获取到上下文对象BeanFactory。
  5. BeanPostProcessor:如果存在类实现BeanPostProcessor接口,执行postProcessBeforeInitialization方法。
  6. InitializingBean:如果Bean实现了InitializingBean接口,执行afterPropertiesSet方法。
  7. 自定义初始化方法:可以自定义一个Bean类的初始化方法,例如initBean方法,这个需要在配置文件中设置,才能执行。
  8. BeanPostProcessor:如果存在类实现BeanPostProcessor接口,执行postProcessAfterInitialization方法。
  9. 执行业务处理:这个时候,Bean已经准备好了,可以执行Bean的具体业务逻辑,他们将一直留在应用的上下文中,直到应用上下文被销毁。
  10. DisposableBean:如果Bean实现了DisposableBean接口,执行destroy方法。
  11. 自定义销毁方法:可以调用指定的销毁方法customerDestroy。

以上就是Spring Bean的生命周期的步骤,其中第五步和第八步可以结合AOP,在初始化执行之前或者执行之后执行一些操作。

7.什么是BeanFectory?

BeanFactory,以 Factory 结尾,表示它是一个工厂类(接口),它负责生产和管理Bean的一个工厂,我们可以通过它获取工厂管理的对象。在Spring 中,BeanFactor 是IOC容器的核心接口,它的职龄包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。它定义了 getBean0)、containsBean0等管理 Bean的通用方注。但 BeanFactory 只是个接口,并不是IOC容器的具体实现,但是 Spring 容器给出了很多种实现,如:

  • DefaultListableBeanFactory
  • XmlBeanFactory
  • ApplicationContext

其中 XmlBeanFactory 就是常用的一个,该实现将以 xML方式描述组成应用的对象及对象间的依赖关系。

8.什么是FectoryBean?

使用 XML 配置 spring 容器的时候,Spring 通过反射机制利用的 class 属性指定实现类实例化 Bean,在某些情况下,实例化Bean 过程比较复杂,如果按照传统的方式,则需要在中提供大量的配置信息。配置方式的灵活性是受限的,比如一个类大量依赖了其他的对象属性,此时就算是使用自动装配,不需要再显式的写出 bean 之间的依赖关系,但是其依赖的对象也需要将其装配到spring容器中,也需要力它所依赖的多有对象都创建 bean标签将他们注入,如果这个类依赖了上百个对象,那么这个工作量无疑是非常大的。

Spring 为此提供了一个 org:springframework.bean.factory. FactoryBean 的工厂类接口,用户可以通过实现该接口定制实例化 Bean 的逻辑。FactoryBean 接口对于 Spring 框架来说占用重要的地位,Spring自身就提供了70多个 FactoryBean 的实现。它们隐藏了实例化一些复杂Bean 的细节,给上层应用带来了便利。从Spring3.0开始,FactoryBean 开始支持泛型,即接口声明改为FactoryBean的形式。

Spring 中共有两种bean,一种为普通 bean,另一种则为工厂 bean;

以 Bean结尾,表示它是一个 Bean,不同于普通Bean 的是:它是实现了 FactoryBean接口的Bean,根据该 Bean的ID 从 BeanFactory 中获取的实际上是 FactoryBean 的 getObject()返回的对象,而不是FactoryBean 本身,如果要获取 FactoryBean 对象,请在id 前面加一个&符号来获取。

9.BeanFactory和FactoryBean的区别?

共同点:都是接口
区别
首先啊,Spring里面的核心功能是IOC容器,所谓的IOC容器本质上就是一个Bean的容器,或者是一个Bean的工厂,它能够去根据Xml里面声明的Bean的配置去进行Bean的加载和初始化,然后Beanfactory呢,来生产我们所需要的各种各样的一个Bean。所以我对Beanfactory的理解有两个,第一个Beanfactory呢,是所有Bean容器的顶级接口,它为Bean容器定义了一套规范,并提供了像getBean这样的一些方法去从容器中获取指定Bean实例的一个功能。第二个Beanfactory里呢,在产生Bean的同时啊,还提供了解决Bean之间的依赖注入的一个能力,也就是所谓的DI。而FactoryBean呢,是一个工厂Bean,它是一个接口,它的主要功能是动态去生成某一类型的Bean的一个实例,也就说我们可以自定义一个Bean,并且加载到IOC容器里面,它里面有一个重要的方法叫get object(),这个方法里面呢,就是用来实现动态构建Bean的一个过程。SpringCloud里面的Openfeign组件,客户的代理啊,就是使用FactoryBean来实现的,以上就是我对这个问题的理解。

10.@Transactional的原理?

@Transactional注解只能应用于public方法上,否则它将不会生效。
当面试官问及你对@Transactional的理解时,你可以从以下几个方面来回答:

基本概念:首先解释@Transactional是Spring框架提供的一个注解,它用于声明一个方法或类需要事务管理。当在方法或类上使用此注解时,Spring会为这个方法或类中的所有方法创建代理,并管理事务的边界。

事务的边界:解释事务的边界通常是由方法调用开始到方法调用结束。如果在方法执行过程中发生异常,事务会被回滚,确保数据的完整性和一致性。

传播行为:提到@Transactional有一个属性叫做propagation,它定义了事务的传播行为。比如,Propagation.REQUIRED表示当前方法必须在一个事务中运行,如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。

隔离级别:解释@Transactional还有一个属性isolation,它定义了事务的隔离级别。隔离级别决定了多个并发事务之间的可见性和相互影响程度。你可以列举几种常见的隔离级别,如ReadUncommittedReadCommittedRepeatableReadSerializable,并简要描述它们的特性。

只读事务:提到@TransactionalreadOnly属性,它用于指定事务是否只读。设置为true时,表示该事务只读取数据而不修改数据,这有助于提高性能。

异常处理:解释在事务中,并不是所有

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值