Spring框架知识点汇总

01.Spring框架的基本理解

关键字:核心思想IOC/AOP,作用(解耦,简化),简单描述框架组成;

Spring框架是一款轻量级的开发框架,核心思想是IOC(反转控制)和AOP(面向切面编程),为Java应用程序开发提供组件管理服,用于组件之间的解耦,以及简化第三方JavaEE中间件技术的使用(JMS,任务调度,缓存,ORM框架),是一个基础架构型的开发框架;

Spring框架包括:IOC容器,Validation数据校验,AOP面向切面编程,Transactions事务管理,Spring JDBC,Spring MVC框架,以及第三方JavaEE中间件技术集成;

02.Spring框架由哪些模块组成

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

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

1、Core:核心模块

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

2、Testing:测试模块

包括:Mork Objects(测试模拟对象),TestContext Framework(测试框架),Spring MVC Test(用于测试Spring MVC),WebTestClient(用于测试WebClient,Restful,Webflux等);

3、Data Access:数据访问模块

包括: Transactions (事务管理),DAO Support(统一的 Data Access object DA0模式封装),JDBC(Spring 对于 JDBC 的操封装),0/R Mapping (Spring 对于对象关系映射框架的封装,例如 Hibernate 等框架)等;

4、Web Servlet:基于Servlet的Web应用开发

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

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

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

03.SpringIOC的理解

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

Ioc(Inversion of control,中文释义: 控制反转)是 Spring 架的核心思想之,主要用于解耦。 IOC 是指将创建对象的控制权转移给 pring 框架进行管理。由 Spring框架根据配置文件或注解等方式,创建 bean 对象并管理各个bean 对象之间的依赖关系。使对象之间形成松散耦合的关系,实现解耦;

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

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

04.Spring IOC容器的理解

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

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

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

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

05.Spring DI的理解

关键字:名词解释 是一种通过容器自动将依赖对象注入到目标对象中的机制

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

06.什么是Spring的bean

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

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

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

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

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

@Service :定义业务层Bean的注解;

@Controller:定义控制器Bean的注解;

08.@Component和@Bean的区别是什么

@Component 注解作用于类,而 @Bean 注解作用于方法;

@Component 通常是通过类路径扫描来实现自动扫描并完成装配 Bean 到 Spring IOC 容器中;

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

09.@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有什么区别

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

两者区别与不同:

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

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

Bean的创建加载方式:

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

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

13.Spring框架启动流程

首先,初始化 Spring 容器,注册内置的 BeanPostProcessor 的 BeanDefinition 到容器中;

实例化 BeanFactory[ DefaultListableBeanFactory ]工厂,用于生成 Bean对象;

实例化 BeanDefinitionReader ,用于读取 Spring 配置文件或注解,将配置文件中Spring 需要 管理的组件类,转化成 BeanDefinition 对象,( BeanDefinit中极甘重要的个艇今对免的所有特 征信自夜佬aN例如: Bean的ID,是否单例,是否懒加载等);

实例化ClassPathBeanDefinitionScanner路径扫描器,用于对指定的包目录进行扫描查找bean 对象;

将配置类的BeanDefinition注册到容器中;

调用refresh0方法刷新容器;

prepareRefresh()刷新前的预处理;

obtainFreshBeanFactory():获取在容器初始化时创建的BeanFactory;

prepareBeanFactory(beanFactory): BeanFactory的预处理工作,向容器中添加一些组件

postProcessBeanFactory(beanFactory): 子类重写该方法,可以实现在BeanFactory创建并预 处理完成以后做进一步的设置;

invokeBeanFactoryPostProcessors(beanFactory): 在BeanFactory标准初始化之后执行 BeanFactoryPostProcessor的方法,即BeanFactory的后置处理器:

registerBeanPostProcessors(beanFactory): 向容器中注册Bean的后置处理器 BeanPostProcessor,它的主要作用是干预Spring初始化bean的流程,从而完成代理自动注入、循环依赖等功能

initMessageSource(): 初始化MessageSource组件,主要用于做国际化功能,消息绑定与消息 解析:

initApplicationEventMulticaster(): 初始化事件派发器,在注册监听器时会用到:

onRefresh(): 留给子容器、子类重写这个方法,在容器刷新的时候可以自定义逻辑;

registerListeners(): 注册监听器: 将容器中所有的ApplicationListener注册到事件派发器中,并 派发之前步骤产生的事件;

finishBeanFactorylnitialization(beanFactory): 初始化所有剩下的单实例bean,核心方法是prelnstantiateSingletons(),会调用getBean0方法创建对象;

finishRefresh():发布BeanFactory容器刷新完成事件。

14.Spring框架中的Bean的作用域

singleton:Spring只会为该bean对象创建唯一实例,Spring中的bean默认都是单例;

prototype:每次获取bean,Spring会创建一个新的bean实例;

request:每一次HTTP请求,Spring会创建一个新的bean实例;

session:不同的HTTP会话,Spring会创建不同的bean对象。

15.Spring框架中的Ben的线程安全

对于prototype作用域的Bean,每次都会创建一个新的对象,也就是线程之间不存在Bean共享,因此不会有线程安全问题;

对于 singleton 作用域的 Bean,所有的线程都共享一个单例状态的 Bean,存在资源竞争,因此是存在线程安全问题;

对于 singleton 作用域的单例 bean ,它的线程安全问题,常见有两种解决办法:

1、在bean 中尽量避免定义可变的成员变量(用于保存数据的成员变量);

2、在类中定义一个ThreadLocal成员变量,将需要可变的成员变量保存在ThreadLocal中。

16.Spring框架中的Bean生命周期

Spring的生命周期总体分为四个阶段:实例化=>属性注入=>初始化=>销毁

Step1 实例化 Bean: 根据配置文件中 Bean 的定义,利用 Java Reflection 反射技术创建Bean的实例;

1、加载xml配置文件,解析获取配置中的每个的信息,封装成一个个的BeanDefifinition对象;

2、将BeanDefifinition存储在一个名为beanDefifinitionMap的Map<String,BeanDefifinition>中;

3、ApplicationContext底层遍历beanDefifinitionMap,创建Bean实例对象;

4、创建好的Bean实例对象,被存储到一个名为singletonObjects的Map<String,Object>中;

5、当执行applicationContext.getBean(beanName)时,从singletonObjects去匹配Bean实例返回

Step2 注入对象依赖的属性值 (或对象)

Spring在进行属性注入时,会分为如下几种情况:

1、注入普通属性,String、int或存储基本类型的集合时,直接通过set方法的反射设置进去;

2、注入单向对象引用属性时,从容器中getBean获取后通过set方法反射设置进去,如果容器中没有,则先创建被注入对象Bean实例(完成整个生命周期)后,在进行注入操作;

3、注入双向对象引用属性时,就比较复杂了,涉及了循环引用(循环依赖),使用三级缓存解决;

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(Object 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类,这样就形成了循环依赖问题。

多个实体之间相互依赖并形成闭环的情况就叫做"循环依赖",也叫做"循环引用

Spring提供了三级缓存存储 完整Bean实例和半成品Bean实例,用于解决循环依赖问题。

在DefaultListableBeanFactory的上四级父类DefaultSingletonBeanRegistry中提供如下三个Map:

public class DefaultSingletonBeanRegistry ... {
//1、最终存储单例Bean成品的容器,即实例化和初始化都完成的Bean,称之为"一级缓存"
Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
//2、早期Bean单例池,缓存半成品对象,且当前对象已经被其他对象引用了,称之为"二级缓存"
Map<String, Object> earlySingletonObjects = new ConcurrentHashMap(16);
//3、单例Bean的工厂池,缓存半成品对象,对象未被引用,使用时在通过工厂创建Bean,称之为"三级缓存"
Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
}
注:将对象保存至三级缓存的时候,会包装成ObjectFactory对象录入,未来通过此接口对应的get方法再次提取对象

18.Spring框架中有哪些注解

用于声明Bean的注解:

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

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

@Service :定义业务层Bean的注解;

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

用于注入的注解:

@Autowired:按类型自动注入;

@Qualifier: 按名称自动注入;

声明配置、扫描、启用特性的注解:

@Configuration : 声明配置类;

@ComponentScan :组件扫描;

@EnableScheduling : 启用任务调度;

@EnableAspectJAutoProxy : 启用自动代理工厂

19.Spring框架中用到的设计模式

工厂模式:Spring 使用工厂模式,通过 BeanFactory 或ApplicationContext 来创建对象;

单例模式:Bean 默认作用域为单例,按照单例设计模式进行设计实现;

策略模式:Resource的实现类,针对不同的资源文件,实现了不同方式的资源获取策略;

代理模式:Spring的AOP的实现依靠动态代理(JDK的反射和CGLIB);

模板方法:Spring 提供了 JdbcTemplate,RedisTemplate 等模板对象,将相同的操作步骤进行了封装;

适配器模式:Spring AOP 的增强或通知 ( Advice )使用到了适配器模式, Spring MVC中也用到了适配器模式适配 Controller;

20.Spring框架中AOP的基本理解

AOP (Aspect-0riented 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 已经集成了 AspectJ,AspectJ是一个 Java 技术生态系统中实现AOP编程思想的独立框架; AspectJ相比于 Spring AOP 能更加强大,但是 Spring AOP相对来说更简单更容易;

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

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

如果项目中的切面代码比较少,两者性能差异不大。如果切面代码太多的话,最好选择AspectJ,因为基于字节码操作的缘故,AspectJ比 Spring AOP 从性能上要快很多。

22.Spring AOP有哪些通知类型

前置通知:实现 MethodBeforeAdvice 接口,在目标方法调用前,执行通知;

环绕通知:实现 MethodInterceptor 接口,是一个包围目标方法的通知。环绕通知可以在方法调用先后完成定义的行为;

后置通知:实现AfterReturningAdvice 接口,在在目标方法调用后,执行通知(如果方法抛出异常,则不执行通知) ;

异常通知:实现 ThrowsAdvice 接口,在方法抛出异常时,执行通知;

返回通知

23.Spring管理事务的方式有几种

编程式事务: 在代码中硬编码 (不推荐使用) :通过 TransactionTemplate 或者 TransactionManager手动管理事务,实际应用中很少使用,用于理解 Spring 事务管理;

声明式事务 : 在 XML配置文件或者基于注解 @Transactional(推荐使用),通过AOP实现。

24.Spring事务中有哪几种事务传播行为

事务传播行为是为了解决业务层方法之间互相调用时,产生事务问题。

当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如: 方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。

事务传播行为有如下分类:

1、TransactionDefinition.PROPAGATION REQUIRED

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

2、TransactionDefinition.PROPAGATION REQUIRESNEW

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

3、TransactionDefinition.PROPAGATION NESTED

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

4、TransactionDefinition.PROPAGATION MANDATORY

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

5、TransactionDefinition.PROPAGATION SUPPORTS

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

6、TransactionDefinition.PROPAGATION NOT SUPPORTED

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

7、TransactionDefinition.PROPAGATION NEVER

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

25.Spring事务中有哪几种事务隔离级别

1、TransactionDefinition.ISOLATION_DEFAULT 默认隔离级别

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

2、TransactionDefinition.ISOLATION READ UNCOMMITTED 读未提交

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

3、TransactionDefinition.ISOLATION READ_COMMITTED 读已提交

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

4、TransactionDefinition.ISOLATION REPEATABLE READ可重复读

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

5、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中失效。

3、方法没有被public修饰

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

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

4、同一类中方法调用

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

5、未配置事务管理器

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

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

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

7、不正确的异常捕获

不正确的捕获异常也会导致 Spring 的事务失效。

8、错误的标注异常类型

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

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

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

此时可以手动指定updateProductstockCountById()方法标注的事务异常类型。

27.谈谈对Spring MVC的理解

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

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

28.Spring MVC的工作原理(执行流程)

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

2、DispatcherServlet根据请求信息调用 HandlerMapping 。HandlerMapping根据uri去匹配查找能处理的Handler(也就是我们定义的 Controller 控制器) ,并会将请求涉及到的拦截器和 Handler 一起封装;

3、DispatcherServlet 调用 HandlerAdapter 适配执行 Handler 。

4、Handler 完成对用户请求的处理后,会返一个 ModelAndView 模型视图对象给 DispatcherServlet 。 ModelAndview 中包含了数据模型以及相应的视图信息。 Model 是返回的数据对象,View 是 View 视图的逻辑名称。

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

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

29.SpringMVC的核心组件有哪些

1、DispatcherServlet : 核心处理器,负责统一接收请求将请求分发至不同的控制器,并负责客户端响应;

2、HandlerMapping : 处理器映射器,根据 uri 去配查找能处理的 Handler ,并会将请求涉及到的拦截器和 Handler 一起封装。

3、HandlerAdapter : 处理器适配器,根据 HandlerMapping 找到的 Handler ,适配执行对应的 Handler;

4、Handler : 请求处理器,处理实际请求的处理器。

5、ViewResolver : 视图解析器,根据 Handler 返回的逻辑视图名称,解析并染真正的视图文件,并传递给 DispatcherServlet 响应至客户端

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/114665.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu 20.04.5 怎么安装微信

这是我的ubutun版本号 在这个系统装桌面版微信很多功能不健全。搜索了很多方法&#xff0c;这个算是不错的一个法子。 1.添加仓库 首次使用时&#xff0c;你需要运行如下一条命令将移植仓库添加到系统中。 wget -O- https://deepin-wine.i-m.dev/setup.sh | sh 2.应用安装 …

【01】弄懂共识机制PoW

基于工作量证明机制的共识机制PoW&#xff08;Proof of Work&#xff09; 特点就是多劳多特 共识过程 一个区块链系统中&#xff0c;交易历经多个步骤才能得以上链&#xff0c;并且需要经过多个节点的验证。以下是这些步骤的详细叙述&#xff1a; 交易进入交易池&#xff08;内…

MyBatis与spring集成

目录 MyBatis与Spring集成 导入pom依赖 导入generatorConfig.xml 导入spring-mybatis.xml 自动生成mapper文件 编写接口类&#xff1a;BookBiz aop整合PageHelper分页插件 编写分页查询 编写pagebean 编写PagerAspect类 测试结果 MyBatis与Spring集成 导入pom依赖 &l…

通过这 5 项 ChatGPT 创新增强您的见解

为什么绝大多数的人还不会使用chatGPT来提高工作效能&#xff1f;根本原因就在还不会循序渐进的发问与chatGPT互动。本文总结了5个独特的chatGPT提示&#xff0c;可以帮助您更好地与Chat GPT进行交流&#xff0c;以获得更清晰的信息、额外的信息和见解。 澄清假设和限制 用5种提…

面试必备:揭秘ArrayList和LinkedList,区别、优缺点与使用场景

大家好&#xff0c;我是你们的小米&#xff01;今天我要跟大家聊一个在面试中经常被问到的热门话题——ArrayList和LinkedList的区别、优缺点以及它们的使用场景。作为程序员&#xff0c;掌握这些知识点不仅可以在面试中脱颖而出&#xff0c;还能帮助我们更好地在项目中选择合适…

IntelliJ IDEA 2023.2.1使用Git时弹出“使用访问令牌登录”问题解决

文章目录 一、内网Git环境GitLabGogsGitea 二、外网Git环境GitHubGitee 升级为IntelliJ IDEA 2023.2.1后&#xff0c;使用Git时弹出“使用访问令牌登录”的窗口&#xff0c;习惯使用Git帐号密码登录的用户&#xff0c;面对这个突如其来的弹窗真的很懵。 一、内网Git环境 GitLa…

Android 中SettingsActivity(PreferenceFragmentCompat)的简单使用

如果你需要一个简单的APP设置&#xff0c;可以使用sharedPreferences进行存储&#xff0c;我们可以借助AndroidStudio快速创建一个用于设置的Activity&#xff0c;其实它是继承PreferenceFragmentCompat&#xff0c;存储方式用的就是sharedPreferences&#xff0c;只是帮我们节…

Springboot 接口方式硬通知实现ConfigurationProperties 、@Value 动态刷新

前言 看到这个文章标题&#xff0c;也许有的看官就觉得很多余&#xff0c; 因为Nacos 可以设置 NacosValue(value "${XXX}",autoRefreshed true) 实现动态刷新&#xff1b; 又因为cloud config的RefreshScope 实现动态刷新&#xff1b; 还有阿波罗...等 这…

[ros][ubuntu]ros在ubuntu18.04上工作空间创建和发布一个话题

构建catkin工作空间 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src catkin_init_workspace cd ~/catkin_ws/ catkin_make 配置环境变量 echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc source ~/.bashrc 检查环境变量 echo $ROS_PACKAGE_PATH…

详解I2C

I2C&#xff08;也常写作 I I C IIC IIC&#xff0c; I 2 C I^2C I2C&#xff09;&#xff0c;全称为Inter-Integrated Circuit&#xff08;“互连集成电路”&#xff09;&#xff0c;用于在集成电路之间进行短距离数据传输。它由Philips&#xff08;现在的NXP半导体&#xff0…

Python爬虫基础之正则表达式

目录 一、什么是正则表达式&#xff1f; 二、re.compile()编译函数 三、group()获取匹配结果函数 四、常用匹配规则 4.1匹配单个字符 4.2匹配前字符次数 4.3匹配原生字符串 4.4匹配字符串开头和结尾 4.5分组匹配 五、re.match()开头匹配函数 六、re.search()全文搜索…

恒流电路的三种设计方案

作为硬件研发工程师相信对恒流电路不会陌生&#xff0c;本文介绍下三种恒流电路的原理图。 三极管恒流电路 三极管恒流电路 三极管的恒流电路&#xff0c;主要是利用Q2三极管的基级导通电压为0.6~0.7V这个特性&#xff1b;当Q2三极管导通&#xff0c;Q1三极管基级电压被拉低而…

lnmp架构-mysql2

4.mysql 组复制集群 首先对所有的节点重新初始化 因为对节点的数据一致性要求非常高 主从复制的时候 slave只会复制master的binlog日志 就是二进制日志 不会复制relay_log 在server1上 根据实际情况修改主机名和网段 log_slave_updateON 意思就是 当slave的sql线程做完之后…

【Unity-Cinemachine相机】虚拟相机(Virtual Camera)的本质与基本属性

我们可以在游戏进行时修改各个属性&#xff0c;但在概念上&#xff0c;最好将Virtual Camera 当作一种相机行为的“配置文件”&#xff0c;而不是一个组件。 我们的相机有几种行为就为它准备几种虚拟相机&#xff0c;比如角色移动就为它第三人称相机&#xff0c;瞄准就准备一个…

Ubuntu搭建web站点并发布公网访问【内网穿透】

文章目录 前言1. 本地环境服务搭建2. 局域网测试访问3. 内网穿透3.1 ubuntu本地安装cpolar3.2 创建隧道3.3 测试公网访问 4. 配置固定二级子域名4.1 保留一个二级子域名4.2 配置二级子域名4.3 测试访问公网固定二级子域名 前言 网&#xff1a;我们通常说的是互联网&#xff1b…

Java设计模式:四、行为型模式-06:观察者模式

文章目录 一、定义&#xff1a;观察者模式二、模拟场景&#xff1a;观察者模式2.1 观察者模式2.2 引入依赖2.3 工程结构2.4 模拟摇号2.4.1 摇号服务接口2.4.2 摇号返回结果类 三、违背方案&#xff1a;观察者模式3.0 引入依赖3.1 工程结构3.2 添加摇号接口和实现3.2.1 摇号服务…

【锁】定时任务推送数据-redission加锁实例优化

文章目录 redission 加锁代码-有问题优化代码看门狗是什么&#xff1f; redission 加锁代码-有问题 /*** 收货入库物料标签(包装码)推送接口** throws Exception*/public void synReceiveMaterialTags() throws Exception {String tag DateFormatUtils.format(new Date(), &qu…

昨天面试的时候被提问到的问题集合(答案)

1、vue的双向绑定原理是什么&#xff1f;里面的关键点在哪里&#xff1f; Vue的双向绑定原理是基于Object.defineProperty或者Proxy来实现的&#xff0c;其关键点在于数据劫持&#xff0c;即对数据的读取和修改进行拦截&#xff0c;在数据发生变化时自动更新视图 2、实现水平垂…

frida动态调试入门01——定位关键代码

说明 frida是一款Python工具可以方便对内存进行hook修改代码逻辑在移动端安全和逆向过程中常用到。 实战 嘟嘟牛登录页面hook 使用到的工具 1&#xff0c;jadx-gui 2&#xff0c;frida 定位关键代码 使用jadx-gui 进行模糊搜索&#xff0c;例如搜索encyrpt之类的加密关键…

深入解析即时通讯App开发中的关键技术

即时通讯App开发在现代社交和通信领域中扮演着重要的角色。随着移动设备的普及和网络的高速发展&#xff0c;人们对即时通讯工具的需求不断增加。本篇文章将深入探讨即时通讯App开发中的关键技术&#xff0c;帮助读者了解该领域的最新动态和技术趋势。 基础架构和通信协议 现…