Spring IOC、DI、AOP以及Spring MVC面试原理(1)

简介: Spring IOC、DI、AOP以及Spring MVC面试原理(1)

Spring IOC加载流程:

初始化ApplicationContext;ApplicationContext实现类中完成的

通过BeanDefinitionReader加载配置文件,并封装成BeadDefinition

将BeanDefinition包装成BeanWrapper

将BeanWrapper保存至IOC容器中


(1)读取配置文件:通过ResourceLoader的getResource方法将类路径,URL,文件系统等方式读为Resource

(2)解析配置文件:解析是在BeanDefinitionReader中完成的,最常用的类是XMLBeanDefinitionReader来完成的,解析涉及到很多步骤,最常见的是将XML文件读取成Document文档,DefaultBeanDefinitionDocumentReader对Document对象进一步解析,DefaultBeanDefinitionDocumentReader又委托给BeanDefinitionParserDelegate进行解析,如果是标准的XML Namespace元素,则会委托合适的NameSpaceHandler进行解析最终解析的结果封装为BeanDefinitionHolder至此解析完成。

(3)Bean的注册:bean的注册是在BeanFactory里完成的,BeanFactory最常见的一个实现类是DefaultListableBeanFactory,,它实现了BeanDefinitionRegistry接口,所以其中的registerBeanDefinition()方法,可以对BeanDefinition进行注册这里附带一提,最常见的XmlWebApplicationContext不是自己持有BeanDefinition的,它继承自AbstractRefreshableApplicationContext,其持有一个DefaultListableBeanFactory的字段,就是用它来保存BeanDefinition所谓的注册,其实就是将BeanDefinition的name和实例,保存到一个Map中。刚才说到,最常用的实现DefaultListableBeanFactory,其中的字段就是beanDefinitionMap,是一个ConcurrentHashMap。

(4)实例化:注册也完成之后,在BeanFactory的getBean()方法之中,会完成初始化,也就是依赖注入的过程


Spring DI加载流程:

Spring DI的基本流程:

(1)循环读取BeanDefinition的缓存信息

(2)调用getBean方法创建对象实例

(3)将创建好的对象实例包装BeanWrapper对象

(4)将BeanWrapper对象缓存到IOC容器

(5)循环IOC容器执行注入


实例化策略根据配置实现不同的策略,将其封装为BeanWrapper

SimpleInstantiationStrategy

实例化有两种情况?

目标类配置了AOP,实例化对象代理类

目标类没有配置AOP,实例化原生对象


为什么要使用BeanWrapper?

统一一个对外访问对象的入口

扩展一些功能,缓存一些配置信息


DI原理:

**FactoryBean.getBeans()**触发依赖注入

createBeanInstance->用反射创建了对象实例->封装成BeanWrapper();

populateBean()–>根据beanName、BeanDefinition、BeanWrapper找到需要赋值的属性,把需要


赋值的属性封装为一个集合,集合的元素是PropertyValue,PropertyValue保存了需要赋值的Bean,赋值需要调用的方法,要赋什么值。


applyPropertyValues() 循环PropertyValue,挨个调用BeanWrapper的setValue()方法,用反射代用setter方法完成赋值。


DI是依赖注入,当IOC容器完成初始化后,针对非懒加载的Bean进行依赖注入或者当第一次getBean时


1)实例化 通过反射机制实例化Bean


2)依赖注入 判断其field是否有需要被注入的属性,如果有则进行注入该依赖的Bean属性


3) 循环依赖的问题,可以通过多级缓存来解决,二级缓存,三级缓存


Spring循环依赖三级缓存是否可以去掉第三级缓存?


image.png


BeanFactory是ApplicationContext的父类


BeanFactory与FactoryBean的区别:

BeanFactory是管理Bean的工厂

FactoryBean是创建对象的工厂Bean


Spring AOP面向切片编程:

基本概念:

(1)切面(Aspect)

 切面是一个横切关注点的模块化,一个切面能够包含同一个类型的不同增强方法,比如说事务处理和日志处理可以理解为两个切面。切面由切入点和通知组成,它既包含了横切逻辑的定义,也包括了切入点的定义。 Spring AOP就是负责实施切面的框架,它将切面所定义的横切逻辑织入到切面所指定的连接点中。


(2) 目标对象(Target)

 目标对象指将要被增强的对象,即包含主业务逻辑的类对象。或者说是被一个或者多个切面所通知的对象。


(3) 连接点(JoinPoint)

 程序执行过程中明确的点,如方法的调用或特定的异常被抛出。连接点由两个信息确定:


方法(表示程序执行点,即在哪个目标方法)

相对点(表示方位,即目标方法的什么位置,比如调用前,后等)

 简单来说,连接点就是被拦截到的程序执行点,因为Spring只支持方法类型的连接点,所以在Spring中连接点就是被拦截到的方法。

(4) 切入点(PointCut)

 切入点是对连接点进行拦截的条件定义。切入点表达式如何和连接点匹配是AOP的核心,Spring缺省使用AspectJ切入点语法。

 一般认为,所有的方法都可以认为是连接点,但是我们并不希望在所有的方法上都添加通知,而切入点的作用就是提供一组规则(使用 AspectJ pointcut expression language 来描述) 来匹配连接点,给满足规则的连接点添加通知。


(5) 通知(Advice)

 通知是指拦截到连接点之后要执行的代码,包括了“around”、“before”和“after”等不同类型的通知。Spring AOP框架以拦截器来实现通知模型,并维护一个以连接点为中心的拦截器链。


前置通知(Before)指某连接点之前执行的通知,但这个通知不能阻止连接点之前的代码的执行。

后置通知(After)指当某连接点退出时执行的通知(无论是正常返回还是异常退出)

返回后通知(After Return Advice)是某个连接点正常完成通知后执行的通知,不包括抛出异常的情况。

环绕通知(Around Advice)围绕在连接点前后,比如一个方法调用前后

异常通知(After Throwing Advice)是在方法抛出异常导致退出时执行的通知。

(6) 织入(Weaving)

 织入是将切面和业务逻辑对象连接起来, 并创建通知代理的过程。织入可以在编译时,类加载时和运行时完成。在编译时进行织入就是静态代理,而在运行时进行织入则是动态代理。


(7) 增强器(Adviser)

 Advisor是切面的另外一种实现,能够将通知以更为复杂的方式织入到目标对象中,是将通知包装为更复杂切面的装配器。Advisor由切入点和Advice组成。

 Advisor这个概念来自于Spring对AOP的支撑,在AspectJ中是没有等价的概念的。Advisor就像是一个小的自包含的切面,这个切面只有一个通知。切面自身通过一个Bean表示,并且必须实现一个默认接口。

 简单来讲,整个 aspect 可以描述为: 满足 pointcut 规则的 joinpoint 会被添加相应的 advice 操作。


两个步骤

AOP的入口:AOP的入口是由接入BeanPostProcessor后置处理器开始的,在bean初始化后提供回调入口,在AbstractAutowireCapableBeanFactory中initializeBean()方法中添加BeanPostProcessor后置处理器。


创建代理类:1,PostProcessAfterInitialization()方法中调用了wrapIfNecessary(),如果代理类实现了接口,使用JDK动态代理,如果没有实现接口,使用cglib动态代理。


代码织入:1,在JDK动态代理类中,如果动态代理类会实现InvokeHandler接口重写invoke方法,在Invoke方法中会通过getInterceptorsAndDynamicInterceptionAdvice方法从提供的配置实例config中获取Advisor列表,遍历处理这个Advisor切面,如果是PointCutAdvisor,则判断此Advisor能否应用到目标方法Method上,将满足条件的Advisor通过AdvisorAdapter转化为MethodInterceptor拦截器列表返回。接下来在Invoke中判断拦截器是否为空,如果为空,则直接调用Method.Invoke反射方法,如果拦截器列表不为空,则调用ReflectiveMethodInvocation.proceed()方法触发执行链的执行,Proceed()串其了整个Interceptor调用链。


image.png


两个重要的类:intercept 拦截器,责任链组件 invoke()

invocation 调用器,嗲用通知回调的组件,procceed()


目录
相关文章
|
8月前
|
XML Java 测试技术
《深入理解Spring》:IoC容器核心原理与实战
Spring IoC通过控制反转与依赖注入实现对象间的解耦,由容器统一管理Bean的生命周期与依赖关系。支持XML、注解和Java配置三种方式,结合作用域、条件化配置与循环依赖处理等机制,提升应用的可维护性与可测试性,是现代Java开发的核心基石。
|
8月前
|
前端开发 Java 微服务
《深入理解Spring》:Spring、Spring MVC与Spring Boot的深度解析
Spring Framework是Java生态的基石,提供IoC、AOP等核心功能;Spring MVC基于其构建,实现Web层MVC架构;Spring Boot则通过自动配置和内嵌服务器,极大简化了开发与部署。三者层层演进,Spring Boot并非替代,而是对前者的高效封装与增强,适用于微服务与快速开发,而深入理解Spring Framework有助于更好驾驭整体技术栈。
|
12月前
|
XML 人工智能 Java
Spring IOC 到底是什么?
IOC(控制反转)是一种设计思想,主要用于解耦代码,简化依赖管理。其核心是将对象的创建和管理交给容器处理,而非由程序直接硬编码实现。通过IOC,开发者无需手动new对象,而是由框架负责实例化、装配和管理依赖对象。常见应用如Spring框架中的BeanFactory和ApplicationContext,它们实现了依赖注入和动态管理功能,提升了代码的灵活性与可维护性。
288 1
|
11月前
|
前端开发 Java API
Spring Cloud Gateway Server Web MVC报错“Unsupported transfer encoding: chunked”解决
本文解析了Spring Cloud Gateway中出现“Unsupported transfer encoding: chunked”错误的原因,指出该问题源于Feign依赖的HTTP客户端与服务端的`chunked`传输编码不兼容,并提供了具体的解决方案。通过规范Feign客户端接口的返回类型,可有效避免该异常,提升系统兼容性与稳定性。
782 0
|
11月前
|
SQL Java 数据库连接
Spring、SpringMVC 与 MyBatis 核心知识点解析
我梳理的这些内容,涵盖了 Spring、SpringMVC 和 MyBatis 的核心知识点。 在 Spring 中,我了解到 IOC 是控制反转,把对象控制权交容器;DI 是依赖注入,有三种实现方式。Bean 有五种作用域,单例 bean 的线程安全问题及自动装配方式也清晰了。事务基于数据库和 AOP,有失效场景和七种传播行为。AOP 是面向切面编程,动态代理有 JDK 和 CGLIB 两种。 SpringMVC 的 11 步执行流程我烂熟于心,还有那些常用注解的用法。 MyBatis 里,#{} 和 ${} 的区别很关键,获取主键、处理字段与属性名不匹配的方法也掌握了。多表查询、动态
342 0
|
11月前
|
JSON 前端开发 Java
第05课:Spring Boot中的MVC支持
第05课:Spring Boot中的MVC支持
428 0
|
XML Java 数据格式
Spring IoC容器的设计与实现
Spring 是一个功能强大且模块化的 Java 开发框架,其核心架构围绕 IoC 容器、AOP、数据访问与集成、Web 层支持等展开。其中,`BeanFactory` 和 `ApplicationContext` 是 Spring 容器的核心组件,分别定位为基础容器和高级容器,前者提供轻量级的 Bean 管理,后者扩展了事件发布、国际化等功能。
374 18
|
XML Java 数据格式
京东一面:spring ioc容器本质是什么? ioc容器启动的步骤有哪些?
京东一面:spring ioc容器本质是什么? ioc容器启动的步骤有哪些?
|
设计模式 前端开发 Java
了解 Spring MVC 架构、Dispatcher Servlet 和 JSP 文件的关键作用
Spring MVC 是 Spring 框架的一部分,是一个 Web 应用程序框架。它旨在使用 Model-View-Controller(MVC) 设计模式轻松构建Web应用程序。
333 0
|
存储 设计模式 前端开发
什么是SpringMVC?简单好理解!什么是应用分层?SpringMVC与应用分层的关系? 什么是三层架构?SpringMVC与三层架构的关系?
文章解释了SpringMVC的概念和各部分功能,探讨了应用分层的原因和具体实施的三层架构,以及SpringMVC与三层架构之间的关系和联系。
1135 1
什么是SpringMVC?简单好理解!什么是应用分层?SpringMVC与应用分层的关系? 什么是三层架构?SpringMVC与三层架构的关系?

热门文章

最新文章