文章目录

  • 1 Spring MVC 执行流程
  • 2 Spring 框架中用到的设计模式
  • 3 Spring 事务、隔离级别
  • 4 @SpringBootApplication 做了哪些事
  • 5 Spring Boot 自动装配原理
  • 6 Spring 容器:BeanFactory & ApplicationContext
  • 7 依赖注入的两种方式
  • 8 单例 Bean 是线程安全的吗
  • 9 AOP 通知的执行顺序
  • 10 依赖注入的四个注解

1 Spring MVC 执行流程

  1. 客户端(浏览器)发送请求,直接请求到 DispatcherServlet
  2. DispatcherServlet 根据请求信息调用 HandlerMapping,解析请求对应的 Handler
  3. 解析到对应的 Handler(也就是 Controller)后,开始由 HandlerAdapter 适配器处理。
  4. HandlerAdapter 会根据 Handler 来调用真正的处理器开处理请求,并处理相应的业务逻辑。
  5. 处理器处理完业务后,会返回一个 ModelAndView 对象,Model 是返回的数据对象,View 是逻辑上的视图。
  6. ViewResolver 会根据逻辑 View 查找实际的 View。
  7. DispaterServlet 进行视图渲染。
  8. 把 View 返回给请求者(浏览器)。

2 Spring 框架中用到的设计模式

参考:Spring 中的设计模式

  1. 工厂模式
    Spring 通过 BeanFactoryApplicationContext 创建 Bean 对象
  2. 单例模式
    Bean 默认都是单例的
  3. 代理模式
    AOP 功能的实现基于代理模式
  4. 模板模式
    xxxTemplate(例如 RestTemplate 等)使用了模板模式
  5. 适配器模式
    Spring AOP 的增强或通知(Advice,例如 @ControllerAdvice)使用到了适配器模式;Spring MVC 中用到了适配器模式适配 Controller

3 Spring 事务、隔离级别

  • 一般使用 @Transactional 注解方式实现,只能应用到 public 方法上,否则不生效
  • 事务传播:解决业务层方法之间互相调用的事务问题
传播行为 解释
PROPAGATION_REQUIRED @Transactional注解默认使用。如果当前存在事务,则加入该事务(变成了同一事务,只要一个方法回滚,整个事务均回滚);如果当前没有事务,则创建一个新的事务
PROPAGATION_REQUIRES_NEW 创建一个新的事务,如果当前存在事务,则把当前事务挂起。也就是说不管外部方法是否开启事务,会新开启自己的事务,且开启的事务相互独立,互不干扰
PROPAGATION_NESTED 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则等价于 PROPAGATION_REQUIRED
PROPAGATION_MANDATORY 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常
  • 隔离级别:类似于 MySQL
隔离级别 解释
ISOLATION_DEFAULT 默认的隔离级别,MySQL 默认采用的 REPEATABLE_READ 隔离级别,Oracle 默认采用的 READ_COMMITTED 隔离级别
ISOLATION_READ_UNCOMMITTED 允许读取尚未提交的数据变更,可能会导致 脏读、幻读或不可重复读
ISOLATION_READ_COMMITTED 允许读取并发事务已提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
ISOLATION_REPEATABLE_READ 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生
ISOLATION_SERIALIZABLE 所有事务依次执行,这样事务之间就不可能产生干扰,可以防止脏读、不可重复读以及幻读
  • @Transactional(rollbackFor = MyException.class) 注解
    如果类或者方法加了这个注解,那么这个类里面的方法抛出异常,就会回滚,数据库里面的数据也会回滚

    @Transactional 注解中如果不配置 rollbackFor 属性,那么事务只会在遇到 RuntimeException 的时候才会回滚,加上 rollbackFor=Exception.class ,可以让事务在遇到自定义的非运行时异常时也回滚


4 @SpringBootApplication 做了哪些事

@SpringBootApplication = @Configuration + @EnableAutoConfiguration + @ComponentScan

  • @EnableAutoConfiguration:启用 SpringBoot 的自动配置机制
  • @ComponentScan: 扫描被 @Component (@Service,@Controller) 注解的 bean,注解默认会扫描该类所在的包下所有的类
  • @Configuration:允许在 Spring 上下文中注册额外的 bean 或导入其他配置类

5 Spring Boot 自动装配原理

自动装配可以简单理解为:通过注解或者一些简单的配置就能在 Spring Boot 的帮助下实现某块功能

  1. @SpringBootApplication -> @EnableAutoConfiguration -> AutoConfigurationImportSelector
  2. AutoConfigurationImportSelector 实现了 ImportSelector 接口中的 selectImports 方法,该方法主要用于获取所有符合条件的类的全限定类名(返回 String 数组,一系列的 “xxxAutoConfiguration”),这些类需要被加载到 IoC 容器中
private static final String[] NO_IMPORTS = new String[0];public String[] selectImports(AnnotationMetadata annotationMetadata) {// <1>.判断自动装配开关是否打开if (!this.isEnabled(annotationMetadata)) {return NO_IMPORTS;} else {//<2>.获取所有需要装配的beanAutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);  // 下图详细说明return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}
}

下图中的红色字体“自动配置类名”即为 xxxAutoConfiguration 类

  1. 所有 Spring Boot Starter 下的 META-INF/spring.factories 都会被读取到。XXXAutoConfiguration 类的作用就是按需加载组件

  1. 启动应用时,不同的 Stater 的 spring.factories 的配置很多,每次启动不会全部加载。只有自动配置类或其中的方法上的 @ConditionalOnXXX 中的所有条件都满足才会生效

@Configuration
// 检查相关的类是否存在,存在才会加载
@ConditionalOnClass({EnableAspectJAutoProxy.class, Aspect.class, Advice.class, AnnotatedElement.class})
@ConditionalOnProperty(prefix = "spring.aop", name = {"auto"}, havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {// ...@Configuration@EnableAspectJAutoProxy(proxyTargetClass = true)@ConditionalOnProperty(prefix = "spring.aop", name = {"proxy-target-class"}, havingValue = "true", matchIfMissing = true)public static class CglibAutoProxyConfiguration {public CglibAutoProxyConfiguration() {}}// ...
}

6 Spring 容器:BeanFactory & ApplicationContext

  • BeanFactoryApplicationContext 是 Spring 的两大核心接口,都可以当做 Spring 的容器, ApplicationContextBeanFactory 的子接口

  • BeanFactroy 采用的是 延迟加载 形式来注入 Bean 的,即只有在使用到某个 Bean 时(调用getBean()),才对该 Bean 进行实例化

    • 这样导致不能发现一些存在的 Spring 的配置问题:如果Bean的某一个属性没有注入,BeanFacotry 加载后,直至第一次使用调用 getBean 方法才会抛出异常
    • 是一种低级的容器,类似于一个 HashMap,Key 是 BeanName,Value 是 Bean 实例,通常只提供注册(put),获取(get)这两个功能
  • ApplicationContext 在容器启动时,一次性创建了所有的 Bean(把创建资源的过程放在服务器启动时)。这样在容器启动时就可以发现 Spring 中存在的配置错误,这样有利于检查所依赖属性是否注入。 ApplicationContext 启动后预载入所有的单实例Bean,通过预载入单实例 Bean,确保当需要的时候就不用等待


7 依赖注入的两种方式

  1. 使用 setter 方法
    - 容器通过调用无参构造器或无参static工厂方法实例化 Bean 之后,调用该 Bean 的 setter 方法
    - 用于实现可选依赖,适合设置少量属性

  2. 使用有参构造器
    - 构造器依赖注入通过容器触发一个类的构造器来实现的
    - 用于实现强制依赖,适合设置大量属性


8 单例 Bean 是线程安全的吗

  • 不是,Spring 框架并没有对单例 Bean 进行多线程的封装处理
  • 大部分时候 Bean 是无状态的(比如 dao ,无状态即不会保存数据),所以大部分 Bean 是线程安全的
  • 如果 Bean 有状态的话,需要开发者保证线程安全,最简单的就是改变 Bean 的作用域,把 singleton 变更为 prototype ,这样请求 Bean 相当于 new Bean(),就可以保证线程安全了

9 AOP 通知的执行顺序

@Component(value = "enhanceClass")
@Aspect
public class EnhanceClass {@Before(value = "execution(* pojo.MyClass.add(..))")public void before() {System.out.println("前置通知");}@AfterReturning(value = "execution(* pojo.MyClass.add(..))")public void afterReturning() {System.out.println("后置通知,正常返回时才执行");}@After(value = "execution(* pojo.MyClass.add(..))")public void after() {System.out.println("最终通知,无论是否正常返回都执行");}@AfterThrowing(value = "execution(* pojo.MyClass.add(..))")public void afterThrowing() {System.out.println("异常通知");}@Around(value = "execution(* pojo.MyClass.add(..))")public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println("环绕通知:前");proceedingJoinPoint.proceed();System.out.println("环绕通知:后");}
}- 无异常时:
1. around before advice
2. before advice
3. target method
4. around after advice
5. after advice
6. afterReturning advice- 有异常时:
1. around before advice
2. before advice
3. target method 执行
4. around after advice
5. after advice
6. afterThrowing advice
7. 异常发生

10 依赖注入的四个注解

注解 作用 范围
@Autowired 按类型自动装配 构造方法、成员变量、Setter 方法
@Qualifier 按名称自动装配,需要和 @Autowired 搭配使用 成员变量、Setter 方法
@Resource 按名称或类型自动装配;未指定规则时,默认先按名称装配,找不到满足要求的 bean,再按类型装配 成员变量、Setter 方法
@Value 注入 int / float / String 等基本数据类型 成员变量、Setter 方法

Spring框架相关问题相关推荐

  1. Spring框架入门

    目录 Spring框架概述 1.Spring框架组成 2.使用spring有什么好处 3.为什么使用spring框架 4.Spring快速入门 4.1Spring IoC底层实现原理 4.2下载Spr ...

  2. Spring框架快速入门

    目录 什么是Spring? 为什么学习Spring? Spring的快速入门 Spring的版本 IOC概述 什么是IOC? Spring的IoC入门 下载Spring的开发包 创建web项目,引入S ...

  3. Spring入门第一讲——Spring框架的快速入门

    Spring的概述 什么是Spring? 我们可以从度娘上看到这样有关Spring的介绍: 说得更加详细一点,Spring是一个开源框架,Spring是于2003年兴起的一个轻量级的Java开发框架, ...

  4. 手写简易版Spring框架(七):定义标记类型接口Aware,实现感知容器相关的信息

    文末有惊喜 目标 目前已实现的 Spring 框架,在 Bean 操作上能提供出的能力,包括:Bean 对象的定义和注册,以及在操作 Bean 对象过程中执行的,BeanFactoryPostProc ...

  5. Spring框架系列之AOP思想

    微信公众号:compassblog 欢迎关注.转发,互相学习,共同进步! 有任何问题,请后台留言联系! 1.AOP概述 (1).什么是 AOP AOP 为 Aspect Oriented Progra ...

  6. spring 全局变量_[Spring]-Spring框架-02-IOC容器

    Spring框架 IOC容器 理解IOC容器和DI依赖注入 IOC容器 Inverser Of Control反转控制 就是把原来在程序中创建HelloService对象的控制权限交给Spring管理 ...

  7. 阿里三面让我现场改造Spring框架,明天带他去爬山!

    作为一个Java程序员,提到开源框架,Spring无疑是绕不过去的门槛,相信大家对它都不陌生,或多或少都用过. 但是如果谈到改造Spring框架,实现它的自定义扩展,以及大厂面试必问的源码,很多人就会 ...

  8. spring学习12 -Spring 框架模块以及面试常见问题注解等

    以下为spring常见面试问题: 1.Spring 框架中都用到了哪些设计模式? Spring框架中使用到了大量的设计模式,下面列举了比较有代表性的: 代理模式-在AOP和remoting中被用的比较 ...

  9. Spring 系列: Spring 框架简介

    Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的.框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架. 在这篇由三部 ...

最新文章

  1. 困扰人工智能50多年的常识问题,是否迎来“破局”?
  2. 【控制】《鲁棒控制-线性矩阵不等式处理方法》-俞立老师-第1章-引言
  3. 开启php,php开启openssl的方法
  4. python与rpc服务
  5. windows下快速启动或关闭系统服务方法
  6. 世界上最欢乐的职业,可能就是蹦极的工作人员了!
  7. linux延时与定时操作
  8. Windows/Android/IOS平台如何在Unity3d播放RTSP/RTMP流
  9. [Thinking]从赢在中国,思考博客园的商业化
  10. java简单ai聊天_一个hello/hi的简单的网络聊天程序——JAVA
  11. 划分子网后的三级结构
  12. python新式类c3算法_python中的MRO和C3算法
  13. IoT:加密与安全:几种常用安全加密算法原理与用途解析
  14. Android JSON 数据解析 之原生 API
  15. 多核时代不宜再用 x86 的 RDTSC 指令测试指令周期和时间
  16. python 扫描枪_获取键盘输入或者USB扫描枪数据
  17. 部落战魂找不到服务器,部落战魂官方版
  18. 【ECLIPSE 二】eclipse java web 版本修改问题 3.0-2.5
  19. 《风暴英雄》游戏体验
  20. 操作系统实验一到实验九合集(哈工大李治军)

热门文章

  1. Asp.net 面向接口可扩展框架之核心容器
  2. byte java byte_详解java中的byte类型
  3. Failed:(13: Permission denied)导致访问浏览器出现Nginx 500 Internal Server Error
  4. C语言试题四十八之该函数可以统计一个长度为2的字符串在另一个字符串中出现的次数。
  5. 「零门槛多语言 Python/C/C# 通用思想学习系列」第一篇:经典HelloWorld
  6. 世界上最震撼的地质景观,你认识多少?
  7. 高糊马赛克秒变高清,表情帝:这还是我吗?
  8. 人体的血管连起来竟能绕地球两圈!?| 今日最佳
  9. 教师节,老师们最大的愿望竟然是。。 | 今日最佳
  10. 豆瓣最高评分8.9!让你拥有“多样性思维”