皮皮网

【财易源码】【超跌股源码】【郑爽源码】ioc源码解读

2024-12-24 11:06:01 来源:c 图形建模源码

1.spring的组件及作用(springclou组件)
2.Spring IoC:getBean 详解
3.Spring IoC源码深度剖析
4.Spring源码系列-BeanPostProcessor与BeanFactoryPostProcessor
5.什么是码解AOP、IOC他们的码解作用是什么?
6.ioc是什么意思

ioc源码解读

spring的组件及作用(springclou组件)

       ç®€è¦è¯´æ˜Žspring的两个核心功能及其作用

       spring框架是一个轻量级的开源仔伍框架,是一个IOC和AOP容器。它是低侵入式设计,独立于各种应用服务器,

       ä¾èµ–注入的特点将组件关系透明化,降低耦合度

       æŽ§åˆ¶åè½¬ï¼ˆIOC):用来降低程序代码之间的耦合度,使整个程序体系结构更加灵活,同时将类的创建和依赖关系写在配置文件里,由配置文件注入,达到松耦合的效果。

       DI(依赖注入)

       è®¾å€¼æ³¨å…¥ï¼šåº•å±‚实现set方法赋值。

       ä½¿ç”¨æž„造器注入:罩凳底层实现构造方法注入,根据bean下的参数类型和参数数量,寻找对应的构造方法。

       è‡ªåŠ¨è£…配,不能自动装配所谓的简单类型包括基本类型,字符串和集合类通常用来自动装配对象

       æŒ‰ç…§åç§°æ¥è‡ªåŠ¨è£…配底层实现是set方法

       æŒ‰ç…§ç±»åž‹æ¥è‡ªåŠ¨è£…配底层实现是set方法

       2.面向切面编程(AOP)

       æœ€ä¸»è¦çš„作用:可以在不修改源代码的情况下,给目标方法动态添加功能

       ä¸šåŠ¡é€»è¾‘就专心的处理实际需求,通用的增强功能独立出来。将安全事务等程序逻辑相对独立的功能抽取出来,利用Spring的配置文件将这些功能插进去,实现了按照切面编程,提高了复用性。

       å››ç§å¢žå¼ºæ–¹å¼ï¼š

       å‰ç½®å¢žå¼ºï¼Œåœ¨æ ¸å¿ƒåŠŸèƒ½ä¹‹å‰æ‰§è¡Œçš„额外功能

       åŽç½®å¢žå¼ºï¼Œåœ¨æ ¸ç‰©æˆšæ—…心功能之后执行的额外功能

       å¼‚常增强,在核心功能发生异常时执行的额外功能

       çŽ¯ç»•å¢žå¼ºï¼Œåœ¨æ ¸å¿ƒåŠŸèƒ½ä¹‹å‰ä»¥åŠä¹‹åŽæ‰§è¡Œçš„额外功能

       spring包含哪些组件

       Spring框架是一个分层架构,由7个定义良好的模块组成袜判。Spring模块构建在核心容器之上,核心容器竖宴定义了创建、配置和管理bean的方式,组成Spring框架的每个模块(或组件)都可以单独存告纤改在,或者与其他一个或多个模块联合实现。

SpringMVC主要组件说明

       1、前端控制器DispatcherServlet(不需要开发,由框架提供【核心】)

       DispatcherServlet是SpringMVC的入口函数。接收请求,响应结果,相当于转发器碧简,中央处理器。有了DispatcherServlet,可以大大减少其它组件之间的耦合度。

       ç”¨æˆ·è¯·æ±‚到达前端控制器,就相当于mvc模式中的c,DispatcherServlet是整个流程控制的中心,由它调用其它组件来处理用户的请求。

       2、处理器映射器HandlerMapping(不需要开发,由框架提供)

       HandlerMapping负责根据用户请求(URL),找到相应的Handler即处理器(Controller),SpringMVC提供了不同映射器实现的不同映射方式,例如:配置文件方式,实现接口方式,注解方式等。

       3、处理器适配器HandlerAdapter(不需要开发,由框架提供)

       æŒ‰ç…§ç‰¹å®šè§„则(HandlerAdapter要求的规则)去执行Handler,通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行处理。

       4、处理器Handler(需要工程师开发)

       Handler是继DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下,Handler对具体的用户请求进行处理。由于Handler涉及到具体的用户业务请求,所以一般情况下需要工程师根据业务需求来开发Handler。

       5、视图解析器ViewResolver(不需要开发,由框架提供)

       ä½œç”¨ï¼šè¿›è¡Œè§†å›¾è§£æžï¼Œæ ¹æ®é€»è¾‘视图名解析成真正的视图(View),ViewResolver负责将处理结果生成View视图。首先,根据逻辑视图名解析成物理视图名(即具体的页面地址),再生成View视图对象,最后对View进行渲染,将处理结果通过页面展示给用户。

       SpringMVC框架提供了很多的View视图类型,包括:jstlView、freemarkerView、pdfView等。一般情况下,需要通过页面标签或页渗键面模版技术,将模型数据通过页面展示给用户,这需要由工程师根据丛慧巧业务需求开发具体的页面。

       6、视图View(需要工程师开发)

       View是一个接口,实现类才可以支持不同的View类型(jsp、freemarker、pdf...)

       æ€»ç»“:处理器Handler(也就是平常说的Controller控制器)以及视图层View,都是需要自行开发的。其他的一些组件,如:前端控制器DispatcherServlet、处理器映射器HandlerMapping、处理器适配器HandlerAdapter等都是由框架提供。

spring主要的作用?

       Spring框架是为了解决企业应用开发的复杂性而创建的。

       Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。使用基本的JavaBean代替EJB,并提供了更多的企业应用功能。

       æ‰©å±•èµ„æ–™

       ä¼˜ç‚¹

       1、JAVAEE应该更加容易使用。

       2、面向对象的设计比任何实现技术(比如JAVAEE)都重要。

       3、面向接口编程,而不是针对类编程。Spring将使用接口的复杂度降低到零。(面向接口编程有哪些复杂度)

       4、代码应该易于测试。Spring框架会帮助你,使代码的测试判衡更加简单。

       5、JavaBean提供了应用程序配置的最好方法。

       6、在Java中,已检查异常(Checkedexception)被过度使用。框架不应该迫使你捕拍碧获不掘贺做能恢复的异常。

       å‚考资料来源:百度百科-spring框架

Spring IoC:getBean 详解

       接着 Spring IoC:finishBeanFactoryInitialization 详解,我们正式开始学习获取 bean 实例方法,码解该方法是码解 Spring 最核心的方法。

       单击 preInstantiateSingletons 方法里的码解 getBean(beanName) 代码,进入该方法。码解财易源码

       见 doGetBean 方法详解。码解

       doGetBean

       1.解析 beanName,码解主要是码解解析别名、去掉 FactoryBean 的码解修饰符 “&”,在 Spring IoC:finishBeanFactoryInitialization 详解 中的码解代码块4已解析过。

       2.尝试从缓存中获取 beanName 对应的码解实例,在 Spring IoC:finishBeanFactoryInitialization 详解 中的码解代码块7已解析过。

       3.1 返回 beanName 对应的码解实例对象(主要用于 FactoryBean 的特殊处理,普通 bean 会直接返回 sharedInstance 本身),码解见代码块1详解。

       6.如果不是仅仅做类型检测,而是创建 bean 实例,这里要将 beanName 放到 alreadyCreated 缓存,见代码块5详解。

       7.根据 beanName 重新获取 MergedBeanDefinition,在 Spring IoC:finishBeanFactoryInitialization 详解 中的代码块2已解析过。

       8.2 检查 dep 是否依赖于 beanName,即检查是否存在循环依赖,见代码块6详解。

       8.4 将 dep 和 beanName 的依赖关系注册到缓存中,见代码块7详解。

       9.1 scope 为 singleton 的 bean 创建(新建了一个 ObjectFactory,并且重写了 getObject 方法),见代码块8详解。

       9.1.1、9.2.2、9.3.4 创建 bean 实例,限于篇幅,在下篇文章单独解析。超跌股源码

       9.1.2、9.2.4、9.3.6 返回 beanName 对应的实例对象,见代码块1详解。

       9.2.1 scope 为 prototype 时创建实例前的操作、9.2.3 scope 为 prototype 时 创建实例后的操作,相对应的两个方法,见代码块详解。

       代码块1:getObjectForBeanInstance

       如果对 FactoryBean 不熟悉的,可以回头去看 Spring IoC:finishBeanFactoryInitialization 详解 中对 FactoryBean 的简单介绍。

       6.mbd 为空,但是该 bean 的 BeanDefinition 在缓存中存在,则获取该 bean 的 MergedBeanDefinition,在 Spring IoC:finishBeanFactoryInitialization 详解 中的代码块2已经解析过。

       8.从 FactoryBean 获取对象实例,见代码块2详解。

       代码块2:getObjectFromFactoryBean

       3.调用 FactoryBean 的 getObject 方法获取对象实例,见代码块3详解。

       5.对 bean 实例进行后续处理,执行所有已注册的 BeanPostProcessor 的 postProcessAfterInitialization 方法,见代码块4详解。

       代码块3:doGetObjectFromFactoryBean

       很简单的方法,就是直接调用 FactoryBean 的 getObject 方法来获取到对象实例。

       细心的同学可以发现,该方法是以 do 开头,看过 Spring IoC:源码总览 的同学知道,我在总览里就特别提到以 do 开头的方法是最终进行实际操作的方法,例如本方法就是 FactoryBean 最终实际进行创建 bean 对象实例的方法。

       代码块4:postProcessObjectFromFactoryBean

       这边走的是 AbstractAutowireCapableBeanFactory 里的方法。通过前面的介绍,我们知道创建的 BeanFactory 为 DefaultListableBeanFactory,而 DefaultListableBeanFactory 继承了 AbstractAutowireCapableBeanFactory,因此这边会走 AbstractAutowireCapableBeanFactory 的重写方法。

       在 Spring IoC:registerBeanPostProcessors 详解 中已经学过 BeanPostProcessor,郑爽源码在创建完 bean 实例后,会执行 BeanPostProcessor 的 postProcessAfterInitialization 方法。

       代码块5:markBeanAsCreated

       2.这边会将 beanName 对应的 MergedBeanDefinition 移除,然后在之后的代码重新获取,主要是为了使用最新的 MergedBeanDefinition 来进行创建操作。

       代码块6:isDependent

       这边引入了一个缓存 dependentBeanMap:beanName -> 所有依赖 beanName 对应的 bean 的 beanName 集合。内容比较简单,就是检查依赖 beanName 的集合中是否包含 dependentBeanName,隔层依赖也算。例如:A 依赖了 B,B 依赖了 C,则 A 也算依赖了 C。

       代码块7:registerDependentBean

       这边又引入了一个跟 dependentBeanMap 类似的缓存,dependenciesForBeanMap:beanName -> beanName 对应的 bean 依赖的所有 bean 的 beanName 集合。

       这两个缓存很容易搞混,举个简单例子:例如 B 依赖了 A,则 dependentBeanMap 缓存中应该存放一对映射:其中 key 为 A,value 为含有 B 的 Set;而 dependenciesForBeanMap 缓存中也应该存放一对映射:其中 key 为:B,value 为含有 A 的 Set。

       代码块8:getSingleton

       5.创建单例前的操作,7.创建单例后的操作,这两个方法是对应的,见代码块9详解。

       6.执行 singletonFactory 的 getObject 方法获取 bean 实例,该方法会走文章开头 doGetBean 方法的注释 9.1.1。

       8.如果是新的单例对象,将 beanName 和对应的单例对象添加到缓存中,见代码块详解。

       代码块9:beforeSingletonCreation、afterSingletonCreation

       inCreationCheckExclusions 是要在创建检查排除掉的 beanName 集合,正常为空,可以不管。这边主要是引入了 singletonsCurrentlyInCreation 缓存:当前正在创建的 bean 的 beanName 集合。在 beforeSingletonCreation 方法中,aggregation源码通过添加 beanName 到该缓存,可以预防出现构造器循环依赖的情况。

       为什么无法解决构造器循环依赖?

       我们之前在 Spring IoC:finishBeanFactoryInitialization 详解 中的代码块7提过,getSingleton 方法是解决循环引用的核心代码。解决逻辑的第一句话:“我们先用构造函数创建一个 “不完整” 的 bean 实例”,从这句话可以看出,构造器循环依赖是无法解决的,因为当构造器出现循环依赖,我们连 “不完整” 的 bean 实例都构建不出来。Spring 能解决的循环依赖有:通过 setter 注入的循环依赖、通过属性注入的循环依赖。

       代码块:addSingleton

       代码块:beforePrototypeCreation、afterPrototypeCreation

       该方法和代码块9的两个方法类似。主要是在进行 bean 实例的创建前,将 beanName 添加到 prototypesCurrentlyInCreation 缓存;bean 实例创建后,将 beanName 从 prototypesCurrentlyInCreation 缓存中移除。这边 prototypesCurrentlyInCreation 存放的类型为 Object,在只有一个 beanName 的时候,直接存该 beanName,也就是 String 类型;当有多个 beanName 时,转成 Set 来存放。

       总结

       本文介绍了获取 bean 实例的大部分内容,包括先从缓存中检查、 FactoryBean 的 bean 创建、实例化自己的依赖(depend-on 属性)、创建 bean 实例的前后一些标记等,在下篇文章中,将解析创建 bean 的内容。

       推荐阅读

Spring IoC源码深度剖析

       Spring IoC容器初始化深度剖析

       Spring IoC容器是Spring的核心组件,主要负责对象管理和依赖关系管理。容器体系丰富多样,如BeanFactory作为顶层容器,它定义了所有IoC容器的基本原则,而ApplicationContext及其子类如ClassPathXmlApplicationContext和AnnotationConfigApplicationContext则提供了额外功能。九零源码Spring IoC容器的初始化流程关键在AbstractApplicationContext的refresh方法中。

       1.1 初始化关键点

       通过创建特定类LagouBean并设置断点,我们发现Bean的创建在未设置延迟加载时,发生在容器初始化过程中。构造函数调用、InitializingBean的afterPropertiesSet方法以及BeanFactoryPostProcessor和BeanPostProcessor的初始化和调用,都在refresh方法的不同步骤中发生。

       1.2 主体流程概览

       Spring IoC容器初始化的主体流程主要集中在AbstractApplicationContext的refresh方法,涉及Bean对象创建、构造函数调用、初始化方法执行和处理器调用等步骤。

       1.3 深度剖析

       分析发现,延迟加载机制使得懒加载的bean在第一次调用getBean时才进行初始化。而对于非懒加载bean,它们在容器初始化阶段已经完成并缓存。Spring处理循环依赖的方法依赖于构造器调用的顺序规则,不支持原型bean的循环依赖,而对单例bean则通过setXxx或@Autowired方法提前暴露对象来避免循环依赖。

Spring源码系列-BeanPostProcessor与BeanFactoryPostProcessor

       在Spring框架中,BeanPostProcessor与BeanFactoryPostProcessor各自承担着不同的职责,它们在IoC容器的工作流程中起着关键作用。

       BeanFactoryPostProcessor作用于BeanDefinition阶段,对容器中Bean的定义进行处理。这个过程发生在BeanFactory初始化时,对BeanDefinition进行修改或增强,提供了一种在不修改源代码的情况下定制Bean的机制。相比之下,BeanPostProcessor则在Bean实例化之后生效,对已经创建的Bean对象进行进一步处理或替换,提供了更晚、更灵活的扩展点。

       以制造杯子为例,BeanFactoryPostProcessor相当于在选择材料和形状阶段进行定制,而BeanPostProcessor则在杯子制造完成后,进行诸如加花纹、抛光等深加工。

       在Spring框架中,BeanPostProcessor的使用场景较为广泛,尤其在实现AOP(面向切面编程)时,通过使用代理类替换原始Bean,实现如日志记录、事务管理等功能。

       此外,容器在启动后,还会进行消息源初始化、广播器初始化及监听器初始化,为Bean实例化做好准备。完成这些准备工作后,容器会调用registerBeanPostProcessors方法注册BeanPostProcessor,对已创建的Bean进行进一步处理。同时,初始化消息源、广播器和监听器,为后续事件处理做好基础。

       总结,BeanFactoryPostProcessor与BeanPostProcessor在Spring IoC容器中的作用各有侧重。前者侧重于对BeanDefinition的定制,后者则是在Bean实例化后的进一步加工,两者共同为构建灵活、可扩展的IoC容器提供了强大的支持。

       在深入分析Spring框架的源码时,我们发现refresh()方法的实现中包含了对BeanFactoryPostProcessor和BeanPostProcessor的注册与处理。这些处理步骤确保了容器能够在启动时对Bean进行正确的配置和初始化。

       文章中通过一个例子展示了如何使用BeanFactoryPostProcessor替换已注册Bean的实现,以及对其源码的分析。通过例子和源码的结合,读者能够更直观地理解这些后置处理器在Spring框架中的应用和工作原理。

什么是AOP、IOC他们的作用是什么?

       什么是IoC

       Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。如何理解好Ioc呢?理解好Ioc的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”,那我们来深入分析一下:

       控制是什么:传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对象的创建;谁控制谁?当然是IoC 容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。

       为何是反转,哪些方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。

       IoC能做什么

       IoC不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。

       其实IoC对编程带来的最大改变不是从代码上,而是从思想上,发生了“主从换位”的变化。应用程序原本是老大,要获取什么资源都是主动出击,但是在IoC/DI思想中,应用程序就变成被动的了,被动的等待IoC容器来创建并注入它所需要的资源了。

       IoC和DI

       DI—Dependency Injection,即“依赖注入”:是组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。

       注:如果想要更加深入的了解IoC和DI,请参考大师级人物Martin Fowler的一篇经典文章《Inversion of Control Containers and the Dependency Injection pattern》,原文地址:/articles/injection.html。

       AOP:面向切面编程

       什么是AOP:

       概念:在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。(百度百科)

       简单的说:就是将程序中重复的代码抽取出来,在需要执行的时候,使用动态代理的技术,在不修改源码的基础上,对我们的已有方法进行增强。

       AOP的作用和优势:

       作用:从定义中来看,就是为了在程序运行期间,不修改源码对已有方法进行增强。

       优势:减少重复代码 提交了开发效率 维护方便

       实现方式: 就是动态代理的技术

       具体的作用:实现事务的控制 日志 和 安全模块

       想系统的学习编程可以来我这看看,希望对您有所帮助!~

ioc是什么意思

       IOC是控制反转的缩写。

       详细解释如下:

一、IOC的基本含义

       IOC作为控制反转的缩写,是软件工程中一个重要的概念。在面向对象编程中,IOC思想强调的是将传统程序中由代码直接控制的流程,转变为通过配置文件或外部服务来控制,从而使得应用程序的配置和依赖性规范与实际的应用程序代码分开。这样,当应用需要进行变更或调整时,只需要更改配置文件,而无需更改实际的应用程序代码。IOC大大增强了软件系统的可维护性和灵活性。

二、IOC的重要性

       在传统的程序设计中,程序的流程通常由程序本身的代码控制。而随着软件系统的复杂性和规模的扩大,这种方式的缺点逐渐显现。一旦系统需要改变流程,就意味着需要修改源代码,这不仅增加了维护的难度,也降低了系统的灵活性。而IOC的出现解决了这一问题,它通过将程序的依赖关系外部化,使得程序流程的控制权发生了反转。这样,程序就可以更加专注于自身的业务逻辑,而无需关心依赖关系的创建和管理。

三、IOC的应用场景

       IOC在软件系统中有着广泛的应用场景。特别是在依赖注入技术中,IOC的思想得到了充分的体现。在依赖注入技术中,对象的创建和对象间的相互调用关系被外部化,并由IOC容器来管理。通过这种方式,开发者可以更加专注于业务逻辑的实现,而无需关心对象的创建和配置细节。这种解耦的设计方式大大提高了软件系统的可维护性和可扩展性。

       综上所述,IOC作为控制反转的缩写,在软件工程中具有重要意义。它通过改变程序流程的控制方式,使得软件系统的配置和依赖关系与实际的应用程序代码分开,从而提高了软件系统的可维护性和灵活性。