Java面试题总结记录(3)—— Spring篇

1、什么是Spring?


Spring 是个java企业级应用的开源开发框架。Spring主要用来开发Java应用,但是有些扩展是针对
构建J2EE平台的web应用。 Spring 框架目标是简化Java企业级应用开发,并通过 POJO为基础的编程
模型促进良好的编程习惯


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

实际上是问的是Spring框架的优点

  • 轻量: 基本版本只有2MB。
  • 控制反转: 通过IOC实现松耦合,对象们给出它们的依赖,而不直接创建或查找依赖的对象。
  • 面向切面编程AOP: 支持将应用逻辑和系统逻辑分离。
  • 容器: 包含并管理应用中对象的生命周期和配置。
  • MVC框架: 一个很好的WEB框架,主要是Model + View + Controller
  • 事务管理: 一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)。
  • 异常处理: 提供方便的API把具体技术相关的异常。

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

@Autowired 和 @Resource 都是用来注入 bean ,其实 @Resource 并不是 Spring 的注解,是来源自 javax.annotation.Resource,需要导入,但是Spring支持该注解的注入。

(1)共同点

两者都可以写在字段和setter方法上,若写在字段上,则不需要再写在setter上。

(2)不同点

  • @Autowired

    • 导包: org.springframework.beans.factory.annotation.Autowired
    • 注入方式: 按照类型进行注入(byType),默认情况下,要求依赖对象必需存在,如果想要按照名称(byName)来装配,则结合@Qualifier注解一起使用。
    • 属性: required —— 允许空值
  • @Resource

    • 导包: javax.annotation.Resource
    • 注入方式: 默认按照名称进行注入(byName)。
    • 两个属性: name 和 type,Spring 将 @Resource的 name 属性解析为 bean 的名字,而 type 属性则解析为 bean的类型。
    • 自动注入策略
      • 设置 name 属性: 使用byName 的自动注入策略
      • 设置 type 属性: 使用 byType自动注入策略
      • 不设置属性: 通过反射机制使用byName自动注入策略
    • 装配顺序
      • 同时设置 name 和 type: 从上下文中找到唯一匹配的bean进行装配,否则抛出异常
      • 设置 name 属性: 从上下文查找 id 匹配的bean进行装配,否则抛异常
      • 设置 type 属性: 从上下文查找 type 匹配的bean进行装配,若找不出或找到多个则抛异常
      • 没有设置属性: 自动按照 byName进行装配;若没匹配到,则回退一个原始类型进行匹配,如果匹配则自动装配

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

(1)构造器注入: 通过构造器的参数注入给依赖对象,并且初始化对象的时候注入

  • 优点: 对象初始化完成后便获得可使用的对象。
  • 缺点: 当需要注入的对象很多时,构造器参数列表将会很长,不够灵活。若有多重注入方式,没种方式只需注入指定几个依赖,name需要提供多个重载的构造函数。

(2)setter注入: IOC Service Provider 通过调用成员变量提供 setter 函数将被依赖对象注入给依赖类。

  • 优点: 灵活,可选择性地选择需要的对象。
  • 缺点: 依赖对象初始化完成后,由于尚未注入被依赖对象,因此还不能使用。

(3)接口注入: 依赖类必需要实现指定接口,然后实现该接口中的一个函数,该函数用于依赖注入,该函数的参数就是要注入对象。

  • 优点: 接口注入时,接口名、函数名不重要,只要保证函数的参数是要注入的对象类型即可。
  • 缺点: 增加额外功能时,需要提供额外的代码,不建议使用。

5、讲一下什么是Spring

(1)概念: Spring是一个轻量级的IoC和AOP容器框架。是为Java应用程序提供基础性服务的一套框架,目的是用于简化企业应用程序的开发,它使得开发者只需要关心业务需求。常见的配置方式有三种:基于XML的配置、基于注解的配置、基于Java的配置。

(2)模块组成:

  • Spring core:核心类库,提供IOC
  • Spring Content:提供框架式的Bean访问方式,以及企业级功能(JNDI、定时任务等)
  • Spring AOP:AOP服务
  • Spring Dao:对JDBC的抽象,简化了数据访问异常的处理
  • Spring ORM:对现有的ORM框架的支持
  • Spring Web: 提供了基本的面向Web的综合特性,例如多方文件上传
  • Spring MVC:提供面向Web应用的Model-View-Controller实现

6、SpringMVC的理解

(1)什么是MVC模式

MVC是一种设计模式。

(2)MVC的原理:

用户——>发起请求给控制器——>控制器调用业务类——>交付模型层处理,处理结束返回处理结果给控制器——>结果交个视图进行渲染

(3)MVC工作原理

  • 用户发送请求至前端控制器 DispatcherServlet
  • DispatcherServlet 收到请求调用 HandlerMapping 处理器映射器。
  • 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给 DispatcherServlet
  • DispatcherServlet调用 HandlerAdapter 处理器适配器。
  • HandlerAdapter 经过适配调用具体的处理器(Controller,也叫后端控制器)。
  • Controller 执行完成返回 ModelAndView
  • HandlerAdaptercontroller 执行结果 ModelAndView 返回给 DispatcherServlet
  • DispatcherServletModelAndView 传给 ViewReslover 视图解析器。
  • ViewReslover解析后返回具体View。
  • DispatcherServlet 根据View进行渲染视图(即将模型数据填充至视图中)。
  • DispatcherServlet 响应用户。

(4)组件说明

  • DispatcherServlet:作为前端控制器,整个流程控制的中心,控制其它组件执行,统一调度,降低组件之间的耦合性,提高每个组件的扩展性。
  • HandlerMapping:通过扩展处理器映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
  • HandlAdapter:通过扩展处理器适配器,支持更多类型的处理器。
  • ViewResolver:通过扩展视图解析器,支持更多类型的视图解析,例如:jsp、freemarker、pdf、excel等。

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

  • @RequestMapping: 用于处理请求 url 映射的注解,可用于类或方法上。用于类上,则表示类中的所有响应请求的方法都是以该地址作为父路径。
  • @RequestBody: 注解实现接受http请求的json数据,将json转换为java对象
  • @ResponseBody: 注解实现将controller方法返回对象转化为json对象响应给客户

8、谈谈你对Spring的AOP理解

AOP(Aspect-Oriented Programming,面向切面编程),能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可扩展性和可维护性。

Spring AOP是基于动态代理的,如果要代理的对象实现了某个接口,那么Spring AOP就会使用JDK动态代理去创建代理对象;而对于没有实现接口的对象,就无法使用JDK动态代理,转而使用CGlib动态代理生成一个被代理对象的子类来作为代理。

当然也可以使用AspectJ,Spring AOP中已经集成了AspectJ,AspectJ应该算得上是Java生态系统中最完整的AOP框架了。使用AOP之后我们可以把一些通用功能抽象出来,在需要用到的地方直接使用即可,这样可以大大简化代码量。我们需要增加新功能也方便,提高了系统的扩展性。日志功
能、事务管理和权限管理等场景都用到了AOP。


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

Spring AOP是属于运行时增强,而AspectJ是编译时增强。

Spring AOP基于代理(Proxying),而AspectJ基于字节码操作(Bytecode Manipulation

Spring AOP已经集成了AspectJ,AspectJ应该算得上是Java生态系统中最完整的AOP框架了。

如果切面量少,那么两者性能差异不大。但是,当切面太多的话,最好选择AspectJ,它比SpringAOP快很多。


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

(1)区别

  • 关注点是应用中一个模块的行为,一个关注点可能会被定义成一个我们想实现的一个功能。
  • 横切关注点是一个关注点,此关注点是整个应用都会使用的功能,并影响整个应用,比如日志,安全和数据传输,几乎应用的每个模块都需要的功能。因此这些都属于横切关注点。

(2)连接点和切入点

  • 连接点: 连接点代表一个应用程序的某个位置,在这个位置我们可以插入一个AOP切面,它实际上是个应用程序执行Spring AOP的位置。
  • 切入点: 切入点是一个或一组连接点,通知将在这些位置执行。可以通过表达式或匹配的方式指明切入点。

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

通知是个在方法执行前或执行后要做的动作,实际上是程序执行时要通过SpringAOP框架触发的代码段。

Spring切面可以应用五种类型的通知:

  • before: 前置通知,在一个方法执行前被调用
  • after: 在方法执行之后调用的通知,无论方法是否执行成功
  • after-returning: 仅当方法成功完成后执行的通知。
  • after-throwing: 在方法抛出异常退出时执行的通知。
  • around: 在方法执行之前和之后调用的通知。

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

(1)IOC的概念: 是指创建对象的控制权的转移。以前创建对象的主动权和时机是由自己把
控的,而现在这种权力转移到Spring容器中,并由容器根据配置文件去创建实例和管理各个实例之
间的依赖关系。对象与对象之间松散耦合,也利于功能的复用。

(2)最直观的表达就是,IOC让对象的创建不用去new了,可以由spring自动生产,使用java的反
射机制,根据配置文件在运行时动态的去创建对象以及管理对象,并调用对象的方法的。

(3)Spring的IOC有三种注入方式 :构造器注入、setter方法注入、根据注解注入。

IOC与AOP的概念: IoC让相互协作的组件保持松散的耦合,而AOP编程允许你把遍布于应用各层的功能分离出来形成可重用的功能组件。


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

在面试中,完全可以直接说,Bean的生命周期是 实例化 》 属性赋值 》 初始化 》使用 》 销毁

然后回答实例化、属性赋值、初始化、使用、销毁的实现方式。

  • 实例化: Spring通过反射或其它方式创建Bean实例
  • 属性赋值: 通过setter方法赋值,进行初始化和使用
  • 初始化: 通过实现 InitializingBean 接口进行初始化或者通过配置文件指定init-method自定义初始化过程
  • 销毁: 通过配置文件指定destroy-method自定义销毁过程 或 本身实现 DisposableBean 接口进行销毁。

(1)Servlet的生命周期: 实例化 》初始化init 》 接收请求service 》 销毁destroy

(2)Spring 上下文中的 Bean 声明周期与Servlet生命周期

  • 实例化Bean: 对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean进行实例化。对于ApplicationContext容器,当容器启动结束后,通过获取 BeanDefinition 对象中的信息,实例化所有的bean。
  • 设置对象属性(DI): 实例化后的对象被封装在 BeanWrapper 对象中,Spring 根据 BeanDefinition 中的信息 以及 通过 BeanWrapper 提供的设置属性的接口完成依赖注入。
  • 处理Aware接口: Spring会检测该对象是否实现了xxxAware接口,并将相关的xxxAware实例注入给Bean:
    • 如果这个 Bean 已经实现了 BeanNameAware 接口,会调用它实现的 setBeanName(String beanId),此处传递的就是Spring配置文件中的Bean的Id值
    • 如果这个Bean实现了BeanFactoryAware 接口,会调用它实现的 setBeanFactory() 方法,传递的是Spring工厂自身。
    • 如果这个Bean实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文。
  • BeanPostProcessor: 如果想对Bean进行一些自定义的处理,那么可以让Bean实现了BeanPostProcessor接口,那将会调用postProcessBeforeInitialization(Object obj, String s)方法。
  • InitializingBean 与 init-method: 如果Bean在Spring配置文件中配置了 init-method 属性,则会自动调用其配置的初始化方法。
  • 如果这个Bean实现了BeanPostProcessor接口,postProcessAfterInitialization(Object obj, String s)方法;由于这个方法是在Bean初始化结束时调用的,所以可以被应用于内存或缓存技术
  • DisposableBean: 当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用其实现的destroy()方法
  • destroy-method: 如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。

14、解释Spring支持的集中bean的作用域?

Spring Bean 分为 5 个范围:

  • singleton: 默认,每个容器中只有一个bean的实例,单例的模式由BeanFactory自身来维护。
  • prototype: 为每个bean请求提供一个实例。
  • request: 为每个请求都提供一个实例,当请求完成则失效并回收。
  • session: 与request范围类似,确保每个session中有个bean的实例,在session过期后,bean会随之失效。
  • global-session: 全局作用域。

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

(1)Set方法注入
(2)构造器注入:

  • 通过index设置参数的位置
  • 通过type设置参数类型
    (3)静态工厂注入
    (4)实例工厂

通常只要回答前两种即可,不然很容易被继续问。
接下来后两种的实现方式

静态工厂注入的方式

(1)创建对象类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Card {
	private String cno;
	private String cpwd;
}

(2)创建静态工厂

public class StaticFactory {
	public static Card getCard(){
		return new Card("1","666666");
	}
}

(3)配置bean


<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
 
	

	<bean id="cardStatic" class="com.util.StaticFactory" factory-method="getCar">
		<constructor-arg value="1" />
	bean>
beans>

(4)注入bean


public class SpringTemp {
 
	@Test
	public void createBean() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
		Card card=(Card) ctx .getBean("cardStatic");
		System.out.println(card);
	}
}

实例工厂注入

(1)创建实例工厂

public class InstanceFactory{
	private Card card = null;

	public InstanceFactory(){
		card = new Card(null,null);
	}
	public Card getCard(){
		return card;
	}
}

(2)配置文件


<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
 
	<bean id="cardFactory" class="com.util.InstanceFactory">bean>
	<bean id="cardInstance" factory-bean="cardFactory" factory-method="getCar">
		<constructor-arg value="2" />
	bean>
beans>

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

  • 简单工厂模式: Spring 中的 BeanFactory 就是简单工厂模式的体现。根据传入唯一的标识获得 Bean 对象,但是在传入参数后创建还是传入参数前创建,根据具体情况来定。
  • 工厂模式: Spring中的 FactoryBean 就是典型的工厂方法模式,实现了 FactoryBean 接口的 bean 是一类叫做 factory 的 bean。其特点是,spring 在使用 getBean() 调用获得该 bean 时,会自动调用该 bean 的 getObject() 方法,所以返回的不是 factory 这个 bean,而是这个 bean.getObject() 方法的返回值。
  • 单例模式: 在 spring 中用到的单例模式由:scope="singleton,注册式单例模式,bean 存放于 Map 中。 bean name 作为 key,bean 作为 value。
  • 原型模式: 在 spring 中用到的单例模式由:scope="prototype,每次获取的是通过克隆生成的新实例,对其进行修改时对原有实例对象不造成任何影响。
  • 迭代器模式: 在 Spring 中有个 CompositeIterator 实现了 Iterator,Iterable 接口和 Iterator 接口,这两个都是迭代相关的接口。可以这么认为,实现了 Iterable 接口,则表示某个对象是可被迭代的。Iterator 接口相当于是一个迭代器,实现了 Iterator 接口,等于具体定义了这个可被迭代的对象时如何进行迭代的。
  • 代理模式: Spring 中经典的 AOP,就是使用动态代理实现的,分 JDK 和 CGlib 动态代理。
  • 适配器模式: Spring 中的 AOP 中 AdvisorAdapter 类,它有三个实现:MethodBeforAdviceAdapter、AfterReturnningAdviceAdapter、ThrowsAdviceAdapter。Spring会根据不同的 AOP 配置来使用对应的 Advice,与策略模式不同的是,一个方法可以同时拥有多个Advice。Spring 存在很多以 Adapter 结尾的,大多数都是适配器模式。
  • 观察者模式: Spring 中的 Event 和 Listener。spring 事件:ApplicationEvent,该抽象类继承了EventObject 类,JDK 建议所有的事件都应该继承自 EventObject。spring 事件监听器:ApplicationListener,该接口继承了 EventListener 接口,JDK 建议所有的事件监听器都应该继承EventListener。
  • 模板模式: Spring 中的 org.springframework.jdbc.core.JdbcTemplate 就是非常经典的模板模式的应用,里面的 execute 方法,把整个算法步骤都定义好了。
  • 责任链模式: DispatcherServlet 中的 doDispatch() 方法中获取与请求匹配的处理器HandlerExecutionChain,this.getHandler() 方法的处理使用到了责任链模式。

注意: 这里只是列举了部分设计模式,其实里面用到了还有享元模式、建造者模式等。


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

(1)包目录不同
-** BeanFactory:spring-beans.jar 中 org.springframework.beans.factory.BeanFactory**

  • ApplicationContext:spring-context.jar 中 org.springframework.context.ApplicationContext

(2)国际化

  • BeanFactory 是不支持国际化功能的,因为 BeanFactory 没有扩展 Spring 中 MessageResource接口。
  • ApplicationContext 扩展了 MessageResource 接口,因而具有消息处理的能力。

(3)强大的事件机制(Event)

ApplicationContext 的事件机制主要通过 ApplicationEventApplicationListener 这两个接口来提供的,和 Java swing 中的事件机制一样。即当 ApplicationContext 中发布一个事件时,所有扩展了 ApplicationListener 的 Bean 都将接受到这个事件,并进行相应的处理。

(4)底层资源的访问

  • ApplicationContext 扩展了 ResourceLoader(资源加载器)接口,从而可以用来加载多个Resource。
  • BeanFactory 是没有扩展 ResourceLoader。

(5)对 Web 应用的支持

  • BeanFactory:以编程的方式被创建
  • ApplicationContext:以声明的方式创建

(6)延迟加载

  • BeanFactory 采用延迟加载注入 Bean 的,即 只有使用到 Bean(调用getBean()) 的时候才对它实例化。
  • ApplicationContext 是在容器启动时,一次性创建了所有的 Bean。
  • BeanFactory 和 ApplicationContext 都支持BeanPostProcessor,区别在于前者手动注册,后者自动注册

BeanFactory 主要用于 Spring框架的基础设施,面向 Spring 本身。
ApplicationContext 主要用于开发场景,面向 Spring 开发者,并且包含了 BeanFactory 的所有功能,还支持 Spring 的各种插件,还以一种面向框架的方式工作以及对上下文进行分层和实现继承。


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

Spring 框架并没有对单例 Bean 进行任何多线程的封装处理。

  • 关于单例 Bean 的线程安全和并发问题,需要开发者自行处理。
  • 单例的线程安全问题,并不是 Spring 去关心的。Spring 应该做的是,提供根据配置,创建单例 Bean 或多例 Bean 的功能。

实际上,大多数的Spring Bean 并没有可变的状态,在某种程度上, Spring 的单例 Bean 是线程安全的,如果 Bean 有多重状态的话,就需自行保证线程安全,最初级的方法就是 @Scope="prototype"


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

流程:主要是 三级缓存存储 和 提前曝光

(1)首先依赖 A 完成初始化第一步就是自己提前曝光(通过 ObjectFactory 将自己曝光),在初始化的时候,发现自己依赖对象 B,此时就会尝试 get(B),这个时候会发现 B 未创建。
(2)B 开始初始化流程,在 B 初始化的时候,同样发现自己依赖 C,C 也没有被创建出来。
(3)C 开始初始化进程,但是初始化时发现自己依赖 A ,于是 get(A),这个时候 A 已经添加到缓存中(一般都是添加到三级缓存 singletonFactories),通过 ObjectFactory 提前曝光,所以可以通过 ObjectFactory.getObject() 方法拿到 A,C 拿到 A 对象后顺利完成初始化,然后将自己添加到一级缓存中。
(4)回到 B,B 也可以拿到 C 对象,完成初始化,A 可以顺利拿到 B 完成初始化。


20、说说事务的隔离级别

  • 未提交读(Read Uncommitted): 允许脏读,也就是可能读取到其它会话中未提交实物修改的数据。
  • 提交读(Read Committed): 只能读取到已经提交的数据,Oracle 等多数数据库默认都是该级别(不重复读)。
  • 可重复读(Repeated Read): 在同一个事务内的查询都是事务开始时刻一致的,Mysql的InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻读(多个事务修改同一数据,事务之间不知道彼此的存在,当事务提交后,后面事务修改的数据将会覆盖前事务,那么前一个事务读取该数据时,就是幻读)
  • 可串行化(Serializable): 完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞。

21、说说事务的传播级别

  • PROPAGATION_REQUIRED: 默认的Spring事物传播级别,若当前存在事务,则加入该事务,若不存在事务,则新建一个事务。
  • PAOPAGATION_REQUIRE_NEW: 若当前没有事务,则新建一个事务。若当前存在事务,则新建一个事务,新老事务相互独立。外部事务抛出异常回滚不会影响内部事务的正常提交。
  • PROPAGATION_NESTED: 如果当前存在事务,则嵌套在当前事务中执行。如果当前没有事务,则新建一个事务,类似于REQUIRE_NEW。
  • PROPAGATION_SUPPORTS: 支持当前事务,若当前不存在事务,以非事务的方式执行。
  • PROPAGATION_NOT_SUPPORTED: 以非事务的方式执行,若当前存在事务,则把当前事务挂起。
  • PROPAGATION_MANDATORY: 强制事务执行,若当前不存在事务,则抛出异常。
  • PROPAGATION_NEVER: 以非事务的方式执行,如果当前存在事务,则抛出异常。

Spring事务传播级别一般不需要定义,默认就是PROPAGATION_REQUIRED,除非在嵌套事务的情况下需要重点了解。


22、Spring 事务实现方式

  • 编程式事务管理: 这意味着你可以通过编程的方式管理事务,这种方式带来了很大的灵活性,但很难维护。
  • 声明式事务管理: 这种方式意味着你可以将事务管理和业务代码分离。你只需要通过注解或者XML配置管理事务。

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

  • 为不同的事务API(如JTA, JDBC, Hibernate, JPA, 和JDO)提供了统一的编程模型。
  • 为编程式事务管理提供了一个简单的API而非一系列复杂的事务API(如JTA)。
  • 支持声明式事务管理。
  • 可以和 Spring 的多种数据访问技术很好的融合。

24、事务三要素是什么?

(1)数据源: 表示具体的事务性资源,如MySQL

(2)事务管理器: 从整体上管理事务的处理过程,如打开、提交、回滚等。

(3)事务应用和属性配置: 像一个标识符,表明哪些方法参与事务,如何参与事务,以及一些相关属性,如隔离级别、超出时间等。


24、 事务注解的本质是什么?

@Transactional 这个注解仅仅是一些(和事务相关的)元数据,在运行时被事务基础设施读取,并使用这些元数据来配置bean的事务行为。

大致来说具有两方面功能:一是表明该方法要参与事务;二是配置相关属性来定制事务的参与方式和运行行为。

声明式事务主要是得益于Spring AOP。使用一个事务拦截器,在方法调用的前后/周围进行事务性增强(advice),来驱动事务完成。

@Transactional 注解既可以标注在类上,也可以标注在方法上。当在类上时,默认应用到类里的所有方法。如果此时方法上也标注了,则方法上的优先级高。 另外注意方法一定要是public的。

你可能感兴趣的:(java,spring,开发语言)