javascript
异常将上下文初始化事件发送到类的侦听器实例_Spring的Bean实例化原理,这一次彻底搞懂了!...
前言
之前分析了Spring XML和注解的解析原理,并將其封裝為BeanDefinition對象存放到IOC容器中,而這些只是refresh方法中的其中一個步驟——obtainFreshBeanFactory,接下來就將圍繞這這些BeanDefinition對象進行一系列的處理,如BeanDefinitionRegistryPostProcessor對象方法的調用、BeanFactoryPostProcessor對象方法的調用以及Bean實例的創建都離不開這些BeanDefinition對象。下面就來看看Spring是如何處理這些對象的。
正文
環境準備
首先我們先回憶下refresh方法:
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {//為容器初始化做準備prepareRefresh();// 解析xml和注解ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// 給BeanFacory設置屬性值以及添加一些處理器,即準備Spring的上下文環境prepareBeanFactory(beanFactory);try {// 由子類實現對BeanFacoty的一些后置處理postProcessBeanFactory(beanFactory);/** BeanDefinitionRegistryPostProcessor* BeanFactoryPostProcessor* 完成對這兩個接口的調用* */invokeBeanFactoryPostProcessors(beanFactory);/** 把實現了BeanPostProcessor接口的類實例化,并且加入到BeanFactory中* */registerBeanPostProcessors(beanFactory);/** 國際化* */initMessageSource();//初始化事件管理類initApplicationEventMulticaster();//這個方法著重理解模板設計模式,因為在springboot中,這個方法是用來做內嵌tomcat啟動的onRefresh();/** 往事件管理類中注冊事件類* */registerListeners();/** 1、bean實例化過程* 2、依賴注入* 3、注解支持* 4、BeanPostProcessor的執行* 5、Aop的入口** */finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.finishRefresh();} finally {resetCommonCaches();}}}prepareBeanFactory和postProcessBeanFactory沒什么復雜的,關注一下里面設置了哪些值,添加了哪些對象就行,這些東西在后面的流程中會起到作用。尤其是postProcessBeanFactory,這是一個模板方法,在其子類AbstractRefreshableWebApplicationContext中設置了兩個重要的標識:
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {// 主要看著里面beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));beanFactory.ignoreDependencyInterface(ServletContextAware.class);beanFactory.ignoreDependencyInterface(ServletConfigAware.class);WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);}public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");// Remove from old position, if anythis.beanPostProcessors.remove(beanPostProcessor);// Track whether it is instantiation/destruction awareif (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {this.hasInstantiationAwareBeanPostProcessors = true;}if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {this.hasDestructionAwareBeanPostProcessors = true;}// Add to end of listthis.beanPostProcessors.add(beanPostProcessor);}分別將hasInstantiationAwareBeanPostProcessors、hasDestructionAwareBeanPostProcessors屬性都設置成了true,可以猜一下它們有什么作用。
兩個重要的Processor
在將上下文環境設置完成后,就是通過invokeBeanFactoryPostProcessors方法完成對BeanDefinitionRegistry以及BeanFactory的后置處理器的處理和調用,也就是依次調用BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口的實現類。我們可以通過實現這兩個接口在在BeanDefinition注冊完成后,對象實例化之前對容器中的BeanDefinition進行動態的增刪查改,比如Spring中@Configuration注解的解析就是在這個過程中實現的。我們先來了解一下Spring內置的Processor實現有哪些:
整個體系需要有個大概的印象,其中重點關注ConfigurationClassPostProcessor類,該類就是完成對@Configuration、@Bean等注解的解析注冊,這一塊的源碼這里暫時不分析。繼續開始的流程,進入到invokeBeanFactoryPostProcessors方法:
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {// getBeanFactoryPostProcessors方法一般是獲取不到值的,除非我們手動調用addBeanFactoryPostProcessor方法添加進去,// 換言之我們可以通過注解@Component或是手動調用addBeanFactoryPostProcessor方法來注入BeanFactoryPostProcessors對象PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());省略......}這里面 通過委托模式調用PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors方法,并傳入了BeanFactory和Processors對象,但需要注意getBeanFactoryPostProcessors方法不是獲取通過xml配置和Component注解注冊到容器中的Processor對象,而是獲取通過調用AbstractApplicationContext.addBeanFactoryPostProcessor方法添加的類,換言之我們實現了Processor接口后可以不在類上添加@Component,直接調用addBeanFactoryPostProcessor方法即可,但需要注意,這種方式并沒有對應的BeanDefinition類,添加的對象也不存在于IOC容器中。
繼續進入invokeBeanFactoryPostProcessors方法:
這個方法很長,但邏輯并不復雜。首先判斷傳入的BeanFactory對象是不是BeanDefinitionRegistry對象,是的話則優先調用傳入的Processor對象的postProcessBeanDefinitionRegistry方法,之后再通過beanFactory.getBeanNamesForType拿到容器中所有BeanDefinitionRegistryPostProcessor實現類的名字,然后依次實例化并調用實現了PriorityOrdered、Ordered接口(前者優先級高于后者,數字越小優先級越高)的Processor的postProcessBeanDefinitionRegistry方法,最后再實例化并調用剩余未實現排序接口的Processor的方法。當所有BeanDefinitionRegistryPostProcessor實現類調用完成后,會依次調用來自于父接口BeanFactoryPostProcessor的postProcessBeanFactory方法。
上述流程處理完成后,又會通過beanFactory.getBeanNamesForType拿到容器中所有BeanFactoryPostProcessor實現類的名字,處理流程和上面一樣。
注冊BeanPostProcessor對象
以上就是兩個擴展點的調用流程,完成之后又會調用registerBeanPostProcessors注冊所有BeanPostProcessor的子類到容器中來,這個接口也是Spring的一個重要的擴展點,它包含了兩個方法:
@Nullabledefault Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}@Nullabledefault Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}實現了該接口的對象在實例化之前和之后分別會調用這兩個方法。同樣,我們先來了解下該接口的繼承體系:
可以看到這個接口Spring內置的實現就比較多,可見用途之廣泛。另外上面畫紅框的是本次需要重點記憶的類,后面Bean實例化時會出現。接著我們來看看registerBeanPostProcessors的實現邏輯:
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {//拿到工程里面所有實現了BeanPostProcessor接口的類,獲取到BeanDefinition的名稱String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();List<String> orderedPostProcessorNames = new ArrayList<>();List<String> nonOrderedPostProcessorNames = new ArrayList<>();//提前實例化BeanPostProcessor類型的bean,然后bean進行排序for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {//getBean是實例化方法,后面我們在講bean實例化過程是會著重講到BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);priorityOrderedPostProcessors.add(pp);//判斷類型是否是MergedBeanDefinitionPostProcessor,如果是則代碼是內部使用的if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);}else {nonOrderedPostProcessorNames.add(ppName);}}// First, register the BeanPostProcessors that implement PriorityOrdered.sortPostProcessors(priorityOrderedPostProcessors, beanFactory);//注冊到BeanFactory中registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);// Next, register the BeanPostProcessors that implement Ordered.List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();for (String ppName : orderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);orderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}sortPostProcessors(orderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, orderedPostProcessors);// Now, register all regular BeanPostProcessors.List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();for (String ppName : nonOrderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);nonOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);// Finally, re-register all internal BeanPostProcessors.sortPostProcessors(internalPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, internalPostProcessors);// Re-register post-processor for detecting inner beans as ApplicationListeners,// moving it to the end of the processor chain (for picking up proxies etc).beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));}這段代碼的實現邏輯也很簡單,也是先區分優先級,再獲取Bean實例,最后注冊到容器中,等到Bean實例化時調用。
接下來在refresh方法中調用了initMessageSource、initApplicationEventMulticaster、onRefresh、registerListeners,分別是初始化國際化資源、初始化時間廣播器、容器刷新事件(子類回調)、注冊監聽器,這幾個方法都很簡單,自己看看就行,這里就不詳細闡述了。
Bean對象的創建
當所有的準備工作都做好后,就該開始初始化Bean實例了,也就是finishBeanFactoryInitialization方法所做的事。不過這里可不是根據BeanDefinition new一個對象就完了,它包含了以下幾個工作:
- 初始化實例
- 解析@PostConstruct,@PreDestroy,@Resource, @Autowired,@Value等注解
- 依賴注入
- 調用BeanPostProcessor方法
- AOP入口(本篇暫不分析)
下面就來詳細分析Bean實例化的整個流程:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {......//重點看這個方法// Instantiate all remaining (non-lazy-init) singletons.beanFactory.preInstantiateSingletons();}public void preInstantiateSingletons() throws BeansException {if (logger.isTraceEnabled()) {logger.trace("Pre-instantiating singletons in " + this);}// Iterate over a copy to allow for init methods which in turn register new bean definitions.// While this may not be part of the regular factory bootstrap, it does otherwise work fine.// xml解析時,講過,把所有beanName都緩存到beanDefinitionNames了List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);// Trigger initialization of all non-lazy singleton beans...for (String beanName : beanNames) {// 把父BeanDefinition里面的屬性拿到子BeanDefinition中RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);//如果不是抽象的,單例的,非懶加載的就實例化if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {//判斷bean是否實現了FactoryBean接口,這里可以不看if (isFactoryBean(beanName)) {Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);if (bean instanceof FactoryBean) {final FactoryBean<?> factory = (FactoryBean<?>) bean;boolean isEagerInit;if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)((SmartFactoryBean<?>) factory)::isEagerInit,getAccessControlContext());}else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean<?>) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}}else {//主要從這里進入,看看實例化過程getBean(beanName);}}}}在preInstantiateSingletons方法中可以看到這里有一個判斷:單例、非懶加載、非抽象,滿足這三個條件才會調用getBean(Bean實例化都是通過調用該方法實現的)實例化:
public Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);}protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {final String beanName = transformedBeanName(name);System.out.println("====beanName=="+beanName+"===instance begin====");Object bean;//從緩存中拿實例Object sharedInstance = getSingleton(beanName);//如果緩存里面能拿到實例if (sharedInstance != null && args == null) {// 該方法是FactoryBean接口的調用入口bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);}else {//如果緩存里面沒有,則走下來//如果是scope 是Prototype的,校驗是否有出現循環依賴,如果有則直接報錯if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}BeanFactory parentBeanFactory = getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {// Not found -> check parent.String nameToLookup = originalBeanName(name);if (parentBeanFactory instanceof AbstractBeanFactory) {return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);}else if (args != null) {// Delegation to parent with explicit args.return (T) parentBeanFactory.getBean(nameToLookup, args);}else if (requiredType != null) {// No args -> delegate to standard getBean method.return parentBeanFactory.getBean(nameToLookup, requiredType);}else {return (T) parentBeanFactory.getBean(nameToLookup);}}if (!typeCheckOnly) {markBeanAsCreated(beanName);}try {// 父子BeanDefinition合并final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);// 檢驗是不是抽象類,是直接拋出異常checkMergedBeanDefinition(mbd, beanName, args);// 獲取依賴對象屬性,依賴對象要先實例化// Guarantee initialization of beans that the current bean depends on.String[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {for (String dep : dependsOn) {if (isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");}registerDependentBean(dep, beanName);try {//實例化getBean(dep);}catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"'" + beanName + "' depends on missing bean '" + dep + "'", ex);}}}//大部分是單例的情況if (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, () -> {try {return createBean(beanName, mbd, args);}});// 該方法是FactoryBean接口的調用入口bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}else if (mbd.isPrototype()) {// It's a prototype -> create a new instance.Object prototypeInstance = null;try {beforePrototypeCreation(beanName);prototypeInstance = createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}// 該方法是FactoryBean接口的調用入口bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);}else {String scopeName = mbd.getScope();final Scope scope = this.scopes.get(scopeName);if (scope == null) {throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");}try {Object scopedInstance = scope.get(beanName, () -> {beforePrototypeCreation(beanName);try {return createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}});// 該方法是FactoryBean接口的調用入口bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);}}}}return (T) bean;}這段代碼首先從緩存里面拿到單例對象,如果沒有,則通過scope類型去創建對應的Bean實例(直接創建或是通過getObjectForBeanInstance調用FactoryBean接口的方法創建)。在創建對象之前如果scope是prototype類型的首先會通過isPrototypeCurrentlyInCreation檢驗是否存在循環依賴(循環依賴這里先不講),存在直接拋出異常,原型對象不允許有循環依賴出現;校驗完成后還會通過mbd.getDependsOn拿到@DependsOn注解的值,如果有,則會優先實例化依賴的對象。
因為大部分都是創建單例對象,所以下面我以getSingleton方法來分析,需要注意該方法傳入了一個Lambda表達式,在該表達式中調用了createBean方法,觀察其它scope創建bean會發現都調用了該方法,所以實際創建bean對象就是該方法,不過我們還是先進入getSingleton方法看看做了些什么:
這個方法里面首先是從緩存中獲取對象,如果有直接返回,如果沒有則將該對象的beanName加入到singletonsCurrentlyInCreation緩存中,如果添加不成功,說明已經有其它地方正在創建該對象,當前創建直接拋出異常,如果添加成功,則調用singletonFactory.getObject去創建對象,這個方法就是傳入的Lambda表達式,創建完成后刪除掉singletonsCurrentlyInCreation緩存中的值并將對象添加到一級緩存,后續需要該對象時,都是從一級緩存中獲取的。
在getObject中通過createBean去創建對象,而該方法又調用了doCreateBean,我們直接來看這個方法:
這個方法里面首先去通過createBeanInstance創建對象的實例,創建完成后又通過applyMergedBeanDefinitionPostProcessors收集類中的注解@Autowired、@Value、@PostConstruct,@PreDestroy,@Resource準備依賴注入或是方法調用,緊接著調用addSingletonFactory添加三級緩存處理循環依賴,之后通過populateBean依賴注入真正完成一個完整對象的創建,最后在initializeBean中觸發事件和一些方法的調用。下面逐個分析這些方法。
createBeanInstance
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {// Make sure bean class is actually resolved at this point.//反射拿到Class對象Class<?> beanClass = resolveBeanClass(mbd, beanName);if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());}Supplier<?> instanceSupplier = mbd.getInstanceSupplier();if (instanceSupplier != null) {return obtainFromSupplier(instanceSupplier, beanName);}// 在xml配置bean時指定factory-bean屬性和factory-method以及@Bean注解if (mbd.getFactoryMethodName() != null) {return instantiateUsingFactoryMethod(beanName, mbd, args);}// Candidate constructors for autowiring?//尋找當前正在實例化的bean中有@Autowired注解的構造函數Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {//如果ctors不為空,就說明構造函數上有@Autowired注解return autowireConstructor(beanName, mbd, ctors, args);}// Preferred constructors for default construction?ctors = mbd.getPreferredConstructors();if (ctors != null) {return autowireConstructor(beanName, mbd, ctors, null);}//無參構造函數的實例化,大部分的實例是采用的無參構造函數的方式實例化// No special handling: simply use no-arg constructor.return instantiateBean(beanName, mbd);}在這個方法里面又做了很多判斷,首先是拿到factoryMethodName,當我們在xml配置bean時指定了factory-bean屬性和factory-method屬性或者是使用了@Bean注解時這里就會拿到值,然后就會通過FactoryMethod去創建一個實例對象;如果不存在factoryMethodName,那么就需要通過構造函數來實例化對象,但構造函數上可能存在注解@Autowired,因此需要通過determineConstructorsFromBeanPostProcessors獲取到所有帶@Autowired注解的構造函數:
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)throws BeansException {/*** 通過AutowiredAnnotationBeanPostProcessor(在component-scan解析時* 通過registerComponents方法注冊的,然后又在refresh中調用registerBeanPostProcessors方法* 實例化的)類找到標記了@Autowired注解的構造函數*/if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);if (ctors != null) {return ctors;}}}}return null;}拿到所有帶@Autowired注解的構造函數后就是通過調用autowireConstructor來進行實例化,具體則是通過委托給ConstructorResolver類進行處理,包括上面通過factoryMethod創建對象也是委托給這個類。如果沒有帶@Autowired的構造函數才會調用instantiateBean方法,利用反射通過無參構造函數去創建對象并返回,也是大部分對象實例化所走的流程。至此,簡單對象的實例化完成。
addSingletonFactory
這個方法就是添加三級緩存解決循環依賴問題,暫時不分析。
populateBean
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {boolean continueWithPropertyPopulation = true;// 這里可以寫接口可以讓所有類都不能依賴注入,沒有什么實際作用if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {//是否需要DI,依賴注入continueWithPropertyPopulation = false;break;}}}}if (!continueWithPropertyPopulation) {return;}PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {MutablePropertyValues newPvs = new MutablePropertyValues(pvs);// Add property values based on autowire by name if applicable.if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {autowireByName(beanName, mbd, bw, newPvs);}// Add property values based on autowire by type if applicable.if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {autowireByType(beanName, mbd, bw, newPvs);}pvs = newPvs;}boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);PropertyDescriptor[] filteredPds = null;//重點看這個if代碼塊if (hasInstAwareBpps) {if (pvs == null) {pvs = mbd.getPropertyValues();}for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;//依賴注入過程,@Autowired的支持PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);if (pvsToUse == null) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}//老版本用這個完成依賴注入過程,@Autowired的支持pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);if (pvsToUse == null) {return;}}pvs = pvsToUse;}}}if (needsDepCheck) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}checkDependencies(beanName, mbd, filteredPds, pvs);}// xml中<property>標簽的依賴注入if (pvs != null) {applyPropertyValues(beanName, mbd, bw, pvs);}}這里面主要有三個方法是完成依賴注入的:postProcessProperties(當前主要使用)、postProcessPropertyValues(老版本廢棄API)、applyPropertyValues(xml中property標簽)。所以主要看看postProcessProperties方法,而這個方法又是來自于InstantiationAwareBeanPostProcessor接口(希望你還記得這個接口的繼承體系),主要看看AutowiredAnnotationBeanPostProcessor,這個就是解決@Autowired依賴注入的。
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);try {metadata.inject(bean, beanName, pvs);}return pvs;}見名知意,findAutowiringMetadata方法就是拿到@Autowired注解的屬性并封裝為InjectionMetadata對象,再調用inject進行依賴注入,注意這里是包含了屬性和方法的(方法也不一定是setter方法才可以,只要是標記了@Autowired且參數類型正確都能依賴成功)。這就是@Autowired的注入過程,另外還有@Resource的注入,在CommonAnnotationBeanPostProcessor類中,流程和這個基本一樣,這里就不闡述了。
initializeBean
以上過程都是對Bean的實例化,以及對象中屬性的注入,都完成過后這個Bean對象才是我們真正可以直接使用的對象,所以接著就是處理一些方法的調用了(包含一些事件通知)。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {invokeAwareMethods(beanName, bean);return null;}, getAccessControlContext());}else {// 調用Aware方法invokeAwareMethods(beanName, bean);}Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {//對類中某些特殊方法的調用,比如@PostConstruct,Aware接口wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {//InitializingBean接口,afterPropertiesSet,init-method屬性調用,非常重要invokeInitMethods(beanName, wrappedBean, mbd);}if (mbd == null || !mbd.isSynthetic()) {// 這個地方可能生出代理實例,是aop的入口wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;}private void invokeAwareMethods(final String beanName, final Object bean) {if (bean instanceof Aware) {// 實現該接口可以在bean實例化完成后獲取到bean的名稱if (bean instanceof BeanNameAware) {((BeanNameAware) bean).setBeanName(beanName);}// 實現該接口可以在bean實例化完成后獲取到當前的類加載器if (bean instanceof BeanClassLoaderAware) {ClassLoader bcl = getBeanClassLoader();if (bcl != null) {((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);}}// 實現該接口可以在bean實例化完成后獲取到當前的AbstractAutowireCapableBeanFactory對象if (bean instanceof BeanFactoryAware) {((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);}}}首先是Aware接口的方法調用,這個很簡單不多說。接著就是applyBeanPostProcessorsBeforeInitialization方法調用,這個就是BeanPostProcessor接口的postProcessBeforeInitialization方法調用(看到這里你是否會發現自己之前理解錯了呢,因為該方法是在對象實例化之前調用,實際上也是實例化完成之后):
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;for (BeanPostProcessor processor : getBeanPostProcessors()) {Object current = processor.postProcessBeforeInitialization(result, beanName);if (current == null) {return result;}result = current;}return result;}這里面著重看幾個實現類的調用:ApplicationContextAwareProcessor(ApplicationEventPublisherAware、ApplicationContextAware等Aware接口的調用)、InitDestroyAnnotationBeanPostProcessor(@PostConstruct注解方法的調用)、ImportAwareBeanPostProcessor(ImportAware類型實例setImportMetadata調用,對理解SpringBoot幫助很大,這里可以暫時不看)。
緊著著又通過invokeInitMethods方法調用InitializingBean接口的afterPropertiesSet方法以及init-method屬性配置的自定義初始化方法。
最后則是通過applyBeanPostProcessorsAfterInitialization方法調用BeanPostProcessor的postProcessAfterInitialization方法,因為涉及到AOP知識,這里不詳細分析。
至此,Bean的整個實例化過程分析完成,看到這里,你應該對于Bean的生命周期函數有個基本的認識了,最后放上我畫的Bean實例化流程時序圖:
總結
本篇篇幅很長,中間很多無關痛癢的代碼我都省略掉了,也有一些無關主流程但也比較重要的代碼沒有分析,比如ConfigurationClassPostProcessor解析@Configuration、@Bean注解的過程,FactoryMethod創建對象過程、獲取@Autowired注解標記的構造函數以及通過這些構造函數實例化過程我都沒有分析,一來是限于篇幅過長,二來主要是因為對理解整個流程并沒有太大作用并且代碼相對更簡單,感興趣的讀者可在理解清楚主流程后自行分析。
作者:夜勿語原文鏈接:https://blog.csdn.net/l6108003/article/details/106439525
總結
以上是生活随笔為你收集整理的异常将上下文初始化事件发送到类的侦听器实例_Spring的Bean实例化原理,这一次彻底搞懂了!...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php 类似微信下拉菜单,微信小程序模拟
- 下一篇: l2-008 最长对称子串 (25分)_