Spring創(chuàng)建Bean的過(guò)程Debug的詳細(xì)流程
Spring流程Debug
1.1 Spring測(cè)試環(huán)境搭建
Spring模塊概覽,綠色是模塊,Spring中八大模塊,黑色表示該模塊包含的jar包(組件)。例如我們想要用IOC容器,也就是綠色的CoreContainer,我們需要導(dǎo)入Beans,Core,Context,SpEL(spring-expression)四個(gè)包。
- Test:測(cè)試相關(guān)
- Core Container:IOC容器
- AOP:面向切面編程
- Aspects:切面
- Instrumenttation:跟JDK關(guān)聯(lián),一般不用
- Messaging:消息服務(wù),一般不用
- Data Access/Integration:數(shù)據(jù)訪問(wèn)與集成(JDBC訪問(wèn),Transaction事務(wù),ORM對(duì)象關(guān)系映射,OXM和XML映射一般不用,JMS為Java消息服務(wù)Java-message-service一般不用)
- Web:Web服務(wù)(WebSocket網(wǎng)絡(luò)通信協(xié)議,Servlet, Web,Portlet一般不用)
最偷懶的方式,是直接導(dǎo)入Spring-Framework。但是可能導(dǎo)入不必要的包,導(dǎo)致項(xiàng)目打包后比較大
由于Spring-Content中的ApplicationContent是整個(gè)IOC的入口。我們導(dǎo)入Spring-context包即可
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.3.RELEASE</version> </dependency>
我們導(dǎo)入spring-content后,默認(rèn)會(huì)導(dǎo)入該組件的依賴(lài)jar,spring-content底層的依賴(lài)可以看到,實(shí)際上我們是導(dǎo)入了Core Container模塊:
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.2.3.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.2.3.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.2.3.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>5.2.3.RELEASE</version> <scope>compile</scope> </dependency> </dependencies>
新建Spring配置文件spring.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--注冊(cè)一個(gè)對(duì)象,spring回自動(dòng)創(chuàng)建這個(gè)對(duì)象--> <!-- 一個(gè)bean標(biāo)簽就表示一個(gè)對(duì)象 id:這個(gè)對(duì)象的唯一標(biāo)識(shí) class:注冊(cè)對(duì)象的完全限定名 --> <bean id="hello" class="com.xiaodai.service.Hello"> <!--使用property標(biāo)簽給對(duì)象的屬性賦值 name:表示屬性的名稱(chēng) value:表示屬性的值 --> <property name="id" value="1"></property> <property name="name" value="zhangsan"></property> <property name="age" value="18"></property> </bean> </beans>
編寫(xiě)測(cè)試類(lèi):
import com.xiaodai.service.Hello; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml"); Hello hello = applicationContext.getBean("hello", Hello.class); System.out.println(hello.getName()); } }
1.2 Debug容器創(chuàng)建過(guò)程
從測(cè)試類(lèi)的new ClassPathXmlApplicationContext("spring.xml")開(kāi)始debug,進(jìn)入ClassPathXmlApplicationContext,可以看到:
public ClassPathXmlApplicationContext( String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException { super(parent); // 設(shè)置配置文件路徑 setConfigLocations(configLocations); if (refresh) { // 核心步驟 refresh(); } }
加載配置文件后,進(jìn)入refresh()方法,該方法是容器初始化的核心步驟。該方法包含十三個(gè)方法:
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. /** * 準(zhǔn)備刷新,做一些最基本的準(zhǔn)備化工作 **/ prepareRefresh(); // Tell the subclass to refresh the internal bean factory. /** * 獲得一個(gè)刷新的bean容器,實(shí)質(zhì)就是獲取工廠。 * 加載xml等配置文件,用該文件產(chǎn)生的BeanDefinition來(lái)創(chuàng)建一個(gè)工廠 **/ ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. /** * 準(zhǔn)備bean工廠 **/ prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. // 后置增強(qiáng),方便擴(kuò)展 postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. // 實(shí)例化并且執(zhí)行BeanFactoryPostProcessors invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. // 實(shí)例化并且注冊(cè)所有的BeanPostProcessor registerBeanPostProcessors(beanFactory); // Initialize message source for this context. // 國(guó)際化設(shè)置,一般用不到 initMessageSource(); // Initialize event multicaster for this context. // 初始化應(yīng)用程序的多波器和廣播器 initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. // 空方法,預(yù)留給子類(lèi)做擴(kuò)展 onRefresh(); // Check for listener beans and register them. // 注冊(cè)監(jiān)聽(tīng)器 registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. // 工作中常用,面試常問(wèn)。實(shí)例化所有非懶加載的實(shí)例對(duì)象 finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. // 完成刷新 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
1.3 AbstractApplicationContext的refresh()包含的13個(gè)方法分析
結(jié)合概覽圖一個(gè)一個(gè)方法分析:
方法1:prepareRefresh() => 準(zhǔn)備工作
準(zhǔn)備刷新,做一些最基本的準(zhǔn)備化工作
protected void prepareRefresh() { // Switch to active. // 設(shè)置開(kāi)始時(shí)間 this.startupDate = System.currentTimeMillis(); // 關(guān)閉狀態(tài)設(shè)置為false this.closed.set(false); // 活躍狀態(tài)設(shè)置為true this.active.set(true); // 打印日志 if (logger.isDebugEnabled()) { if (logger.isTraceEnabled()) { logger.trace("Refreshing " + this); } else { logger.debug("Refreshing " + getDisplayName()); } } // Initialize any placeholder property sources in the context environment. // 初始化屬性資源 initPropertySources(); // Validate that all properties marked as required are resolvable: // see ConfigurablePropertyResolver#setRequiredProperties // 獲取環(huán)境信息,驗(yàn)證屬性信息 getEnvironment().validateRequiredProperties(); // Store pre-refresh // 存儲(chǔ)預(yù)刷新的一些應(yīng)用信息的監(jiān)聽(tīng)器 ApplicationListeners... if (this.earlyApplicationListeners == null) { this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners); } else { // Reset local application listeners to pre-refresh state. this.applicationListeners.clear(); this.applicationListeners.addAll(this.earlyApplicationListeners); } // Allow for the collection of early ApplicationEvents, // to be published once the multicaster is available... // 創(chuàng)建一些監(jiān)聽(tīng)器事件的集合 this.earlyApplicationEvents = new LinkedHashSet<>(); }
總結(jié):
1.設(shè)置啟動(dòng)事件
2.設(shè)置關(guān)閉活躍的狀態(tài)
3.獲取環(huán)境對(duì)象并設(shè)置屬性值
4.設(shè)置監(jiān)聽(tīng)器以及需要發(fā)布事件的集合
重要的點(diǎn):
- 獲取環(huán)境信息,驗(yàn)證屬性信息,getEnvironment().validateRequiredProperties();
- 存儲(chǔ)預(yù)刷新的一些應(yīng)用信息的監(jiān)聽(tīng)器,在Spring中是空實(shí)現(xiàn),但是SpringBoot中,是有具體的值的
方法2:obtainFreshBeanFactory() => 獲得一個(gè)刷新的bean容器
獲得一個(gè)刷新的bean容器,實(shí)質(zhì)就是獲取工廠。創(chuàng)建容器對(duì)象DefaultListableBeanFactory;加載xml配置文件的屬性到當(dāng)前的工廠中,最重要的就是BeanDefinition
AbstractRefreshableApplicationContext:
// 只要進(jìn)到這個(gè)方法,那么我們創(chuàng)建的一定是一個(gè)新的工廠 @Override protected final void refreshBeanFactory() throws BeansException { if (hasBeanFactory()) { // 如果存在先銷(xiāo)毀,后關(guān)閉 destroyBeans(); closeBeanFactory(); } try { // 創(chuàng)建bean工廠,這里使用的就是DefaultListableBeanFactory。此時(shí)創(chuàng)建的工廠里面的屬性值都是默認(rèn)值 DefaultListableBeanFactory beanFactory = createBeanFactory(); // 序列化id beanFactory.setSerializationId(getId()); // 設(shè)置一些屬性值 customizeBeanFactory(beanFactory); // 加載bean的定義屬性值。該方法有很多重載,非常復(fù)雜,核心是do操作 // 完成配置文件或者配置類(lèi)文件的加載 loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }
方法3:prepareBeanFactory(beanFactory) => 準(zhǔn)備(初始化)Bean工廠
為方法2拿到的工廠,設(shè)置某些具體的值
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // Tell the internal bean factory to use the context's class loader etc. // 為bean工廠設(shè)置類(lèi)加載器 beanFactory.setBeanClassLoader(getClassLoader()); // 設(shè)置SPEL解析器 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // Configure the bean factory with context callbacks. // 添加一個(gè)BeanPostProcessor beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); // 忽略對(duì)應(yīng)接口的實(shí)現(xiàn) beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); // BeanFactory interface not registered as resolvable type in a plain factory. // MessageSource registered (and found for autowiring) as a bean. // 注冊(cè)一些依賴(lài) beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); // Register early post-processor for detecting inner beans as // ApplicationListeners添加一個(gè)BeanPostProcessor增強(qiáng)器 ApplicationListeners. beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // Detect a LoadTimeWeaver and prepare for weaving, if found. if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); // Set a temporary ClassLoader for type matching. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } // Register default environment beans. if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } }
方法4:postProcessBeanFactory(beanFactory) => 后置增強(qiáng)Bean(擴(kuò)展實(shí)現(xiàn))
空方法,方便擴(kuò)展
方法5:invokeBeanFactoryPostProcessors(beanFactory) => 執(zhí)行BFPP
實(shí)例化并且執(zhí)行BeanFactoryPostProcessors
/** * Instantiate and invoke all registered BeanFactoryPostProcessor beans, * respecting explicit order if given. * <p>Must be called before singleton instantiation. * 單例對(duì)象之前一定調(diào)用,因?yàn)閱卫齜ean創(chuàng)建后就只有一份 */ protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor) if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }
方法6:registerBeanPostProcessors(beanFactory) => 注冊(cè)BPP
實(shí)例化并且注冊(cè)所有的BeanPostProcessor。實(shí)例化Bean之前的準(zhǔn)備工作
/** * Instantiate and register all BeanPostProcessor beans, * respecting explicit order if given. * <p>Must be called before any instantiation of application beans. */ protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); }
方法7:initMessageSource() => 國(guó)際化設(shè)置
方法8:initApplicationEventMulticaster() => 初始化應(yīng)用程序的多波器和廣播器
也屬于準(zhǔn)備工作
方法9:onRefresh() => 預(yù)留給子類(lèi)做擴(kuò)展
空方法
方法10:registerListeners() => 注冊(cè)監(jiān)聽(tīng)器
也屬于準(zhǔn)備工作
/** * Add beans that implement ApplicationListener as listeners. * Doesn't affect other listeners, which can be added without being beans. */ protected void registerListeners() { // Register statically specified listeners first. for (ApplicationListener<?> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let post-processors apply to them! String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } // Publish early application events now that we finally have a multicaster... Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }
方法11:finishBeanFactoryInitialization(beanFactory) => 實(shí)例化所有單例對(duì)象
面試常問(wèn),工作常用。過(guò)程比較復(fù)雜
/** * Finish the initialization of this context's bean factory, * initializing all remaining singleton beans. */ protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Initialize conversion service for this context. /** * 把類(lèi)型轉(zhuǎn)化操作,設(shè)置到當(dāng)前的beanFactory里面去 **/ if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } // Register a default embedded value resolver if no bean post-processor // (such as a PropertyPlaceholderConfigurer bean) registered any before: // at this point, primarily for resolution in annotation attribute values. /** * 判斷當(dāng)前的beanFactory有沒(méi)有內(nèi)置的值處理器 **/ if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. /** * 織入Aware **/ String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } // Stop using the temporary ClassLoader for type matching. // 設(shè)置類(lèi)加載器 beanFactory.setTempClassLoader(null); // Allow for caching all bean definition metadata, not expecting further changes. /** * 凍結(jié):某些bean不需要進(jìn)行修改操作了,放入 **/ beanFactory.freezeConfiguration(); // Instantiate all remaining (non-lazy-init) singletons. /** * 實(shí)例化所有非懶加載的實(shí)例對(duì)象(重要) **/ beanFactory.preInstantiateSingletons(); }
實(shí)例化所有非懶加載的實(shí)例對(duì)象方法:
@Override 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. /** * 拿到所有注冊(cè)bean的名稱(chēng) **/ List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... // 循環(huán)去創(chuàng)建我們需要的單例對(duì)象 for (String beanName : beanNames) { // 拿到bean的定義信息,就是我們?cè)趚ml配置文件里面指定的一些屬性 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); // 是否是抽象的,是否是單例的,是否是懶加載的 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { // 判斷當(dāng)前類(lèi)是否實(shí)現(xiàn)了factoryBean接口。一般沒(méi)實(shí)現(xiàn),直接進(jìn)入下面的getBean 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 { // 通過(guò)beanName。拿到bean getBean(beanName); } } } // Trigger post-initialization callback for all applicable beans... for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { smartSingleton.afterSingletonsInstantiated(); return null; }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } } }
重要方法:
getMergedLocalBeanDefinition
/** * Return a merged RootBeanDefinition, traversing the parent bean definition * if the specified bean corresponds to a child bean definition. * @param beanName the name of the bean to retrieve the merged definition for * @return a (potentially merged) RootBeanDefinition for the given bean * @throws NoSuchBeanDefinitionException if there is no bean with the given name * @throws BeanDefinitionStoreException in case of an invalid bean definition */ // 返回一個(gè)合并好的RootBeanDefinition。整合子類(lèi)和父類(lèi) protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException { // Quick check on the concurrent map first, with minimal locking. RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName); if (mbd != null && !mbd.stale) { return mbd; } return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); }
getBean() => doGetBean()
/** * Return an instance, which may be shared or independent, of the specified bean. * @param name the name of the bean to retrieve * @param requiredType the required type of the bean to retrieve * @param args arguments to use when creating a bean instance using explicit arguments * (only applied when creating a new instance as opposed to retrieving an existing one) * @param typeCheckOnly whether the instance is obtained for a type check, * not for actual use * @return an instance of the bean * @throws BeansException if the bean could not be created */ @SuppressWarnings("unchecked") protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { // 獲取beanName final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. // 單例檢查,如果一級(jí),二級(jí),三級(jí)緩存中存在該Bean,直接獲取到了 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isTraceEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.trace("Returning cached instance of singleton bean '" + beanName + "'"); } } bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference. // 如果是單例對(duì)象的話,嘗試解決循環(huán)依賴(lài)問(wèn)題 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. // 獲取父類(lèi)容器 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); } } // 標(biāo)志位。如果不是類(lèi)型檢查,表示要?jiǎng)?chuàng)建bean,此處在集合中做一個(gè)記錄 if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { // 獲取beanDefinition final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); // 檢測(cè)beanDefinition checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. // 檢查當(dāng)前的bean是否有其他依賴(lài)的bean String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { // 如果有依賴(lài)的bean,我們要先遞歸解決其他依賴(lài)的bean 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); } } } // Create bean instance. // 是否是單例的 if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); throw ex; } }); 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); } 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); } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " + "defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex); } } } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } // Check if required type matches the type of the actual bean instance. if (requiredType != null && !requiredType.isInstance(bean)) { try { T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return convertedBean; } catch (TypeMismatchException ex) { if (logger.isTraceEnabled()) { logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; }
getSingleton
/** * Return the (raw) singleton object registered under the given name, * creating and registering a new one if none registered yet. * @param beanName the name of the bean * @param singletonFactory the ObjectFactory to lazily create the singleton * with, if necessary * @return the registered singleton object */ public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); synchronized (this.singletonObjects) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { if (this.singletonsCurrentlyInDestruction) { throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction " + "(Do not request a bean from a BeanFactory in a destroy method implementation!)"); } if (logger.isDebugEnabled()) { logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); } beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try { // 實(shí)際上就是調(diào)用了CreateBean singletonObject = singletonFactory.getObject(); newSingleton = true; } catch (IllegalStateException ex) { // Has the singleton object implicitly appeared in the meantime -> // if yes, proceed with it since the exception indicates that state. singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { throw ex; } } catch (BeanCreationException ex) { if (recordSuppressedExceptions) { for (Exception suppressedException : this.suppressedExceptions) { ex.addRelatedCause(suppressedException); } } throw ex; } finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } afterSingletonCreation(beanName); } if (newSingleton) { addSingleton(beanName, singletonObject); } } return singletonObject; } }
doCreateBean => 通過(guò)上方法的singletonObject = singletonFactory.getObject();進(jìn)入的
/** * Actually create the specified bean. Pre-creation processing has already happened * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks. * <p>Differentiates between default bean instantiation, use of a * factory method, and autowiring a constructor. * @param beanName the name of the bean * @param mbd the merged bean definition for the bean * @param args explicit arguments to use for constructor or factory method invocation * @return a new instance of the bean * @throws BeanCreationException if the bean could not be created * @see #instantiateBean * @see #instantiateUsingFactoryMethod * @see #autowireConstructor */ protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { /** * 核心的創(chuàng)建實(shí)例化Bean的過(guò)程 **/ instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } } // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); /** * 解決循環(huán)依賴(lài)。使用三級(jí)緩存 **/ if (earlySingletonExposure) { if (logger.isTraceEnabled()) { logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. Object exposedObject = bean; try { /** * 填充屬性,上文的實(shí)例化只是默認(rèn)屬性值。填充屬性是初始化的第一步,第二步是執(zhí)行init方法 **/ populateBean(beanName, mbd, instanceWrapper); /** * 執(zhí)行init方法 **/ exposedObject = initializeBean(beanName, exposedObject, mbd); } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); } } if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. try { /** * 需要銷(xiāo)毀的時(shí)候,銷(xiāo)毀的鉤子函數(shù) **/ registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
面試題:為甚么循環(huán)依賴(lài)的解決要使用三級(jí)緩存?
createBeanInstance => 核心的創(chuàng)建和實(shí)例化bean的過(guò)程,由doCreateBean調(diào)用
大量的反射出現(xiàn)在該方法中,用來(lái)創(chuàng)建對(duì)象
/** * Create a new instance for the specified bean, using an appropriate instantiation strategy: * factory method, constructor autowiring, or simple instantiation. * @param beanName the name of the bean * @param mbd the bean definition for the bean * @param args explicit arguments to use for constructor or factory method invocation * @return a BeanWrapper for the new instance * @see #obtainFromSupplier * @see #instantiateUsingFactoryMethod * @see #autowireConstructor * @see #instantiateBean */ protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { // Make sure bean class is actually resolved at this point. 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); } if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } // Shortcut when re-creating the same bean... boolean resolved = false; boolean autowireNecessary = false; if (args == null) { synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; autowireNecessary = mbd.constructorArgumentsResolved; } } } if (resolved) { if (autowireNecessary) { return autowireConstructor(beanName, mbd, null, null); } else { return instantiateBean(beanName, mbd); } } // Candidate constructors for autowiring? // 構(gòu)造器 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { 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. /** * 默認(rèn)無(wú)參構(gòu)造 **/ return instantiateBean(beanName, mbd); }
instantiateBean(beanName, mbd) => 默認(rèn)無(wú)參構(gòu)造
/** * Instantiate the given bean using its default constructor. * @param beanName the name of the bean * @param mbd the bean definition for the bean * @return a BeanWrapper for the new instance */ protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) { try { Object beanInstance; final BeanFactory parent = this; if (System.getSecurityManager() != null) { beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () -> // 實(shí)例化只會(huì)分配內(nèi)存空間,設(shè)置默認(rèn)值 getInstantiationStrategy().instantiate(mbd, beanName, parent), getAccessControlContext()); } else { beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent); } BeanWrapper bw = new BeanWrapperImpl(beanInstance); initBeanWrapper(bw); return bw; } catch (Throwable ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex); } }
instantiate
@Override public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) { // Don't override the class with CGLIB if no overrides. if (!bd.hasMethodOverrides()) { Constructor<?> constructorToUse; synchronized (bd.constructorArgumentLock) { constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod; if (constructorToUse == null) { final Class<?> clazz = bd.getBeanClass(); if (clazz.isInterface()) { throw new BeanInstantiationException(clazz, "Specified class is an interface"); } try { if (System.getSecurityManager() != null) { constructorToUse = AccessController.doPrivileged( (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor); } else { constructorToUse = clazz.getDeclaredConstructor(); } bd.resolvedConstructorOrFactoryMethod = constructorToUse; } catch (Throwable ex) { throw new BeanInstantiationException(clazz, "No default constructor found", ex); } } } return BeanUtils.instantiateClass(constructorToUse); } else { // Must generate CGLIB subclass. return instantiateWithMethodInjection(bd, beanName, owner); } }
BeanUtils.instantiateClass => 通過(guò)構(gòu)造器反射創(chuàng)建bean
/** * Convenience method to instantiate a class using the given constructor. * <p>Note that this method tries to set the constructor accessible if given a * non-accessible (that is, non-public) constructor, and supports Kotlin classes * with optional parameters and default values. * @param ctor the constructor to instantiate * @param args the constructor arguments to apply (use {@code null} for an unspecified * parameter, Kotlin optional parameters and Java primitive types are supported) * @return the new instance * @throws BeanInstantiationException if the bean cannot be instantiated * @see Constructor#newInstance */ public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException { Assert.notNull(ctor, "Constructor must not be null"); try { ReflectionUtils.makeAccessible(ctor); if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) { return KotlinDelegate.instantiateClass(ctor, args); } else { Class<?>[] parameterTypes = ctor.getParameterTypes(); Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters"); Object[] argsWithDefaultValues = new Object[args.length]; for (int i = 0 ; i < args.length; i++) { if (args[i] == null) { Class<?> parameterType = parameterTypes[i]; argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null); } else { argsWithDefaultValues[i] = args[i]; } } return ctor.newInstance(argsWithDefaultValues); } } catch (InstantiationException ex) { throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex); } catch (IllegalAccessException ex) { throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex); } catch (IllegalArgumentException ex) { throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex); } catch (InvocationTargetException ex) { throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException()); } }
方法12:finishRefresh() => 完成刷新
/** * Finish the refresh of this context, invoking the LifecycleProcessor's * onRefresh() method and publishing the * {@link org.springframework.context.event.ContextRefreshedEvent}. */ protected void finishRefresh() { // Clear context-level resource caches (such as ASM metadata from scanning). // clearResourceCaches(); // Initialize lifecycle processor for this context. initLifecycleProcessor(); // Propagate refresh to lifecycle processor first. getLifecycleProcessor().onRefresh(); // Publish the final event. publishEvent(new ContextRefreshedEvent(this)); // Participate in LiveBeansView MBean, if active. LiveBeansView.registerApplicationContext(this); }
方法13:resetCommonCaches() => 緩存重置
/** * Reset Spring's common reflection metadata caches, in particular the * {@link ReflectionUtils}, {@link AnnotationUtils}, {@link ResolvableType} * and {@link CachedIntrospectionResults} caches. * @since 4.2 * @see ReflectionUtils#clearCache() * @see AnnotationUtils#clearCache() * @see ResolvableType#clearCache() * @see CachedIntrospectionResults#clearClassLoader(ClassLoader) */ protected void resetCommonCaches() { ReflectionUtils.clearCache(); AnnotationUtils.clearCache(); ResolvableType.clearCache(); CachedIntrospectionResults.clearClassLoader(getClassLoader()); }
最后回顧整個(gè)流程概覽圖:
到此這篇關(guān)于Spring創(chuàng)建Bean的過(guò)程Debug的文章就介紹到這了,更多相關(guān)Spring創(chuàng)建Bean的過(guò)程Debug內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot實(shí)戰(zhàn)之高效使用枚舉參數(shù)(原理篇)案例詳解
這篇文章主要介紹了SpringBoot實(shí)戰(zhàn)之高效使用枚舉參數(shù)(原理篇)案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-09-09Springboot中配置Mail和普通mail的實(shí)現(xiàn)方式
這篇文章主要介紹了Springboot中配置Mail和普通mail的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03Java IO流 File類(lèi)的常用API實(shí)例
這篇文章主要介紹了Java IO流 File類(lèi)的常用API實(shí)例的相關(guān)資料,需要的朋友參考下吧2017-05-05在SSM框架中將圖片上傳到數(shù)據(jù)庫(kù)中的實(shí)現(xiàn)代碼
這篇文章主要介紹了在SSM框架中將圖片上傳到數(shù)據(jù)庫(kù)中的實(shí)現(xiàn)代碼,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03Java算法實(shí)戰(zhàn)之排一億個(gè)隨機(jī)數(shù)
我們?cè)谏钪薪?jīng)常遇見(jiàn)一些這樣的需求,隨機(jī)點(diǎn)名、公司年會(huì)抽獎(jiǎng)、微信拼手氣紅包等,還有一些游戲比如打地鼠小游戲、俄羅斯方塊等,這些場(chǎng)景中都會(huì)用到一種算法:隨機(jī),這篇文章主要給大家介紹了關(guān)于Java算法實(shí)戰(zhàn)之排一億個(gè)隨機(jī)數(shù)的相關(guān)資料,需要的朋友可以參考下2021-11-11