面试官问我SpringBean,我松了一口气。每天都会接触各种bean对象,之前说过,spring提供了IOC来完成bean的创建,这样我们就可以不用new,直接获取对象。使用对象后,我们再看看springbean的定义。spring官方文档对beans的解释如下:在Spring中,构成应用程序主干并由SpringIoC容器管理的对象称为beans。bean是由SpringIoC容器实例化、组装和管理的对象。概念很简单明了,我们提取关键信息:一个bean是一个对象,一个或多个不受限制的bean由Spring中一个叫做IoC的东西管理我们的应用是由bean组成的。下面我们将从springbean的范围、定义继承、前处理器和后处理器、生命周期(加载过程)等方面入手来分析springbean,让大家更加熟悉。采访的范围直接起飞。springbean的作用域分为以下几种:1、Singleton:单例作用域2、prototype:每次从容器中调用一个bean,都会返回一个新的实例,相当于执行一次新的实例化操作3、request:每次HTTP请求调用一个bean,spring容器都会创建一个新的Bean4、session:同一个HttpSession共享一个bean,不同的session使用不同的bean一个Bean实例以单例的形式存在。Spring采用容器的方式,让我们只需要配置就可以得到天然的单例模式。一般来说,stateless或者state-immutable类适合使用单例模式实现,但是Spring利用AOP和LocalThread的能力专门处理非线程安全的变量(states),使得一些非线程安全的变量(states))类(持有Connection的DAO类)成为线程安全类。由于Spring的超强能力,在实际应用中,大部分bean都可以作为单例运行,这也是为什么将bean的默认作用域指定为单例的原因。单例的bean在同一个SpringIoC容器中只会有一个实例。prototype:每次从容器中调用bean,都会返回一个新的实例,相当于执行了一次新的实例化操作。原型范围的bean将导致对bean的每个请求(将其注入另一个bean),当以编程方式调用容器的getBean()方法时,将创建一个新的bean实例。原型是一种原型类型。它不是在我们创建容器的时候实例化的,而是在我们获取bean的时候创建了一个对象,而且我们每次获取的对象都不是同一个对象。根据经验,您应该对有状态bean使用原型作用域,对无状态bean使用单例作用域。另外,Spring容器在把原型bean交给调用者之后,就不再负责管理它的生命周期了。request:每次HTTP请求调用bean,spring容器都会创建一个新的bean,每个http请求都会创建一个新的bean,只在WebApplicationContext环境中使用。请求范围的bean对应一个HTTP请求和生命周期。每次HTTP请求调用一个bean,Spring容器都会创建一个新的bean;当请求被处理时,bean被销毁。session:同一个HttpSession共享一个bean,不同的session使用不同的bean。同一个httpsession共享一个bean,不同的httpsession使用不同的bean,只在WebApplicationContext环境下使用。Bean在整个HTTP会话中工作。Session中的所有HTTP请求将共享同一个Bean。Bean实例只有在HTTPSession结束后才会被销毁。globalSession:全局会话共享一个bean,只在WebApplication环境下使用。globalSession与同一个globalSession共享一个bean,在Portlet中使用,只在WebApplication环境中使用。globalSession的作用域与会话作用域类似,但仅用于PortletWeb应用程序。Portlet定义了一个全局会话,它由构成PortletWeb应用程序的所有子Portlet共享。如果不是在Portletweb应用中,globalSession相当于session定义继承和pre-postprocessor定义继承:bean定义可以包含很多配置信息,包括构造函数参数,属性值,以及初始化方法等具体的容器信息,静态工厂方法名等子bean可以继承父bean的配置数据,当然你也可以重写里面的值,或者增加一个值,Springbean的定义继承与类继承无关Java,但是道理是一样的,我们可以定义一个父bean作为模板,然后多个子bean可以从父bean继承需要的配置。接下来,让我们看看预处理器和后处理器。顾名思义,预处理器是指在实例化对象之前。加工。后处理是指对象被实例化后的处理。Spring中预处理器的接口是BeanFactoryPostProcess。这种机制允许我们在实例化相应的对象之前修改容器中注册的BeanDefinition存储信息。获取Provider信息后,我们可以通过监听触发Protocol#refer,具体调用哪个协议取决于URL的协议。我们看一下DubboProtocol内部的refer,可以根据这个机制给Bean添加其他信息,修改Bean定义的一些属性值。如果要自定义预处理器,需要实现BeanFactoryPostProcess接口。当一个容器中存在多种预处理时,预处理的实现类可以同时继承Ordered接口。顾名思义就是用来排序的,可以实现优先级。Spring容器提供了几个现成的预处理器,例如:PropertyPlaceholderConfigurer:允许在xml文件中使用占位符。将placeholder代表的资源单独配置到一个简单的Properties文件中加载PropertyOverrideConfigurer:与PropertyPlaceholderConfigurer不同,该类用于处理容器中默认值被替换为新值的场景CustomEditorConfigurer:前面两个预处理器BeanDefinition全部处理完毕。通过修改BeanDefinition的数据来达到目的。CustomEditorConfigurer没有对BeanDefinition做任何更改。它负责将以后要用到的信息注册到容器中。例如,将类型转换器注册到BeanDefinition中。用于BeanDefinition将获取到的String类型参数转换为需要的类型。Spring中的后处理器是BeanPostProcessor接口。Spring中的后处理器是BeanPostProcessor接口。可以看到有两个方法,BeanBeforePostProcessor和BeanAfterPostProcessor。我们也可以根据方法名来猜测,大概是一个在前面执行,另一个在后面执行。但问题来了。我们没有看到上面的预处理器吗?为什么这里之前还有一个?那么之前和之后是做什么用的呢?这里的before和after是相对于对象的初始化而言的。上面的前处理器和后处理器都是针对对象的实例化的。两者的范围不同。实例化就是我们常说的,创建Bean的过程,也就是调用Bean的构造函数;而初始化过程是一个赋值的过程,也就是调用Bean的setter,设置Bean的属性过程生命周期(加载过程)springbean的生命周期,也就是加载过程,应该和spring的循环依赖是一样的,也是面试中经常被问到的一个点。不知道你有没有问过。不管怎样,我被问到了。spring这个话题本来就是面试中非常热门的一个点,IOC和AOP是经常被问到的,也是最基础的部分,跟源码关系不大。他们会问循环依赖的三级缓存怎么用,为什么不用二级缓存,bean生命周期等问题。嗯,多学点数据结构和算法,多学点spring,统统拿下。我们看一下springbean的生命周期过程,可以分为几个阶段1、实例化过程2、后处理放入缓存(这一步是为了循环依赖)3、初始化过程(属性赋值)4.销毁过程的主要逻辑在doCreateBean()方法中。其实源码注释也很清楚。大家可以多阅读源码。真的很棒。每个人都很好。其实没用的博客不用看太多,当然对我有用,关注很重要!毕竟,如果您注意,就不会迷路。下次找工作的时候,你还不知道复习什么?当你知道复习哪些知识点的时候,我的账号真的很重要!我也会总结所有相关的技术文章,放在GitHub上。可以随时翻阅公众号关注,时不时看几篇技术文章,也可以看下面的灵魂文章;收藏GitHub地址,下次面试不用担心,轻松拿下offer,直接起飞。这个源码我贴出来,其实有点多,大家不用细说阅读,只是阅读了一个粗略的流程。这个方法真的很长,也是主流。快速看一下,就是先实例化Bean,然后,就和我们上面说的后处理器相关了。允许后置处理器设置处理器修改相应的属性,然后将实例Bean直接放入缓存中,非常渴望放入缓存中!相信看过我上篇文章的springcycle依赖的大家应该很熟悉了,也知道为什么在这里紧急放入缓存了。没错,就是为了解决spring的循环依赖问题。然后就是属性设置和初始化的过程。这个阶段主要是属性赋值,这里有些朋友有个误区,以为这块会为属性分配内存空间,不对,分配内存的操作是在实例化Bean的过程中,JVM已经完成了分配这个过程中的内存空间。第一步是摧毁。这一步真的没什么好说的。我想说的应该就是这些了。如果想深入了解bean,可以阅读源码。真心推荐大家看一下关键地方的源码。很多小伙伴也为阅读源码而头疼。我会教你一个好方法。阅读源码的时候,首先可以找到其中的重点。如何找到它?谷歌,百度!找到重点,然后一步步研究源码的设计过程和一些地方的细节,不仔细看每一个细节,真的没必要,浪费时间,关注重点,看那些下次准备换工作的关键地方不用担心要复习什么!
