Java面试题--Spring篇(超级详细,看完迎接offer)

【2023最新Java面试宝典】Spring面试题及答案解析汇总(130题) 答:Spring是一个开源应用框架,旨在降低应用程序开发的复杂度。它是轻量级、松散耦合的。它具有分层体系结构,允许用户选择组件,同时还为J2EE应用程序开发提供了一个有凝聚力的框架。它可以集成其他框架,如 Structs、Hibernate、EJB 等,所以又称为框架的框架。答:Spring配置文件是XML文件。该文件主要包含类信息。它描述了这些类是如何配置以及相互引入的。但是,XML配置文件冗长且更加干净。如果没有正确规划和编写,那么在大项目中管理变得非常困难。 阅读详情

1、什么是spring?

Spring是一个Java开发框架,它提供了一种可扩展的模型来开发Java应用程序。Spring框架的目标是提供一个全面的解决方案,用于构建企业级应用程序。Spring框架的核心特点包括依赖注入(DI)、面向切面编程(AOP)、声明式事务管理、MVC框架等。

Spring框架的核心是Spring容器,它是一个负责管理应用程序中的对象的容器。容器使用依赖注入技术来自动注入依赖项,使得开发者可以专注于编写应用程序的业务逻辑而不必关心对象创建和管理的细节。此外,Spring框架还提供了很多其他的功能和扩展,例如Spring Security、Spring Data等,可以让开发者更加容易地开发出高质量的Java应用程序。

2、你们项目中为什么使用Spring框架?

  1. Spring框架提供了依赖注入(DI)和控制反转(IoC)的功能,这使得应用程序中的组件可以松散耦合,并且容易进行单元测试和集成测试。

  1. Spring框架具有面向切面编程(AOP)的功能,可以将通用的横切关注点(例如日志记录、事务管理)从应用程序代码中分离出来,这提高了应用程序的可维护性和可扩展性。

  1. Spring框架提供了一个MVC框架,使得开发者可以轻松地构建Web应用程序。

  1. Spring框架具有良好的扩展性,例如Spring Security、Spring Data等,可以使得开发者更加容易地开发出高质量的Java应用程序。

综上所述,Spring框架是一个非常流行和强大的Java开发框架,它可以提高应用程序的可维护性、可测试性和可扩展性,因此被广泛应用于企业级应用程序的开发中。

3、 Autowired和Resource关键字的区别?

@Autowired和@Resource都是用于在Spring容器中自动装配Bean的关键字,它们的作用相似,但是存在一些区别。

@Autowired注解是Spring提供的一种基于类型的自动装配方式。它可以用于自动装配Spring容器中所有可以类型匹配的Bean。当有多个Bean与要装配的类型匹配时,Spring会尝试根据Bean的名称来进行匹配。如果仍然无法确定装配哪个Bean,则会抛出异常。

@Resource注解是J2EE提供的一种基于名称的自动装配方式。它可以用于自动装配Spring容器中指定名称的Bean。如果未指定名称,则会按照变量名进行匹配。如果有多个Bean与名称匹配,Spring会尝试根据Bean的类型来进行匹配。如果仍然无法确定装配哪个Bean,则会抛出异常。

因此,主要的区别在于:

  1. Autowired是基于类型的自动装配,而Resource是基于名称的自动装配。

  1. Autowired是Spring提供的注解,而Resource是J2EE提供的注解。

在实际使用中,如果Bean的名称与变量名不同,或者存在多个Bean与类型或名称匹配,建议使用@Resource注解来指定具体的Bean名称,以避免出现错误。

4、依赖注入的方式有几种,各是什么?

依赖注入(Dependency Injection)是一种实现对象之间松散耦合的设计模式,它将对象之间的依赖关系从代码中抽离出来,并由容器负责将依赖关系注入到对象中。依赖注入的方式有三种,分别是:

  1. 构造函数注入(Constructor Injection):通过在类的构造函数中声明需要注入的依赖项,容器会在创建对象时自动将依赖项注入到构造函数中。

publicclassUserServiceImplimplementsUserService {
    private UserDao userDao;

    publicUserServiceImpl(UserDao userDao) {
        this.userDao = userDao;
    }

    // other methods
}
  1. Setter方法注入(Setter Injection):通过在类中声明Setter方法,并在方法中传入需要注入的依赖项,容器会在创建对象后自动调用Setter方法注入依赖项。

publicclassUserServiceImplimplementsUserService {
    private UserDao userDao;

    publicvoidsetUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    // other methods
}
  1. 字段注入(Field Injection):通过在类中声明需要注入的依赖项的字段,并在字段上使用注解(如@Autowired、@Resource等)来标识需要注入的依赖项,容器会在创建对象后自动注入依赖项。

publicclassUserServiceImplimplementsUserService {
    @Autowiredprivate UserDao userDao;

    // other methods
}

在选择依赖注入方式时,建议优先使用构造函数注入和Setter方法注入,因为这样可以将依赖关系明确地表达出来,并且可以更好地控制对象的创建和初始化过程。字段注入一般用于简化代码,但容易造成对象的不可变性被破坏,并且在测试时比较困难。

5、讲一下什么是Spring容器?

Spring容器是Spring框架的核心部分,它负责管理Spring应用程序中所有的Bean对象。Spring容器提供了一个容器环境,将应用程序中的对象、组件和其他元素组织起来,并协调它们之间的交互。在Spring容器中,所有的对象都是由容器进行创建、组装和管理的,应用程序只需要通过依赖注入(DI)的方式获取需要的Bean对象即可。

Spring容器的主要作用包括:

  1. 实例化和管理Bean对象:Spring容器负责创建和管理应用程序中所有的Bean对象,并且可以在需要时对这些对象进行初始化、销毁、缓存等操作,以确保应用程序能够正确地运行。

  1. 提供依赖注入(DI)支持:Spring容器通过依赖注入的方式将应用程序中的各个组件和对象连接起来,从而实现了对象之间的松耦合,使应用程序更加灵活和易于维护。

  1. 提供AOP支持:Spring容器提供了AOP(面向切面编程)的支持,使得应用程序可以更加方便地实现横切关注点的编程,如事务管理、日志记录、安全控制等。

  1. 提供声明式事务管理支持:Spring容器提供了声明式事务管理的支持,使得应用程序可以更加方便地管理数据库事务,从而提高了应用程序的可靠性和性能。

Spring容器主要有两种实现方式:

  1. BeanFactory容器:BeanFactory是Spring容器的基本实现,提供了最基本的依赖注入和生命周期管理功能。它是一个轻量级的容器,仅在需要时才会对Bean进行初始化。

  1. ApplicationContext容器:ApplicationContext是BeanFactory的子类,提供了更丰富的功能,如国际化、事件处理、资源访问等。ApplicationContext在启动时就会对Bean进行初始化,因此启动时间较长,但在应用程序运行时可以提供更快的响应速度。同时,ApplicationContext也是Spring容器的推荐实现方式。

6、说说你对Spring MVC的理解

Spring MVC是Spring框架的一个重要组成部分,它是一种基于MVC(Model-View-Controller)设计模式的Web框架,用于构建Web应用程序。Spring MVC通过提供一系列标准化的接口和类,使得开发者可以更加方便地实现Web应用程序的开发和管理。

Spring MVC的主要组件包括:

  1. 控制器(Controller):负责处理用户请求,并将请求转发给相应的服务层进行处理。

  1. 视图(View):负责渲染模型数据,并将结果返回给客户端。

  1. 模型(Model):负责封装数据,并将数据传递给视图进行展示。

Spring MVC的工作流程如下:

  1. 客户端发送请求到DispatcherServlet。

  1. DispatcherServlet将请求转发给HandlerMapping,寻找匹配的Controller。

  1. HandlerMapping将请求映射到相应的Controller。

  1. Controller处理请求,并将处理结果封装到ModelAndView中。

  1. ModelAndView被传递给ViewResolver,由ViewResolver根据视图名称解析出对应的视图。

  1. 视图将模型数据渲染成HTML,并将结果返回给客户端。

在Spring MVC中,开发者可以通过注解(如@Controller、@RequestMapping等)和XML配置文件来配置和管理Controller、View等组件。同时,Spring MVC还提供了许多有用的特性,如数据绑定、数据格式化、文件上传、拦截器等,使得Web应用程序的开发和管理更加方便和灵活。

7、 SpringMVC常用的注解有哪些?

SpringMVC常用的注解包括:

  1. @Controller:标识一个类为SpringMVC的控制器,处理用户请求。

  1. @RequestMapping:将请求映射到对应的处理方法上,可以用于类和方法上。可指定HTTP请求方法(GET、POST等)、URL路径等属性。

  1. @RequestParam:绑定请求参数到方法参数上,可以指定参数名、是否必需等属性。

  1. @PathVariable:用于从URL路径中获取参数值,将参数值绑定到方法参数上。

  1. @ResponseBody:将方法返回值直接作为响应体返回给客户端,常用于返回JSON、XML等数据格式。

  1. @RequestBody:将请求体中的数据绑定到方法参数上,常用于接收JSON、XML等数据格式的请求。

  1. @ModelAttribute:将请求参数绑定到一个JavaBean对象上,常用于表单提交。

  1. @SessionAttribute:将指定名称的属性存储到会话(Session)中,常用于跨请求共享数据。

  1. @CookieValue:将请求中指定名称的Cookie值绑定到方法参数上。

  1. @Valid:用于数据校验,常用于表单提交。配合javax.validation包中的注解一起使用,如@NotNull、@Size、@Pattern等。

  1. @ExceptionHandler:用于处理指定类型的异常,常用于统一处理异常信息。

以上注解是SpringMVC开发中常用的注解,使用它们可以简化代码开发,提高代码的可读性和可维护性。

8、 谈谈你对Spring的AOP理解

在Spring框架中,AOP(Aspect-Oriented Programming)是一个重要的模块,它允许开发者通过切面(Aspect)的方式,将系统中的关注点(Concern)从核心业务逻辑中分离出来,以达到提高系统模块化、可维护性和可扩展性的目的。

AOP主要基于以下几个核心概念:

  1. 切面(Aspect):一个横跨多个核心逻辑的功能,即横切关注点。例如,日志、安全、事务等。

  1. 连接点(Join Point):程序执行过程中可以插入切面的点,例如,方法调用、异常处理、属性设置等。

  1. 切入点(Pointcut):一组匹配连接点的规则,用于确定哪些连接点应该被切面处理。

  1. 通知(Advice):切面在连接点处执行的操作,包括前置通知、后置通知、环绕通知、异常通知和最终通知等。

  1. 切面执行顺序(Ordering):多个切面对同一个连接点进行处理时,需要确定它们的执行顺序。

在Spring框架中,AOP的实现主要基于动态代理和字节码生成技术,通过在运行时生成代理对象,来实现对目标对象的方法进行拦截和增强。开发者可以通过声明式的方式配置AOP,将切面和通知应用到目标对象上,而不需要在代码中显式地进行调用。

总之,Spring的AOP能够提高代码的可维护性、可扩展性和可重用性,使得系统中的各个模块可以更加独立、聚焦,从而提高系统的整体质量和效率。

9、Spring AOP和AspectJ AOP有什么区别?

Spring AOP和AspectJ AOP是两种不同的AOP实现方式,它们的区别主要在以下几个方面:

  1. 实现方式:Spring AOP是基于代理的AOP实现,它是通过在运行时动态生成代理对象来实现对目标对象方法的拦截和增强;而AspectJ AOP是基于字节码增强的AOP实现,它是通过在编译期间修改目标类的字节码来实现对目标对象的方法拦截和增强。

  1. 支持的切入点表达式:Spring AOP仅支持基于方法级别的切入点表达式,如execution、within、this、target等;而AspectJ AOP支持更加丰富的切入点表达式,包括基于方法、字段、构造器等不同级别的切入点表达式,以及复合切入点表达式、逻辑切入点表达式等。

  1. 对于静态方法和final方法的支持:Spring AOP无法拦截静态方法和final方法;而AspectJ AOP可以拦截静态方法和final方法。

  1. 集成方式:Spring AOP是Spring框架的一部分,与Spring IoC容器紧密集成,方便在Spring应用中使用;而AspectJ AOP是独立的AOP框架,需要单独引入和配置。

总之,Spring AOP相对简单、易用,可以与Spring框架紧密集成;而AspectJ AOP相对强大、灵活,支持更多的切入点表达式和拦截方式,但需要单独引入和配置。具体使用哪种AOP实现方式,需要根据实际业务需求和技术场景进行选择。

在Spring AOP 中,关注点和横切关注的区别是什么?

在Spring AOP中,关注点和横切关注是AOP的两个重要概念,它们之间的区别如下:

  1. 关注点(Concern):关注点是指在软件系统中需要模块化的功能或需求,例如日志、事务、安全、缓存等,一个系统通常有多个关注点。关注点定义了系统的功能需求,可以被抽象为一组类或方法。在AOP中,关注点可以被视为被横切的对象。

  1. 横切关注(Cross-cutting Concerns):横切关注是指那些与业务逻辑无关,但是多个模块或层次共同使用的功能或需求,例如日志、事务、安全、缓存等,这些功能横跨多个模块和层次,不易被封装到单个模块中。在AOP中,横切关注是指在系统中被多个关注点共享的行为,它们可以通过AOP的方式进行统一实现和管理。

因此,关注点是指在系统中需要模块化的功能或需求,而横切关注是指跨越多个模块和层次的通用功能或需求。在AOP中,横切关注可以通过切面的方式进行统一管理和实现,从而提高代码的复用性和可维护性。

什么是通知呢?有哪些类型呢?

通知(Advice)是指在目标对象的方法执行过程中,AOP框架注入的一段代码,它可以在目标对象方法执行前、执行后、抛出异常等不同的执行时机进行拦截和增强,从而实现横切关注的功能。

在Spring AOP中,通知可以分为以下几种类型:

  1. 前置通知(Before Advice):在目标对象方法执行之前执行的通知,可以用于打印日志、权限检查、性能监控等场景。

  1. 后置通知(After Returning Advice):在目标对象方法执行之后执行的通知,可以用于打印返回结果、清理资源等场景。

  1. 环绕通知(Around Advice):在目标对象方法执行之前和之后都可以执行的通知,可以用于在目标对象方法执行前进行前置处理,执行后进行后置处理,也可以控制目标对象方法的执行过程。

  1. 异常通知(After Throwing Advice):在目标对象方法抛出异常后执行的通知,可以用于记录异常日志、异常处理等场景。

  1. 最终通知(After Advice):在目标对象方法执行之后无论是否抛出异常都会执行的通知,可以用于清理资源、释放锁等场景。

在AOP中,通知是实现横切关注的关键,通过注入不同类型的通知,可以实现对目标对象方法不同阶段的拦截和增强。

10、说说你对Spring的IOC是怎么理解的?

Spring的IOC(Inversion of Control)是一种设计模式,也是Spring框架的核心特性之一。它的主要思想是将对象的创建、管理、依赖关系的维护等工作交给容器来完成,而不是由程序员手动编码实现,从而实现对象的解耦、松耦合和易于维护。

在Spring的IOC容器中,所有的Bean对象都由容器来创建和管理,Bean之间的依赖关系也由容器来维护。程序员只需要在配置文件中定义Bean对象的属性和依赖关系,容器会根据配置文件中的信息来自动创建Bean对象,并将依赖关系注入到Bean对象中,从而实现Bean对象的解耦和重用。

Spring的IOC容器实现了控制反转的思想,将对象的创建、管理、依赖关系的维护等工作从程序员手中转移到了容器中,程序员只需要专注于业务逻辑的实现,而不需要关注对象的创建和管理。这种设计模式使得程序的可扩展性和可维护性大大提高,也提高了程序的灵活性和可重用性。

总之,Spring的IOC容器是一个非常重要的特性,它使得我们能够更加方便地管理和维护对象,提高了程序的可扩展性和可维护性,也为我们带来了更好的编程体验。

11、解释一下spring bean的生命周期

Spring Bean的生命周期指的是一个Bean对象从创建到销毁的整个过程,主要包括以下几个阶段:

  1. 实例化(Instantiation):在IOC容器中创建Bean对象实例的过程,通常是通过Java反射机制来实现。

  1. 属性赋值(Population):在IOC容器中为Bean对象的属性设置值的过程,包括通过构造方法、Setter方法或直接字段赋值等方式。

  1. 初始化(Initialization):在IOC容器中对Bean对象进行初始化的过程,可以通过实现InitializingBean接口或配置init-method方法来实现。

  1. 使用(Using):Bean对象被IOC容器创建之后,可以被其他对象引用和使用。

  1. 销毁(Destruction):在IOC容器关闭或Bean对象不再使用时,会调用Bean对象的销毁方法,可以通过实现DisposableBean接口或配置destroy-method方法来实现。

在这个过程中,Spring提供了各种扩展点,可以在特定的时机对Bean对象进行自定义处理,例如通过BeanPostProcessor接口实现在初始化前后对Bean对象进行自定义处理,通过AOP实现对Bean对象的增强等。

总之,了解Spring Bean的生命周期对于理解Spring框架的运作机制非常重要,它也为我们提供了很多自定义处理的扩展点,可以让我们更好地掌控和管理Bean对象。

12、解释Spring支持的几种bean的作用域?

Spring框架支持以下五种作用域:

  1. singleton:默认的作用域,每个Bean在整个应用中只有一个实例,所有对Bean的请求都返回同一个对象实例。

  1. prototype:每次请求Bean时,容器都会创建一个新的Bean实例,并返回给请求者。

  1. request:每个HTTP请求都会创建一个新的Bean实例,Bean实例将绑定到HTTP请求的生命周期内,当请求结束时,Bean实例也会被销毁。

  1. session:每个HTTP会话都会创建一个新的Bean实例,Bean实例将绑定到HTTP会话的生命周期内,当会话结束时,Bean实例也会被销毁。

  1. global-session:它是为Portlet环境准备的作用域,它允许多个Portlet共享一个全局的HTTP会话,它的生命周期是整个Web应用的生命周期。

其中,singleton作用域是默认的作用域,也是最常用的作用域。对于一些比较轻量的Bean,如工具类等,使用singleton作用域可以提高应用的性能。而对于一些需要动态创建的Bean,如请求处理器等,使用prototype作用域可以保证每个请求都有一个独立的处理器实例,避免了线程安全问题。

除了以上五种作用域,Spring还支持自定义作用域,通过实现Scope接口可以自定义一个新的作用域,以满足特定的业务需求。

13、 Spring基于xml注入bean的几种方式?

Spring框架基于XML配置文件的方式支持以下几种方式来注入Bean:

  1. 构造函数注入:通过构造函数来实例化Bean对象,并传递参数来设置Bean对象的属性值。在XML配置文件中使用<constructor-arg>标签来指定参数值,可以通过type属性来指定参数类型,也可以通过index属性或name属性来指定参数的位置或名称。

  1. Setter方法注入:通过Setter方法来设置Bean对象的属性值。在XML配置文件中使用<property>标签来指定属性名和属性值,Spring会自动调用相应的Setter方法来设置属性值。

  1. 工厂方法注入:使用工厂方法来创建Bean对象。在XML配置文件中使用<bean>标签的factory-method属性来指定工厂方法名,使用<constructor-arg>标签来指定参数值。

  1. 静态工厂方法注入:使用静态工厂方法来创建Bean对象。在XML配置文件中使用<bean>标签的class属性来指定工厂类名,使用factory-method属性来指定工厂方法名,使用<constructor-arg>标签来指定参数值。

  1. 实例工厂方法注入:使用实例工厂方法来创建Bean对象。在XML配置文件中使用<bean>标签的class属性来指定工厂类名,使用factory-bean属性来指定工厂对象名,使用factory-method属性来指定工厂方法名,使用<constructor-arg>标签来指定参数值。

除了以上几种方式,还可以使用注解的方式来注入Bean,例如使用@Autowired或@Resource注解来自动注入依赖对象。同时,Spring也支持混合使用以上几种方式来注入Bean,以满足不同的业务需求。

14、Spring框架中都用到了哪些设计模式?

Spring框架是一个非常强大的企业级应用程序开发框架,它涵盖了众多的设计模式,其中一些常见的设计模式包括:

  1. 依赖注入(DI)和控制反转(IOC)模式:Spring框架的核心思想就是依赖注入和控制反转,它们是Spring框架中最重要的设计模式。

  1. 工厂模式:Spring框架中使用BeanFactory和ApplicationContext等工厂类来创建Bean对象,这些工厂类都是基于工厂模式设计的。

  1. 代理模式:Spring框架中的AOP功能就是基于代理模式实现的,它通过代理对象来控制原始对象的访问。

  1. 模板方法模式:Spring框架中的JdbcTemplate和HibernateTemplate等类都是基于模板方法模式设计的,它们封装了通用的数据库操作逻辑,开发人员只需要继承这些类并实现必要的回调方法即可。

  1. 观察者模式:Spring框架中的事件机制就是基于观察者模式实现的,它允许开发人员在应用程序中发布和监听事件。

  1. 策略模式:Spring框架中的DispatcherServlet就是基于策略模式实现的,它根据请求的URL路径选择不同的处理策略。

  1. 适配器模式:Spring框架中的HandlerAdapter就是基于适配器模式实现的,它将不同类型的处理器适配到统一的接口上。

总之,Spring框架中使用的设计模式非常多样化,涵盖了多种常用的设计模式,这些设计模式都为Spring框架的高效、灵活和可扩展性奠定了坚实的基础。

15、说说Spring 中 ApplicationContext 和 BeanFactory 的区别

在 Spring 中,ApplicationContext 和 BeanFactory 都是用来管理 Spring Bean 的容器,但它们之间有以下几点区别:

  1. ApplicationContext 是 BeanFactory 的子接口,它提供了更多的功能,例如支持国际化、资源访问、事件传递、AOP 等。

  1. ApplicationContext 在启动时就会预处理所有的 Bean,如果有配置错误,会在启动时就抛出异常,而 BeanFactory 则是在获取 Bean 时才进行初始化,如果有配置错误,只有在获取 Bean 时才会抛出异常。

  1. ApplicationContext 可以自动检测 Bean 的依赖关系并自动注入依赖的 Bean,而 BeanFactory 则需要手动配置注入依赖的 Bean。

  1. ApplicationContext 支持多种资源的访问方式,例如文件系统、类路径、Web URL 等,而 BeanFactory 只支持基本的资源访问方式。

  1. ApplicationContext 支持事件传递机制,可以监听和发布事件,而 BeanFactory 不支持事件传递机制。

综上所述,ApplicationContext 比 BeanFactory 更加强大,它提供了更多的功能,可以自动化处理更多的任务,但它也需要更多的系统资源。如果应用程序需要更高的性能,可以使用 BeanFactory,如果需要更多的功能,可以使用 ApplicationContext。

16、Spring 框架中的单例 Bean 是线程安全的么?

在 Spring 框架中,单例 Bean 是默认在整个应用程序中共享的实例,这意味着多个线程可以同时访问同一个单例 Bean 实例。因此,Spring 容器会确保单例 Bean 实例的线程安全。

具体地说,Spring 通过以下两种方式来保证单例 Bean 的线程安全:

  1. 通过 synchronized 关键字保护 Bean 实例的访问。在 Spring 容器初始化单例 Bean 时,会在 Bean 的 getBean() 方法上添加 synchronized 关键字,确保在多线程环境下只有一个线程可以访问 Bean 实例。

  1. 通过方法级别的锁来保护 Bean 实例的访问。当使用注解方式配置 Bean 的时候,可以使用 @Scope("singleton") 注解来确保 Bean 实例的单例模式。在这种情况下,Spring 容器会在 Bean 实例的方法上添加锁,以确保在多线程环境下只有一个线程可以访问 Bean 实例。

需要注意的是,如果单例 Bean 中存在共享状态,那么在多线程环境下仍然需要考虑线程安全的问题,可以通过使用 synchronized 关键字或其他并发控制手段来保证线程安全。

17、Spring 是怎么解决循环依赖的?

循环依赖指两个或多个 Bean 之间相互依赖,形成一个环形依赖。Spring 容器默认情况下是不支持循环依赖的,因为容器需要先实例化 Bean,才能进行依赖注入,但是如果出现循环依赖,则会陷入死循环。

为了解决循环依赖问题,Spring 使用了三级缓存机制:

  1. 第一级缓存:Spring 容器在实例化 Bean 时,会将正在创建的 Bean 放到一个缓存 Map 中。如果在创建 Bean 的过程中,出现了依赖其他正在创建的 Bean 的情况,则会把依赖的 Bean 的 ObjectFactory 放到这个 Map 中,表示这个 Bean 还没有完全创建好。

  1. 第二级缓存:当创建一个 Bean 需要依赖另外一个还未创建完成的 Bean 时,Spring 容器会把当前正在创建的 Bean 放到第二级缓存中。这个缓存中存储的是已经实例化、但还未进行属性注入的 Bean 对象,以便后续注入。

  1. 第三级缓存:在 Bean 的属性注入完成后,Spring 容器会把这个 Bean 放到第三级缓存中。这个缓存中存储的是已经实例化并进行了属性注入的 Bean 对象。

当需要获取某个 Bean 时,Spring 容器会先从第一级缓存中查找,如果找不到则会从第二级缓存中查找,如果还是找不到,则会实例化 Bean 并加入到第三级缓存中。

通过三级缓存的机制,Spring 容器可以解决大部分循环依赖的问题,但是如果出现了循环依赖的死循环,则会抛出 BeanCurrentlyCreationException 异常,表示无法解决循环依赖问题。在开发过程中,应尽量避免出现循环依赖的情况。

18、说说事务的隔离级别

在关系型数据库中,事务的隔离级别定义了多个事务之间彼此之间的可见性和影响的程度。Spring 框架提供了对事务的支持,同时也支持多种隔离级别,包括以下 5 种:

  1. 读未提交(Read Uncommitted):允许脏读,即一个事务可以读取到另一个未提交事务的数据。

  1. 读已提交(Read Committed):禁止脏读,但允许不可重复读,即一个事务可以读取到另一个事务已提交的数据。

  1. 可重复读(Repeatable Read):禁止脏读和不可重复读,但允许幻读,即在一个事务内,多次读取同一范围的数据可能会返回不同的结果。

  1. 串行化(Serializable):禁止脏读、不可重复读和幻读,强制事务串行执行。

  1. 默认隔离级别(默认是读已提交):禁止脏读,但允许不可重复读和幻读。

Spring 中事务的隔离级别可以通过设置 TransactionDefinition 的常量来实现,如下所示:

public interface TransactionDefinition {
    int ISOLATION_READ_UNCOMMITTED = 1;
    int ISOLATION_READ_COMMITTED = 2;
    int ISOLATION_REPEATABLE_READ = 4;
    int ISOLATION_SERIALIZABLE = 8;
    int ISOLATION_DEFAULT = ISOLATION_READ_COMMITTED;
    //...
}

在配置事务时,可以使用 @Transactional 注解或者编程式事务进行设置。例如:

19、说说事务的传播级别

在 Spring 框架中,当一个事务方法调用另一个事务方法时,这两个事务如何协同工作是由事务的传播行为控制的。Spring 支持多种传播行为,包括以下 7 种:

  1. PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果不存在,则新建一个事务。这是默认值。

  1. PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果不存在,则以非事务状态执行。

  1. PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果不存在,则抛出异常。

  1. PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则挂起当前事务。

  1. PROPAGATION_NOT_SUPPORTED:以非事务状态执行操作,如果当前存在事务,则挂起当前事务。

  1. PROPAGATION_NEVER:以非事务状态执行操作,如果当前存在事务,则抛出异常。

  1. PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果不存在事务,则新建一个事务。

20、Spring 事务实现方式

Spring 框架提供了多种实现事务的方式,包括编程式事务和声明式事务。下面分别介绍这两种实现方式。

  1. 编程式事务

编程式事务是通过编写代码来管理事务的。在 Spring 框架中,我们可以使用 TransactionTemplate 或者直接使用 PlatformTransactionManager 接口来实现编程式事务。TransactionTemplate 可以简化编程式事务的编写,具有更高的可读性和可维护性。PlatformTransactionManager 是实际执行事务管理的对象,它是一个接口,需要根据使用的数据源来选择不同的实现。

使用 TransactionTemplate 实现编程式事务的示例代码如下:

@Autowired
private PlatformTransactionManager transactionManager;

public void foo() {
    DefaultTransactionDefinition def = new DefaultTransactionDefinition();
    TransactionStatus status = transactionManager.getTransaction(def);
    try {
        // 执行数据库操作
        // ...
        transactionManager.commit(status);
    } catch (Exception ex) {
        transactionManager.rollback(status);
        throw ex;
    }
}
  1. 声明式事务

声明式事务是通过声明式配置来管理事务的,不需要编写特定的代码。在 Spring 框架中,我们可以使用 @Transactional 注解或者 XML 配置来实现声明式事务。@Transactional 注解可以应用在方法或者类级别上,用于配置事务的传播行为、隔离级别、超时时间和只读属性等。

使用 @Transactional 注解实现声明式事务的示例代码如下:

@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public void foo() {
    // 执行数据库操作
    // ...
}

使用 XML 配置实现声明式事务的示例代码如下:

<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="*" propagation="REQUIRED" isolation="READ_COMMITTED"/>
    </tx:attributes>
</tx:advice>

<aop:config>
    <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.example.service.*.*(..))"/>
</aop:config>

需要注意的是,在使用声明式事务时,我们需要将事务管理器注入到容器中,并且需要确保所有的 DAO 类都是 Spring 管理的 Bean。这样才能保证事务生效。

总的来说,声明式事务相对于编程式事务具有更高的可读性和可维护性,同时也可以更好地支持声明式事务的切面编程。因此,在实际开发中,建议使用声明式事务来管理事务。

21、 Spring框架的事务管理有哪些优点

Spring框架的事务管理有以下优点:

  1. 与Spring容器紧密集成,便于开发和维护。

  1. 声明式事务管理使得代码简洁,易于维护。开发者只需要使用注解或XML进行配置,就可以完成事务的管理。

  1. Spring的事务管理支持多种事务定义方式,包括编程式事务管理和声明式事务管理。这样可以根据业务需求进行选择。

  1. Spring的事务管理可以管理多个事务,即使在一个事务中涉及多个数据源,也可以进行管理。

  1. Spring的事务管理提供了对事务状态的良好支持,包括对事务的回滚、提交和挂起等操作。这些操作可以提高数据的安全性和完整性。

  1. Spring的事务管理提供了对JTA事务的支持,可以管理跨越多个应用程序或资源的分布式事务。

综上所述,Spring框架的事务管理具有简单、灵活、高效等优点,可以帮助开发者更好地管理和控制事务。

22、事务三要素是什么?

事务三要素是指事务的三个基本特征,即原子性、一致性和隔离性。

  1. 原子性(Atomicity):事务是一个不可分割的工作单位,要么全部执行,要么全部不执行,事务的各项操作要么全部成功,要么全部失败回滚,不允许只执行其中的一部分操作。

  1. 一致性(Consistency):事务执行前后,数据的完整性、一致性都必须得到保障。在事务执行过程中,系统的约束条件不能被破坏,数据的约束条件必须得到维护。

  1. 隔离性(Isolation):多个事务并发执行时,事务之间是相互隔离的,一个事务不应该影响其他事务的执行。隔离级别是事务并发控制的核心,常见的隔离级别有:读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)和串行化(Serializable)。

这三个要素是事务的核心特性,对事务的正确性和完整性都至关重要。只有同时满足这三个要素,才能保证事务的正确性和完整性。

2023Java面试题大全(整理版)1000+面试题附答案详解,全网最全面详细,看完offer稳了! 对于Java后端的朋友来说应该是最全面最完整的面试备战仓库,为了更好地整理每个模块,我也参考了很多网上的优质博文和项目,力求不漏掉每一个知识点,很多朋友靠着这些内容进行复习,拿到了BATJ等大厂的offer, 也已经帮助了很多的Java学习者,希望也能帮助到你。进大厂是大部分程序员的梦想,而进大厂的门槛也是比较高的,所以这里整理了一份阿里、美团、滴滴、头条等大厂面试大全,其中概括的知识点有:Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、 阅读详情

相关推荐

800道Java后端经典面试题,希望你找到自己理想的Offer呀~

Java 基础 equals与==的区别 final, finally, finalize 的区别 重载和重写的区别 两个对象的hashCode()相同,则 equals()是否也一定为 true? 抽象类和接口有什么区别 BIO、NIO、AIO 有什么区别? String,Stringbuffer,StringBuilder的区别 JAVA中的几种基本数据类型是什么,各自占用多少字节呢 Comparator与Comparable有什么区别? String类能被继承吗,为什么。 说说Java中多态的实现原理

m0_67322837的博客 6171

spring常见面试题(2024最新)

spring常见面试题(2023最新)

酷酷的馫博客 5万+

【Java面试宝典】1000+面试题附答案详解,最全面详细

所有的面试题目都不是一成不变的,上面的面试题只是给大家一个借鉴作用,最主要的是给自己增加知识的储备,有备无患。上面分享的2022最新1000+Java面试题的答案都整理成了PDF文档。最新2022整理收集的一些Java学习资料(都整理成文档),有很多干货,包含mysql,netty,spring,线程,spring cloud等详细讲解,也有详细的学习规划图,面试题整理等,人生短暂,别稀里糊涂的活一辈子,不要将就。

weixin_45987961的博客 2896

Spring面试题

推荐博客:https://blog.youkuaiyun.com/a745233700/article/details/80959716 1. Spring是什么 Spring是一个轻量级的IoC和AOP容器框架。是为Java应用程序提供基础性服务的一套框架,目的是用于简化企业应用程序的开发,它使得开发者只需要关心业务需求。主要包括以下七个模块: Spring Context:提供框架式的Bean访问方式,以及企业级功能(JNDI、定时任务等); Spring Core:核心类库,所有功能都依赖于该类库,提供IOC和

诗和远方 1万+

【Java面试题汇总】Spring篇(2026版)

IoC、DI、aop、事务、为什么不建议@Transactional、事务传播级别、@Autowired和@Resource注解的区别、BeanFactory和FactoryBean的区别、Bean的作用域,以及默认的作用域、Bean的生命周期、循环依赖、三级缓存、

种一棵树最好的时间是十年前,其次是现在 7376

TwinCAT3 Modbus-TCP Client/Server使用

/起始地址是12289//起始地址是12294。

panjinliang066333的博客 7736

2025最新精华版Java面试题之spring篇

Spring是一个Java开发框架,它提供了一种可扩展的模型来开发Java应用程序。Spring框架的目标是提供一个全面的解决方案,用于构建企业级应用程序。Spring框架的核心特点包括依赖注入(DI)、面向切面编程(AOP)、声明式事务管理、MVC框架等。Spring框架的核心是Spring容器,它是一个负责管理应用程序中的对象的容器。容器使用依赖注入技术来自动注入依赖项,使得开发者可以专注于编写应用程序的业务逻辑而不必关心对象创建和管理的细节。

sinat_53467514的博客 9162

从扇束到平行束:等角重排算法在CT重建中的核心原理与MATLAB实践

本文深入解析了CT图像重建中等角扇束重排算法的核心原理与MATLAB实现。通过将实际采集的扇束投影数据,利用几何映射和两次关键插值,转换为适用于经典滤波反投影算法的平行束数据,打通了高效重建的关键路径。文章结合Shepp-Logan模型仿真,提供了完整的MATLAB代码实践,并分析了源-物距、采样率等关键参数对重建质量的影响。

cnn8visionary的博客 647

Java后端真实面试题大全(有详细答案)--高频/真题

本文分享Java后端真实高频面试题,有详细答案,保你稳过面试。题目包括:Java基础、多线程、JVM、数据库、Redis、Shiro、Spring、SpringBoot、MyBatis、MQ、ELK、SpringCloud、设计模式等。 本博客包含从简单到困难、从高频到低频的题目,适合所有Java求职者,包括:刚入门的、三年以内经验、三到五年经验、五到十年经验等。

IT利刃出鞘的博客 17万+

手把手教学|用飞书+扣子工作流实现自动化批量图片生成,效率提升99%!体验完整操作流程

在先前的文章中,我们已经深入探讨了扣子智能体的多种应用场景,以及如何创建和使用工作流进行高效管理。本文将引领大家通过一个具体案例,将扣子的工作流功能嵌入飞书应用中,实现操作的自动化与高效化。

weixin_66485800的博客 6028

【机电杂谈2】BLDC和PMSM的特点和区别

在日常生活中,小到电动玩具,大到电动汽车,永磁电机的身影可以说是无处不在。有刷直流电机、无刷直流电机、永磁同步电机由于其结构和输出特定的不同也被应用到不同的场合。如果你经常拆一些玩具和家电,就会看到大量的有刷直流电机和无刷直流电机,而永磁同步电机主要应用在高精度的工业伺服和电动汽车领域。本文就从电机的结构和控制方面,对这几种常见的永磁电机做简单的梳理和归纳。

2938

Java面试题大全(整理版)1000+面试题附答案详解,最全面详细,看完稳了

对于Java后端的朋友来说应该是最全面最完整的面试备战仓库,为了更好地整理每个模块,我也参考了很多网上的优质博文和项目,力求不漏掉每一个知识点,很多朋友靠着这些内容进行复习,拿到了BATJ等大厂的offer, 也已经帮助了很多的Java学习者,希望也能帮助到你。

javaAnPou的博客 1777

基于人脸识别的课堂考勤系统 tkinter+openpyxl+face_recognition

基于face_recognition库实现人脸考勤系统功能。利用Python的tkinter模块来设计考勤系统的图形化界面,此外结合openpyxl模块,实现将学生的信息和考勤打卡数据保存到表格中,方便查看和调用。该系统具备“刷脸打卡”、“新学生注册”等功能。............

lyx4949的博客 6968

一文整理总结常见Java后端面试题系列——Java基础篇(2022最新版)

为什么会出现自动拆装箱Java 语言是一个面向对象的语言,但是 Java 中的基本数据类型却是不面向对象的,这在实际使用时存在很多的不便,为了解决这个不足,在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八个和基本数据类型对应的类统称为包装类(Wrapper Class)。使得基本数据类型也具有了对象的性质,并且为其添加了属性和方法,丰富了基本类型的操作。

程序猿周周的博客 2万+

Halcon实战:如何快速找到图像中的多个圆并计算圆心距离(附完整代码)

本文详细介绍了Halcon在工业视觉检测中快速定位图像中的多个圆并计算圆心间距离的实战方法。通过两种核心算法(阈值分割和动态阈值)的对比分析,结合完整代码示例和参数调优技巧,帮助开发者高效解决多圆检测问题,提升工业检测精度与效率。

weixin_33701251的博客 316

告别Nginx原始日志!VictoriaLogs+Grafana构建企业级应用日志分析平台实战

描述:做为一个合格的运维工程师,在面对企业安全运维管理中,日志审计是一项非常重要的工作。授人以鱼不如授人以渔,各位运友们可参照作者的方案设计,在自己的项目中根据实际情况调整落地,例如,不在仅仅采集 NGINX 应用日志,而是采集 Apache、Tomcat、SpringBoot 等多种应用服务器的日志,又如,不再仅仅采集网络设备、安全审计审计日志,而是 Windows、Linux 等多种操作系统的审计日志等,大家可充分发挥想象、实践能力,也欢迎大家在知识星球中分享自己的方案设计,一起交流学习。

全栈工程师修炼指南-IT知识分享 2479

肝了一个月,整理了一万道2020年最新Java面试题,阿里offer有了

肝了一个月的面试题终于来啦,大家开心不。 2020年最新Java面试题整理,全网最全一份,包含各个技术栈,Java基础,Java集合,多线程,Java异常,spring,spring MVC,spring boot,spring cloud,netty,dubbo,activemq,Java web,jvm,kafka,MongoDB,mybatis,MySQL,Nginx,rabbitmq,Redis,Tomcat,zookeeper,设计模式,数据结构,算法,分布式,限流,降级,cap原理等等知识点 话

hnjsjsac的博客 3926

816华为OD机试真题 新系统 - 电池充电时间计算 (Java/Py/C/C++/Js/Go)

816华为OD机试真题 新系统 - 电池充电时间计算 (Java/Py/C/C++/Js/Go)

算法大师! 475

2024 Java面试题大全(整理版)1000+面试题附答案详解,全网最全面详细,看完offer稳了!

对于Java后端的朋友来说应该是最全面最完整的面试备战仓库,为了更好地整理每个模块,我也参考了很多网上的优质博文和项目,力求不漏掉每一个知识点,很多朋友靠着这些内容进行复习,拿到了BATJ等大厂的offer, 也已经帮助了很多的Java学习者,希望也能帮助到你。进大厂是大部分程序员的梦想,而进大厂的门槛也是比较高的,所以这里整理了一份阿里、美团、滴滴、头条等大厂面试大全,其中概括的知识点有:Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、

web15870359587的博客 2043

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

2025年一线大厂最全1140道Java面试题附答案详解,最全面详细,看完稳了

我相信大多 Java 开发的程序员或多或少经历过 BAT 一些大厂的面试,也清楚一线互联网大厂 Java 面试是有一定难度的,小编经历过多次面试,有满意的也有备受打击的。因此呢小编想把自己这么多次面试经历以及近期的面试真题来个汇总分析,阐述下如何去准备,去回答面试官的提问,可以和面试官有个愉快的交谈。小编分享的这份 BAT 必考 Java 真题合集包含了性能调优、并发编程。

m0_50180963的博客 708

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

这些干货Java面试题,看完大厂offer不拿到手软请来Gank我!

前言: 最近不是写了一篇关于“好基友”面试成功的干货文章吗,谢谢大家的支持反响很不错。但是好多人私信我说,里面的一些面试题不是常见遇到的,而且局限性很高,以及一些常见面试题的补充。非常感谢大家的建议,我针对大家的建议以及掏空了各大搜索引擎,终于整理了一份比较普遍的java面试题,为了感谢大家的支持,现在分享给大家,请大家多多提建议哦,大家的建议我都会看的,毕竟比我厉害的大神有很多哈哈。如果想要资料答案的话可以私信我(面试集题)自行领取 ,或者查看评论自行领取。 Java集合22题 这个算是j.

weixin_50666791的博客 481

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

看完这篇Spring宝典,面试都给我去怼面试官

关于大厂面试,总的来说,技术相关的考察主要分为两大块,一是基础,二是经验,基础包括java基础、数据库、中间件等,来自于日常的积累和面试前的准备。经验包括以往做过的项目、解决的问题、以及一些场景题(比如你的项目如果流量大了十倍如何保证可用)。既然有进入大厂工作的理想,就要为此付诸行动——学习,刻不容缓。

知识分享官 197

面试大厂必看!凭借这份Java面试题,成功拿到阿里offer!

前言 一位小伙伴经过一个半月的面试准备,成功拿下了阿里的offer,小编把他遇到的面试题分享出来,希望能对即将面试的小伙伴有所帮助。 一、自我介绍 简单的介绍一下自己的工作经历与职责,在校或者在工作中主要的工作内容,主要负责的内容; 介绍下自己最满意的,有技术亮点的项目或平台,重点介绍下自己负责那部分的技术细节; 二、Java多线程 线程池的原理,为什么要创建线程池?创建线程池的方式; 线程的生命周期,什么时候会出现僵死进程; 说说线程安全问题,什么实现线程安全,如何实现线程安全; 创建线程池有哪几个核心

weixin_47955802的博客 2186

2023java面试看完这篇笔记薪资和offer稳了!

新的一年抓住机会,不管跳槽涨薪,还是学习提升,这篇笔记你都不应该错过。 为了帮大家节约时间,整理了这个篇【Java面试核心知识点整理】以及【金三银四高频面试合集】希望大家在新的一年都能拿到理想的薪资和offer!

weixin_51702416的博客 1万+

看完这份:4W字的Java面试题解析 才明白同事斩获5份大厂Offer是有原因的!

编辑小编总是不遗余力地在各个平台分享面试题,不少粉丝纷纷留言互动:程序员A兴奋地分享道:“真是太巧了,我前阵子去阿里巴巴面试,恰好就被问到了这个问题!程序员B遗憾地表示:“上个星期我也遇到了这个面试题,只可惜当时没能给出满意的答案…]程序员C感慨地说:“今天刚从腾讯的面试现场回来,他们正好也问了这个问题。要是能早点看到小编的分享就好了……”其实吧,小编为了每天能持续有内容发送,就没有把这些面试题展示出来。但是,最近小编想赚点零花钱,忍痛割爱把这些面试题给了合作方…

weixin_42924914的博客 553
上一篇: Java面试--网络篇(超级详细,看完迎接offer)
下一篇: Java面试--数据库(超级详细,看完迎接OFFER吧)
Y
博客等级 码龄6年 2粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值