Spring 面试题总结

1.Spring框架的基本理解(重点)

记忆关键字:1.核心思想(IOC、AOP)2.作用(解耦、简化)3.简单描述框架组成

定义: Spring是一个轻量级的控制反转(loC)和面向切面(AOP)的容器(框架)。

**核心思想:**核心是IOC(控制反转)和AOP(面向切面编程)

**作用:**用于组件之间的解耦,以及简化第三方JavaEE中间技术的使用(JMS、任务调度、缓存、ORM框架

**框架组成:**IOC容器、Validation数据校验、AOP面向切面编程、Transactions事务管理、Spring JDBC、Spring MVC框架、以及各类第三方JavaEE中间件技术集成。


2、Spring框架由哪些模块组成?(重点)

记忆关键字:官方文档描述,由7个模块组成

Spring Framework根据官方文档的描述,主要包括以下常用5个模块:

①core:核心模块

包括:IOC Container(loc容器),Events(事件通知机制)、Resources(资源加载机制)、i18n(国际化)、Validation(数据校验).Data Binding(数据绑定)、Type Conversion(类型转换),SpEL(Spring表达式)、AOP(面向切面编程)

②Testing:测试模块

包括:Mock Obiects(测试模拟对象),TestContext Framework(测试框架),Spring MVCTest(用于测试Spring Mvc),webTestclient(用于测试 Webclient、Restful、webflux等);

③Data Access:数据访问模块

包括:Transactions(事务管理),DAOsupport(统一的Data Access Object DAO模式封装),JDBc(Spring对于DC的操作封装),O/RMapping(Spring 对于对象关系映射框架的封装,例如Hibernate等框架)等;

④Web Servlet:基于Servlet的Web应用开发

包括:Spring MNc( Spring基于MVC模式设计封装的Web框架),Websocket(Spring集成Websocket,websocket是一个服务器与客户端双向通信的技术)等;

⑤Integration:企业级系统集成模块(不同系统之间的交互集成)

包括:Remoting(spring 用于在分布式系统中进行远程服务调用的通讯框架),IMS(Spring集成各类Java消息中间件、Java消息服务[JavaMessage Service]、例如ActiveMQ等),Java Emai1(邮件发送),Tasks Scheduling(任务调度);


3.Spring IOC的理解(重点)

记忆关键字:IOC名词解释,作用是解耦,使用IOC容器管理项目组件之间的耦合关系。

lOC(Inversion of Control,中文释义∶控制反转),是Spring框架的核心思想之一,主要用于解耦。

IOC是指将创建对象的控制权转移给Spring框架进行管理,由Spring框架根据配置文件或注解等方式,创建bean对象并管理各个bean对象之间的依赖关系。使对象之间形成松耦合的关系,实现解耦。

控制:指的是对象的创建(实例化、管理)的权利

反转:控制权交给外部环境(Spring框架、IOC容器)


4.Spring IOC容器的理解(重点)

记忆关键字:IOC容器的作用、存储形式、初始化过程

①I0C通常被理解为IOC Container容器,I0C容器其实就是一个Map,key是每个 bean对象的ID,value是bean对象本身。IOC容器负责创建bean对象并管理 bean的生命周期并且根据配置好配置文件或注解,管理IOC容器中的每个bean,以及根据 bean之间的依赖关系,完成bean之间的注入。

②IOC容器属于Spring core模块,用来创建和管理Bean,默认使用单例的方式将bean存储在DefaulListableBeanFactory类的beanDefinitionMap中(-个 ConcurrentHashMap类型的Map集合);

③IOC容器使用ConcurrentHashMap集合存储了BeanDefinition对象,该对象封装了Sprin8对一个Bean所有配置信息,包括:类名,属性,构造方法参数,依赖,是否延迟加载,是否是单例等配置信息;


5.Spring DI的理解

记忆关键字:名词解释

DI ( Dependecy Inject,中文释义︰依赖注入)是对IOC概念的不同角度的描述,是指应用程序在运行时,每一个bean对象都依赖IoC容器注入当前bean对象所需要的另外一个bean对象。(例如在(MyBatis 整合Spring时, SqlSessionFactoryBean依赖(IOC 容器注入一个Datasource数据源bean ) ;


6.什么是Spring 的bean

简单来说,Bean代表被IoC容器管理的对象。

我们通过配置文件或注解,告诉IoC容器帮助我们管理哪些对象。

复制代码
<bean id="student2" class="com.ztt.pojo.Student">
<constructor-arg name="stuName" value="甜甜"></constructor-arg>
<constructor-arg name="stuAge" value="18"></constructor-arg>
<constructor-arg name="stuHobby" value="学习"></constructor-arg>
</bean>

7.将一个类声明为Bean的注解有哪些?

@Component:定义通用Bean的注解,可标注任意类为Bean。如果一个Bean 不知道属于哪个层,可以使用@Component注解标注。

@Repository:定义数据访问层Bean的注解。

@service:定义业务层Bean的注解。

@controller:定义控制器Bean的注解。


8.@Component和@Bean的区别是什么?

@Component 注解作用于类,而@Bean注解作用于方法。
@Component通常是通过类路径扫描来实现自动扫描并完成装配Bean到Spring Ioc容器中。

@Bean注解通常用于注解某个方法,通过@Bean注解告诉了Spring Ioc容器,该方法的返回值实例是一个Bean 。


9.@Autowired和@Resource的区别是什么?

@Autowired是 Spring提供的注解,@Resource是JDK提供的注解。

@Autowired默认的注入方式为byType(按类型自动注入),@Resource默认注入方式为 byName(按名称自动注入)。


10.Spring框架中的常见注入方式有几种?

记忆关键字:整体介绍三种注入方式、分别介绍每个注入方式的细节.

Spring Ioc有三种注入方式:构造注入、Setter注入、属性注入;
构造注入 :使用构造方法注入bean ;
Setter注入 :使用Setter方法注入bean ;
属性注入:使用成员属性注入bean,不推荐。原因:使用私有的成员属性变量,依靠反射实现,破坏封装,只能依靠IoC容器实现注入,不严谨;


11. Spring中常见的ApplicationContext实现类有哪些?

记忆关键字:分别介绍每种实现类或子接口

ClassPathXmlApplicationContext: 根据项目类路径classpath下的配置文件加载bean **FileSystemXmlApplicationContext:**根据当前磁盘的一个绝对系统文件路径下的配置文件加载bean ;

**AnnotationConfigApplicationcontext:**根据读取到的注解加载bean ;

webApplicationContext : web容器下按照配置文件加载 bean ;


12. BeanFactory和ApplicationContext有什么区别?

记忆关键字:两者之间的关系、区别与不同、Bean的创建加载方式

两者之间的关系: BeanFactory 和ApplicationContext 是 Spring 的两大核心接口,都可以当做Spring 的容器;

两者区别与不同:

BeanFactory是 Spring里面最底层的接口,是Ioc的核心,定义了Ioc的基本功能,包含了各种Bean的定义、加载、实例化,依赖注入和生命周期管理等行为;

ApplicationContext接口作为BeanFactory 接口的子接口,包含BeanFactory所具备的功能外,还提供了其它框架功能:继承MessageSource(支持国际化),资源文件访问、可以同时加载多个配置文件、可以通过监听器管理bean的生命周期;

Bean的创建加载方式:

BeanFactroy采用的是延迟加载形式来注入Bean,只有在使用到某个 Bean时,才对该Bean进行加载实例化。这样不能提前发现一些存在的 Spring 的配置问题。如果 Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean()方法才会抛出异常;

ApplicationContext是在容器启动时,一次性创建了所有的 Bean。这样,在容器启动时,我们就可以发现Spring 中存在的配置错误,这样有利于检查所依赖属性是否注入。ApplicationContext 启动后预载入所有的单实例 Bean,所以在运行的时候速度比较快,因为它们已经创建好了。相对于 BeanFactory , ApplicationContext唯一的不足是占用内存空间,当应用程序配置Bean较多时,程序启动较慢;


14. Spring框架中的Bean的作用域
  • singleton : Spring 只会为该bean对象只会创建唯一实例,Spring中的 bean默认都是单例;
  • prototype:每次获取 bean ,Spring会创建一个新的bean 实例;
  • request:每一次HTTP 请求,Spring会创建一个新的bean 实例;
  • session:不同的HTTP会话,Spring会创建不同的bean 实例;

通过XML方式设置bean的作用域

复制代码
通过XML方式设置bean的作用域
1<bean id="demoDaoBean" class=" com.apesource.dao.DemoDAOImpl" scope="singleton" />

通过注解方式设置bean的作用域

复制代码
1 @Scope(configurableBeanFactory.sCOPE_PROTOTYPE)
2public class DemoDAOImpl implements IDemoDAO{ }
15. Spring框架中的Bean的线程安全
  • 对于 prototype作用域的Bean,每次都创建一个新对象,也就是线程之间不存在Bean共享,因此不会有线程安全问题
  • 对于singleton作用域的Bean,所有的线程都共享一个单例状态的 Bean,存在资源竞争,因此是存在线程安全问题的
  • 解决办法:
    • 对于singleton作用域的单例bean,它的线程安全问题,常见有两种解决办法:
      • 在bean中尽量避免定义可变的成员变量(用于保存数据的成员变量);
      • 在类中定义一个ThreadLocal成员变量,将需要可变的成员变量保存在ThreadLocal中;

16.Spring 框架中的Bean生命周期
  • Spring Bean 的生命周期总体分四个阶段:实例化=>属性注入=>初始化=>销毁
  • Step1实例化Bean:根据配置文件中Bean 的定义,利用Java Reflection反射技术创建Bean的实例
  • Step2注入对象依赖的属性值(或对象)
  • Step3处理各种Aware接口:Spring 会检测该Bean是否实现了xxxAware接口,通过(Aware类型的接口,可以让Spring框架为当前Bean注入相应的内容。
    • 如果Bean实现 BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,注入Bean的名字;
    • 如果 Bean实现 BeanclassLoaderAware接口,调用setBeanClassLoader()方法,注入classLoader对象的实例;
    • 如果Bean实现BeanFactoryAware 接口,会调用它实现的setBeanFactory()方法,注入的是Spring工厂;
    • 如果 Bean实现 ApplicationContextAware接口,会调用setApplicationContext()方法,注入Spring上下文;
  • Step4执行BeanPostProcessor前置处理:如果想对Bean进行一些自定义的前置处理,那么可以让Bean 实现了(BeanPostProcessor接口,将会在该阶段调用postProcessBeforeInitialization(Object obj,string s)方法。
  • Step5执行InitializingBean初始化方法:如果Bean 实现了InitializingBean接口,执行afeterPropertiesSet()方法。
  • Step6执行init-method自定义初始化方法:如果Bean 在 Spring 配置文件中配置了init-method属性,则会自动调用其配置的初始化方法。
  • .Step7执行BeanPostProcessor后置处理:如果这个 Bean实现了BeanPostProcessor接口,将会调用postProcessAfterInitialization(0bject obj,string s)方法,由于这个方法是在 Bean初始化结束后调用;
  • 以上几个步骤完成后,|Bean已经被正确创建,可以正常使用这个Bean
  • Step8执行DisposableBean销毁Bean:当Bean 不再需要时,会经过清理阶段,如果Bean 实现了DisposableBean这个接口,会调用其实现的destroy()方法执行销毁;
  • Step9执行destroy-method自定义销毁方法:如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的自定义销毁方法。

17.Spring框架如何解决循环依赖?
  • 循环依赖问题是指:类与类之间的依赖关系形成了闭环,就会导致循环依赖问题的产生。例如A类依赖了B类,B类依赖了C类,而最后C类又依赖了A类,这样就形成了循环依赖问题;

一级缓存:存储的是完整的、初始化后的单例(Singleton)Bean 实例。

二级缓存:存储的是早期的 Bean 实例,通常是已经实例化但还未进行完全初始化(如未完成属性填充)的 Bean。

三级缓存:存储的是一个 Bean 的工厂对象,用于创建半成品的 Bean 实例(通常是代理对象)。


18. Spring框架中有哪些注解?
  • 用于声明Bean的注解:
    • @Component:定义通用Bean的注解,可标注任意类为Bean。如果一个Bean 不知道属于哪个层,可以使用@Component注解标注。
    • @Repository:定义数据访问层Bean的注解。
    • @service:定义业务层Bean的注解。
    • @controller:定义控制器Bean的注解。
  • 用于注入的注解:
    • @Autowired :按类型自动注入
    • @Qualifier :按名称自动注入
  • 声明配置、扫描、启用特性的注解:
    • @Configuration :声明配置类
    • @Componentscan :组件扫描
    • @Enablescheduling :启用任务调度
    • @EnableAspectAutoProxy :启用自动代理工厂

19. Spring框架中用到的设计模式
  • 工厂模式: Spring使用工厂模式,通过BeanFactory或 Applicationcontext来创建对象;
  • 单例模式: Bean默认作用域为单例,按照单例设计模式进行设计实现;
  • 策略模式:Resource的实现类,针对不同的资源文件,实现了不同方式的资源获取策略;
  • 代理模式:Spring 的AOP的实现依靠动态代理(JDK的反射和CGLIB) ;
  • 模板方法:Spring 提供了JdbcTemplate,RedisTemplate等模板对象,将相同的操作步骤进行了封装;
  • 适配器模式:Spring AoP 的增强或通知(Advice)使用到了适配器模式,Spring MvC 中也用到了适配器模式适配Controller ;

20. Spring框架中AOP的基本理解
  • 关键字:AOP名词解释,AOP实现原理(动态代理)
  • AOP ( Aspect-Oriented Programming:面向切面编程)︰将那些与业务无关,却为业务模块所共同调用的逻辑(例如事务处理、日志管理、权限控制等)封装抽取成一个可重用的模块,这个模块被命名为"切面"(Aspect ),便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性;
  • Spring AOP基于动态代理实现:
    • 如果被代理的对象,已经实现某个接口,则Spring AOP会使用JDK Proxy(反射),基于接口的方式,创建代理对象(JDK动态代理的核心是(InvocationHandler 接口和Proxy类);
    • 如果被代理的对象,没有实现某个接口,就无法使用JDK Proxy去进行代理了,这时候Spring AOP会使用Cglib,基于继承的方式,生成一个被代理对象的子类来作为代理(cglib动态代理的核心是 MethodInterceptor接口和Enhancer类);

21.Spring AOP和AspectJ AOP有什么区别?
  • 关键字:增强方式的差异(运行时、编译时),实现方式的差异(动态代理、字节码操作)
  • Spring AoP已经集成了Aspect], Aspect]是一个Java技术生态系统中实现 AOР编程思想的独立框架;Aspect]相比于Spring AOP功能更加强大,但是Spring AoP相对来说更简单更容易;
  • Spring AOP属于运行时增强,而Aspect是编译时增强;
  • Spring AOP基于动态代理(Proxying ),而Aspect]基于字节码操作( Bytecode Maripulation );

22. Spring AOP有哪些通知类型?
  • 关键字:分别介绍每种通知的实现接口,执行方式
  • 前置通知:实现 MethodBeforeAdvice接口,在目标方法调用前,执行通知;
  • 环绕通知:实现 MethodInterceptor 接口,是一个包围目标方法的通知。环绕通知可以在方法调用前后完成自定义的行为。
  • 后置通知:实现AfterReturningAdvice接口,在在目标方法调用后,执行通知(如果方法抛出异常,则不执行通知);
  • 异常通知:实现ThrowsAdvice接口,在方法抛出异常时,执行通知;

23. Spring 管理事务的方式有几种?
  • 编程式事务︰在代码中硬编码(不推荐使用):通过TransactionTemplate或者TransactionManager手动管理事务,实际应用中很少使用,用于理解Spring事务管理。
  • 声明式事务:在XML配置文件或者基于注解@Transactional推荐使用),通过AOP实现。

24. Spring事务中有哪几种事务传播行为?
  • 事务传播行为是为了解决业务层方法之间互相调用时,产生事务问题。
  • 当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。
  • 事务传播行为有如下分类:
  1. TransactionDefinition.PROPAGATION_REQUIRED

如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。@Transactiona1注解默认使用的事务传播行为。

2.TransactionDefinition.PROPAGATION_REQUIRES_NEW

创建一个新的事务,如果当前存在事务,则把当前事务挂起。也就是说不管外部方法是否开启事务,Propagation.REQUIRES_NEw修饰的内部方法会新开启自己的事务,且开启的事务相互独立,互不干扰。

3.TransactionDefinition.PROPAGATION_NESTED

如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。

4.TransactionDefinition.PROPAGATION_MANDATORY

如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:代表强制性)

5.TransactionDefinition.PROPAGATION_SUPPORTS

如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。

  1. TransactionDefinition.PROPAGATION_NOT_sUPPORTED

以非事务方式运行,如果当前存在事务,则把当前事务挂起。7.TransactionDefinition.PROPAGATION_NEVER

以非事务方式运行,如果当前存在事务,则抛出异常。


25.Spring 事务中有哪几种事务隔离级别?
  1. TransactionDefinition.ISOLATION_DEFAULT 默认隔离级别

使用当前数据库的默认隔离级别,MySQL默认采用的是可重复读REPEATABLE_READ隔离级别。oracle 默认采用的是读已提交READ_COMMITTED隔离级别.

  1. TransactionDefinition.ISOLATION_READ_uNCOMMITTED读未提交

最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读3. TransactionDefinition.ISOLATION_READ_COMMITTED读已提交

允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生4. TransactionDefinition.ISOLATION_REPEATABLE_READ可重复读

对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。

  1. TransactionDefinition.ISOLATION_SERIALIZABLE串行化

最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。


26. Spring事务在什么情况下会失效

1.数据库不支持事务

Spring事务生效的前提是所连接的数据库要支持事务,如果底层的数据库都不支持事务,则Spring的事务肯定会失效。例如:如果使用的数据库为MysQL,并且选用了MyISAM存储引擎,则 Spring 的事务就会失效。

2.事务方法未被Spring管理

如果事务方法所在的类没有加载到Spring Ioc 容器中,也就是说,事务方法所在的类没有被Spring 管理,则Spring 事务会失效。例如: Productservice类上没有标注@service注解,(Product的实例没有加载到Spring Ioc容器中,就会造成_updateProductStockCountById()方法的事务在Spring中失效。

复制代码
public class ProductService {
@Autowired
private ProductDao productDao;
@Transactional(propagation = Propagation.REQUIRES_NEw)
public void updateProductStockCountById(Integer stockCount,Long id){productDao.updateProductstockcountById(stockCount,id);
}
}

3.方法没有被public修饰

如果事务所在的方法没有被public修饰,此时Spring 的事务会失效,例如:虽然 ProductServEice上标注了@service注解,同时updateProductstockCountById()方法上标注了@Transactional(propagation = Propagation.REQUIRES_NEW)注解。

但是,由于updateProductStockCountById()方法为内部的私有方法(使用 private修饰),那么此时updateProductStockCountById()方法的事务在Spring中会失效。

复制代码
@service
public class ProductService {@Autowired
private ProductDao productDao;
@Transactional(propagation = Propagation.REQUIRES_NEw)
private void updateProductStockCountById(Integer stockCount,Long id){productDao.updateProductstockCountById(stockcount, id);
}

4.同一类中方法调用

如果同一个类中的两个方法分别为A和B,方法A上没有添加事务注解,方法B上添加了@Transactional事务注解,方法A调用方法B,则方法B的事务会失效。例如:(submitorder()方法和updateProductStockCountById()方法都在OrderService类中,submitOrder()方法上没有标注事务注解,_updateProductStockCountById()方法上标注了事务注解,submitorder()方法调用了(updateProductStockCountById()方法,此时,(updateProductStockCountById()方法的事务在Spring中会失效。

复制代码
@Service
public class orderService {
@Autowired
private OrderDao orderDao;
@Autowired
private ProductDao productDao;
public void submitorder( ){//生成订单
order order = new Order();
long number = Math.abs(new Random( ).nextInt( 500) );order.setId(number);
order.setOrderNo( "order_" +number);orderDao.saveOrder( order);
//减库存
this.updateProductstockCountById(1,1L);}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateProductStockCountById(Integer stockCount,Long id){productDao.updateProductStockCountById(stockCount,id);
)

5.未配置事务管理器

如果在项目中没有配置Spring的事务管理器,即使使用了Spring 的事务管理功能,Spring 的事务也不会生效。例如:没有在项目的配置类中配置如下代码。

复制代码
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}

6.方法的事务传播类型不支持事务

如果内部方法的事务传播类型为不支持事务的传播类型,则内部方法的事务在Spring 中会失效。例如:由于(updateProductStockCountById()方法的事务传播类型为(NOT_SUPPORTED,不支持事务,则updateProductstockcountById()方法的事务会在Spring中失效。

复制代码
@Service
public class OrderService {@Autowired
private OrderDao orderDao;@Autowired
private ProductDao productDao;
@Transactional(propagation = Propagation.REQUIRED)public void submitOrder( ){
/生成订单
order order = new Order( );
long number = Math.abs ( new Random( ).nextInt(500) );order.setId(number) ;
order.setOrderNo( "order_" + number) ;orderDao.saveOrder(order);
//减库存
this.updateProductStockCountById(1,1L);}
@Transactional( propagation = Propagation.NOT_SUPPORTED)
public void updateProductStockCountById( Integer stockCount,Long id){productDao.updateProductStockCountById(stockCount, id);
}
}

7.不正确的捕获异常

不正确的捕获异常也会导致Spring 的事务失效。例如: updateProductStockCountById()方法中使用try-catch 代码块捕获了异常,即使(updateProductStockCountById()方法内部会抛出异常,但也会被catch代码块捕获到,此时updateProductStockCountById()方法的事务会提交而不会回滚,并且 submitorder()方法的事务会提交而不会回滚,这就造成了(Spring 事务的回滚失效问题。

复制代码
service
public class orderService {@Autowired
private orderDao orderDao;@Autowired
private ProductDao productDao;
@Transactional( propagation = Propagation.REQUIRED)public void submitorder(){
l/生成订单
order order = new Order();
long number - Math.abs(new Random( ).nextInt (500) );order.setId( number);
order.setOrderNo( "order_" + number);orderDao.saveorder(order);
//减库存
this.updateProductStockCountById(1,1L);}
@Transactional(propagation = Propagation.REQUIRED)
public void updateProductstockCountById(Integer stockCount,Long id){try{
productDao.updateProductstockcountById(stockcount,id);int i = 1 / 0;
}catch(Exception e){
logger.error("扣减库存异常: ", e.getMesaage( ));}
}}

8.错误的标注异常类型

如果在@Transactional注解中标注了错误的异常类型,则Spring事务的回滚会失效。例如:在(updateProductStockCountById()方法中捕获了异常,并且在异常中抛出了(Exception类型的异常,此时,updateProductstockcountById()方法事务的回滚会失效。"

为何会失效呢?这是因为Spring 中对于默认回滚的事务异常类型为(RuntimeException,上述代码抛出的是Exception异常。

默认情况下,Spring 事务中无法捕获到Exception异常,所以此时updateProductstockCountById()方法事务的回滚会失效。

复制代码
@Transactional(propagation = Propagation.REQUIRED)
public void updateProductstockCountById(Integer stockCount,Long id){
try{
productDao.updateProductStockCountById(stockCount, id);}catch(Exception e){
logger.error( "扣减库存异常:",e.getMesaage());throw new Exception("扣减库存异常");
}
}

此时可以手动指定updateProductstockCountById()方法标注的事务异常类型,如下所示:

复制代码
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)

27.谈谈对SpringMVC的理解?

首先,MC模式是模型(Model )、视图(View )、控制器(Controller )的简写,其核心思想是通过将请求处理控制、业务逻辑、数据封装、数据显示等流程节点分离的思想来组织代码。

所以,MVC是一种设计模式,而Spring MVC是一款基于(MVC设计模式思想实现的的MVC框架,属于Spring技术栈的一部分。Spring MVC可以帮助我们进行更简洁的 web层的开发,并且它天生与Spring框架集成,更利于架构的设计与搭建。


28. SpringMVC的工作原理(执行流程)?

1.客户端(浏览器)发送请求,统一由DispatcherServlet拦截处理请求。

  1. DispatcherServlet根据请求信息调用HandlerMapping 。HandlerMapping根据uri去

匹配查找能处理的Handler(也就是我们定义的Controller控制器),并会将请求涉及到的拦截器和Handler一起封装。

  1. DispatcherServlet调用HandlerAdapter适配执行Handler。

  2. Handler 完成对用户请求的处理后,会返回一个ModelAndView模型视图对象给 DispatcherSe

rvlet。ModelAndView中包含了数据模型以及相应的视图信息。Model是返回的数据对象,iew是view视图的逻辑名称。

  1. ViewResolver 会根据逻辑View名称查找并解析实际的view视图文件,并根据DispaterServlet返回的Model数据模型传给view视图文件,进行渲染执行,产生响应结果。

  2. DispaterServlet负责将响应结果,输出至客户端浏览器。


29. SpringMVC的核心组件有哪些?
  • DispatcherServlet:核心处理器,负责统一接收请求、将请求分发至不同的控制器,并负责客户端响应。
  • HandlerMapping:处理器映射器,根据uri去匹配查找能处理的Handler,并会将请求涉及到的拦截器和Handler一起封装。
  • HandlerAdapter:处理器适配器,根据HandlerMapping找到的Handler,适配执行对应的Handler ;
  • Handler:请求处理器,处理实际请求的处理器。
  • ViewResolver:视图解析器,根据Handler返回的逻辑视图名称,解析并渲染真正的视图文件,并传递给DispatcherServlet响应至客户端
相关推荐
计算机程序员小杨4 分钟前
计算机专业的你懂的:大数据毕设就选贵州茅台股票分析系统准没错|计算机毕业设计|数据可视化|数据分析
java·大数据
y1y1z8 分钟前
EasyExcel篇
java·excel
DokiDoki之父27 分钟前
多线程—飞机大战排行榜功能(2.0版本)
android·java·开发语言
高山上有一只小老虎33 分钟前
走方格的方案数
java·算法
whatever who cares34 分钟前
Java 中表示数据集的常用集合类
java·开发语言
石小石Orz40 分钟前
效率提升一倍!谈谈我的高效开发工具链
前端·后端·trae
JavaArchJourney1 小时前
TreeMap 源码分析
java
孟永峰_Java1 小时前
凌晨线上崩盘:NoClassDefFoundError血案纪实!日志里这行「小字」才是救世主
后端·代码规范
whitepure1 小时前
万字详解Java中的IO及序列化
java·后端
还梦呦1 小时前
2025年09月计算机二级Java选择题每日一练——第一期
java·开发语言