当前位置: 首页 > 科技观察

请大哥解释一下Spring框架中bean的生命周期?

时间:2023-03-22 13:16:38 科技观察

1。Bean的生命周期关于Bean的生命周期,如果不说这个Spring,很多人其实会想到New,它以New对象的形式实现了Bean的实例化,而我们不再使用Bean之后,我们的Java此时会对指定的Bean进行垃圾回收。但是对于Spring来说,Bean的生命周期可能会让人头疼。毕竟Spring这么复杂,里面的Bean管理很有逻辑性,每一层都有每一层的步骤。如果去百度搜一下Springbeans的生命周期,很多人都会这样解释。IoC容器启动后,并不会立即实例化对应的bean。此时,容器只拥有所有对象。BeanDefinition(BeanDefinition:容器依赖于一些工具加载的XML配置信息进行解析分析,并将解析后的信息编组为对应的BeanDefinition)。只有调用了getBean()才有可能触发Bean实例化阶段的活动,有些内容不会解释的很透彻,比如为什么只有调用getBean()change才有可能触发Bean实例。2.生命周期流程图2.1简图在这张图中,Bean在Spring中的生命周期分为几个步骤,即:通过构造方法实例化Bean对象。通过setter方法设置对象的属性。通过Aware,即它的子类BeanNameAware,调用Bean的setBeanName()方法传递Bean的ID(XML中注册的ID)。初始化bean时调用setBeanName方法。通过这个方法,可以得到BeanFactory和Bean在XML中注册的ID。如果Bean实现了BeanFactoryAware,那么工厂调用setBeanFactory(BeanFactoryvar1)传入的参数也是它自己。将Bean实例传递给BeanPostProcessor中的postProcessBeforeInitialization前置方法。完成Bean初始化将Bean实例传递给BeanPostProcessor中的postProcessAfterInitialization方法。这时候在Bean已经正常的情况下,调用上次DisposableBean中的destroy方法进行销毁。而阿芬觉得,如果面试的时候面试官问这个问题,你从图表开始,然后把这些都告诉他,那么相应的,如果你现在不继续深挖这些答案的内容,可能是充足的。然后我们要从根本上论证阿芬写的东西。而且这个细节我们有时候可能记不住,可能还理解不深,但是我们可以从四五个方面记住,构造实例化属性赋值完成初始化(处理前和处理后),使用后销毁从这五个方面来背,或许可以把这张图展开,简明扼要地回答面试官的问题。代码验证包com.yld.bean;importorg.springframework.beans.factory.BeanNameAware;publicclassPersonimplementsBeanNameAware{privateStringname;/***实现类上的override方法*@params*/@OverridepublicvoidsetBeanName(Strings){System.out.println("调用BeanNameAware中的setName赋值");}publicPerson(){}/***属性赋值*@paramname*/publicvoidsetName(Stringname){System.out.println("设置对象属性setName()..");this.name=name;}/***Bean初始化*/publicvoidinitBeanPerson(){System.out.println("InitializeBean");}/***Bean方法使用:speak*/publicvoidspeak(){System.out.println("使用Bean的Speak方法");}/***DestroyBean*/publicvoiddestroyBeanPerson(){System.out.println("DestroyBean");}}主方法publicstaticvoidmain(String[]args){ClassPathXmlApplicationContextpathXmlApplicationContext=newClassPathXmlApplicationContext("applicationContext.xml");Personperson=(Person)pathXmlApplicationContext.getBean("person");person.speak();pathXmlApplicationContext.close();}运行结果展示D:\develop\JDK8\jdk1.8.0_181\bin\java.exe"-javaagent:D:\develop\IDEA\IntelliJIDEA2018.1.8\lib\idea_rt.jar=63906:D:\develop\IDEA\IntelliJIDEA2018.1.8\bin"-Dfile.encoding=UTF-8-classpathD:\develop\JDK8\jdk1.8.0_181\jre\lib\charsets.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\deploy.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\ext\dnsns.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\ext\jaccess.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\ext\localedata.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\ext\nashorn.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\ext\sunec.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\ext\zipfs.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\javaws.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\jce.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\jfr.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\jfxswt.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\jsse.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\management-agent.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\plugin.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\resources.jar;D:\develop\JDK8\jdk1.8.0_181\jre\lib\rt.jar;D:\develop\IDEAProject\KaiYuan\target\classes;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter\2.1.8.RELEASE\spring-boot-starter-2.1.8.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot\2.1.8.RELEASE\spring-boot-2.1.8.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-context\5.1.9.RELEASE\spring-context-5.1.9.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-aop\5.1.9.RELEASE\spring-aop-5.1.9.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-beans\5.1.9.RELEASE\spring-beans-5.1.9.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-expression\5.1.9.RELEASE\spring-expression-5.1.9.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\2.1.8.RELEASE\spring-boot-autoconfigure-2.1.8.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-logging\2.1.8.RELEASE\spring-boot-starter-logging-2.1.8.RELEASE.jar;C:\Users\Administrator\.m2\repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;C:\Users\Administrator\.m2\repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;C:\Users\Administrator\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.11.2\log4j-to-slf4j-2.11.2.jar;C:\Users\Administrator\.m2\repository\org\apache\logging\log4j\log4j-api\2.11.2\log4j-api-2.11.2.jar;C:\Users\Administrator\.m2\repository\org\slf4j\jul-to-slf4j\1.7.28\jul-to-slf4j-1.7.28.jar;C:\Users\Administrator\.m2\repository\javax\annotation\javax.annotation-api\1.3。2\javax.annotation-api-1.3.2.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-core\5.1.9.RELEASE\spring-core-5.1.9.RELEASE。jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-jcl\5.1.9.RELEASE\spring-jcl-5.1.9.RELEASE.jar;C:\Users\Administrator\.m2\存储库\org\yaml\snakeyaml\1.23\snakeyaml-1.23.jar;C:\Users\Administrator\.m2\repository\org\slf4j\slf4j-api\1.7.28\slf4j-api-1.7.28.jarcom。yld.bean.Test16:54:58.817[main]DEBUGorg.springframework.context.support.ClassPathXmlApplicationContext-Refreshingorg.springframework.context.support.ClassPathXmlApplicationContext@123772c416:54:59.074[main]DEBUGorg.springframework.beans.factory.xml。XmlBeanDefinitionReader-Loaded1beanddefinitionsfromclasspathresource[applicationContext.xml]16:54:59.121[main]DEBUGorg.springframework.beans.factory。support.DefaultListableBeanFactory-Creatingsharedinstanceofsingletonbean'person'setobjectpropertysetName()..CallsetNameassignmentinBeanNameAwareInitializeBeanUseBean'sSpeak方法16:54:59.232[main]DEBUGorg.springframework.context.support.ClassPathXmlApplicationContext-Closingorg.springframework.context.support.ClassPathXmlApplicationContext@123772c4,startedonSunJun0716:54:58CST2020destroyingBeanProcessfinishedwithexitcode0是不是和大家预想的一样?用案例回答面试官后,我们最好研究源代码部分。毕竟研究清楚了。你会更深入地理解它吗?InstantiationAwareBeanPostProcessor类是一个继承的BeanPostProcessor,这个类的作用是什么?源码注释是这样解释的:方法一:@NullabledefaultObjectpostProcessBeforeInstantiation(ClassbeanClass,StringbeanName)throwsBeansException{returnnull;}在目标bean实例化之前应用这个Bean处理器返回的bean对象可能是使用了一个proxybean而不是target,也就是说在实例化bean之前调用postProcessBeforeInstantiation。那么AOP在面试中的使用呢?当面试官让你举个例子的时候,你可以直接用这个Spring里面的源码给他讲解,分分钟让面试官打动你。方法二:可以看到这个方法是在属性赋值方法中,但是在进行实际的赋值操作之前。它的返回值是布尔值。defaultbooleanpostProcessAfterInstantiation(Objectbean,StringbeanName)throwsBeansException{returntrue;}你还能这么理解,如果返回值为false,那么赋值失败,也就是间接阻塞了赋值。并且初始化的类同BeanPostProcessor方法一:任何Bean初始化回调,比如在@NullabledefaultObjectpostProcessBeforeInitialization(Objectbean,StringbeanName)throwsBeansException{returnbean;}之后初始化Bean属性方法二:应用这个Bean后处理程序给一个新的Beaninstance,bean的任何初始化后回调(例如{@code}或初始化bean属性后的自定义init方法)。该bean已经填充了属性值。返回的bean实例可能是原始包装器。将此bean后处理程序应用于给定的新bean实例,bean的任何初始化后回调(例如在bean的属性{@code}或自定义init方法初始化之后)。该bean已经填充了属性值。返回的bean实例可能是原始包装器。@NullabledefaultObjectpostProcessAfterInitialization(Objectbean,StringbeanName)throwsBeansException{returnbean;}同样的评论翻译的意思也很明白,这也是阿粉喜欢下载一个插件看评论的原因。毕竟看源码,看别人理解的和自己理解的,有时候差距是非常大的。