------本文只作為跟代碼的一個參考,建議可以根據思路在指定類中斷點調試學習----
1、運行被@SpringBootApplication修飾的程序入口,執行main方法,調用SpringApplication的靜態run方法,返回ConfigurableApplicationContext。
2、在SpringApplication的靜態run方法中創建了以啟動類為參數的SpringApplication對象並調用了非靜態run方法,構造方法和run方法內容如下
1)首先解析SpringApplication構造方法的操作:
public SpringApplication(Class<?>... primarySources) { this((ResourceLoader)null, primarySources); } public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { this.sources = new LinkedHashSet(); this.bannerMode = Mode.CONSOLE; this.logStartupInfo = true; this.addCommandLineProperties = true; this.addConversionService = true; this.headless = true; // 用來在容器初始化之后,用來優雅停止的 this.registerShutdownHook = true; this.additionalProfiles = new HashSet(); this.isCustomEnvironment = false; this.lazyInitialization = false; this.resourceLoader = resourceLoader; // PrimarySources 啟動類class對象 Assert.notNull(primarySources, "PrimarySources must not be null"); this.primarySources = new LinkedHashSet(Arrays.asList(primarySources)); // 判斷是否使用servlet容器啟動,是否選擇內置的servlet容器。SERVLET使用內嵌容器啟動 this.webApplicationType = WebApplicationType.deduceFromClasspath(); // 通過讀取META-INF/spring.factories配置創建springboot啟動的初試化對象 this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
// 初始化監聽類 this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class)); this.mainApplicationClass = this.deduceMainApplicationClass(); } private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) { return this.getSpringFactoriesInstances(type, new Class[0]); } private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) { ClassLoader classLoader = this.getClassLoader(); //使用工廠加載類讀取spring.factories文件中配置的接口實現類的全限定名list Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader)); //使用反射根據全限定名執行構造方法生成對象 List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names); // 根據實現的Ordered接口,實現getOrder返回的int值排序。沒有實現這個接口的類不參與排序,原位置不變 AnnotationAwareOrderComparator.sort(instances); return instances; } private <T> List<T> createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, ClassLoader classLoader, Object[] args, Set<String> names) { List<T> instances = new ArrayList(names.size()); Iterator var7 = names.iterator(); while(var7.hasNext()) { String name = (String)var7.next(); try { Class<?> instanceClass = ClassUtils.forName(name, classLoader); Assert.isAssignable(type, instanceClass); //使用反射調用無參構造方法生成對象 Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes); T instance = BeanUtils.instantiateClass(constructor, args); instances.add(instance); } catch (Throwable var12) { throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, var12); } } return instances; }
SpringFactoriesLoader.loadFactoryNames(type, classLoader)源碼如下:
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) { String factoryTypeName = factoryType.getName(); return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList()); } private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) { MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader); if (result != null) { return result; } else { try { Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories"); //底層封裝的是LinkedHashMap,並對add方法進行了重寫,保證從不同路徑下的spring.factories讀取到的同一個key都會在不同循環中都放在同一個key的value中,不會發生覆蓋 LinkedMultiValueMap result = new LinkedMultiValueMap(); while(urls.hasMoreElements()) { URL url = (URL)urls.nextElement(); UrlResource resource = new UrlResource(url); // PropertiesLoaderUtils,spring的工具類,將配置文件流寫入hashTable子類properties實例中--操作過程中只區分了是不是xml文件 Properties properties = PropertiesLoaderUtils.loadProperties(resource); Iterator var6 = properties.entrySet().iterator(); while(var6.hasNext()) { Entry<?, ?> entry = (Entry)var6.next(); String factoryTypeName = ((String)entry.getKey()).trim(); String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue()); int var10 = var9.length; for(int var11 = 0; var11 < var10; ++var11) { String factoryImplementationName = var9[var11]; result.add(factoryTypeName, factoryImplementationName.trim()); } } } cache.put(classLoader, result); return result; } catch (IOException var13) { throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13); } } }
public void add(K key, @Nullable V value) { List<V> values = (List)this.targetMap.computeIfAbsent(key, (k) -> { return new LinkedList(); }); values.add(value); }
public static void fillProperties(Properties props, Resource resource) throws IOException { InputStream is = resource.getInputStream(); try { String filename = resource.getFilename(); if (filename != null && filename.endsWith(".xml")) { props.loadFromXML(is); } else { props.load(is); } } finally { is.close(); } }
根據Ordered接口排序之前

根據Ordered接口排序之后

初始化的監聽類:

2)下面來看看非靜態run方法中都做了什么:
public ConfigurableApplicationContext run(String... args) { StopWatch stopWatch = new StopWatch();
stopWatch.start(); ConfigurableApplicationContext context = null; Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList(); this.configureHeadlessProperty(); SpringApplicationRunListeners listeners = this.getRunListeners(args); // 啟動監聽 listeners.starting(); Collection exceptionReporters; try { ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments); this.configureIgnoreBeanInfo(environment); Banner printedBanner = this.printBanner(environment); // 根據構造方法中獲得的webApplicationType枚舉類型servlet獲得ApplicationContext實例org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
// 這里new了一個DefualtListableFactiory
//詳見下方截圖 context = this.createApplicationContext(); // 讀取spring.factories文件創建bean exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context); // ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); // 調用構造方法中創建的ApplicationContextInitializer實例重寫的initialize方法做初始化操作 this.prepareContext(context, environment, listeners, applicationArguments, printedBanner); // 詳見下面方法 this.refreshContext(context); // this.afterRefresh(context, applicationArguments); stopWatch.stop(); if (this.logStartupInfo) { (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch); } listeners.started(context); this.callRunners(context, applicationArguments); } catch (Throwable var10) { this.handleRunFailure(context, var10, exceptionReporters, listeners); throw new IllegalStateException(var10); } try { listeners.running(context); return context; } catch (Throwable var9) { this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null); throw new IllegalStateException(var9); } } private void refreshContext(ConfigurableApplicationContext context) { // 調用context父類AbstractAppliactionContext執行容器初始化bean,自動裝配的過程 this.refresh(context); if (this.registerShutdownHook) { try { // context.registerShutdownHook(); } catch (AccessControlException var3) { } } }



這里其實做了很多初始化工作,在java.lang.reflect.Constructor中public T newInstance(Object ... initargs)方法上打斷的看可以看到
走到這里,spring容器啟動和初始化算是完成了,下面就是容器開始初始化bean,裝配bean的過程
我們注意看下,在springContext的refreshContext方法中,除了調用了AbstractApplicationContext.refresh() 方法,委派他去創建和裝配bean外,還做了一個操作就是判斷了
registerShutdownHook參數,默認是true,程序會執行AbstractApplicationContext.registerShutdownHook();方法
public void registerShutdownHook() { if (this.shutdownHook == null) { this.shutdownHook = new Thread("SpringContextShutdownHook") { public void run() { synchronized(AbstractApplicationContext.this.startupShutdownMonitor) { AbstractApplicationContext.this.doClose(); } } }; // 注冊一個shutdownHook線程 ,當進程停止后執行收尾工作,具體可參考https://www.cnblogs.com/maxstack/p/9112711.html Runtime.getRuntime().addShutdownHook(this.shutdownHook); } }
---------具體看下AbstractApplicationContext執行容器操作的內容:---------
public void refresh() throws BeansException, IllegalStateException { synchronized(this.startupShutdownMonitor) { this.prepareRefresh(); // 這里初始化了所有我們希望被spring管理的bean信息,緩存在工廠類中,具體看下方截圖obtainFreshBeanFactory的介紹 ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); this.prepareBeanFactory(beanFactory); try { // 空方法體,待子類重寫 this.postProcessBeanFactory(beanFactory); // 創建指定bean,詳情見 this.invokeBeanFactoryPostProcessors(beanFactory); // this.registerBeanPostProcessors(beanFactory); // this.initMessageSource(); // this.initApplicationEventMulticaster(); // this.onRefresh(); // this.registerListeners(); // 這里使用DefaultListableBeanFactory創建非懶加載的bean this.finishBeanFactoryInitialization(beanFactory); // this.finishRefresh(); } catch (BeansException var9) { if (this.logger.isWarnEnabled()) { this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9); } this.destroyBeans(); this.cancelRefresh(var9); throw var9; } finally { this.resetCommonCaches(); } } }

----------下面詳解finishBeanFactoryInitialization做的操作:------
下面是從創建controller層bean的方法調用鏈如下:(備注:controller層做了通過mybaits連接數據庫返回查詢結果的操作)以下是倒序描述
// 這里就是調用了SqlsessionTemplate的構造方法
<init>:94, SqlSessionTemplate (org.mybatis.spring) sqlSessionTemplate:163, MybatisAutoConfiguration (org.mybatis.spring.boot.autoconfigure) CGLIB$sqlSessionTemplate$1:-1, MybatisAutoConfiguration$$EnhancerBySpringCGLIB$$2abe972c (org.mybatis.spring.boot.autoconfigure) invoke:-1, MybatisAutoConfiguration$$EnhancerBySpringCGLIB$$2abe972c$$FastClassBySpringCGLIB$$d1075e2f (org.mybatis.spring.boot.autoconfigure) invokeSuper:244, MethodProxy (org.springframework.cglib.proxy) intercept:363, ConfigurationClassEnhancer$BeanMethodInterceptor (org.springframework.context.annotation) sqlSessionTemplate:-1, MybatisAutoConfiguration$$EnhancerBySpringCGLIB$$2abe972c (org.mybatis.spring.boot.autoconfigure) invoke0:-1, NativeMethodAccessorImpl (sun.reflect) invoke:62, NativeMethodAccessorImpl (sun.reflect) invoke:43, DelegatingMethodAccessorImpl (sun.reflect) invoke:498, Method (java.lang.reflect) instantiate:154, SimpleInstantiationStrategy (org.springframework.beans.factory.support) instantiate:651, ConstructorResolver (org.springframework.beans.factory.support) instantiateUsingFactoryMethod:636, ConstructorResolver (org.springframework.beans.factory.support) instantiateUsingFactoryMethod:1338, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) createBeanInstance:1177, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)//這里和其他bean的創建是不一樣的,后面的操作也是在這個方法中執行的,執行完這個方法的后續操作和其他bean是一樣的 doCreateBean:557, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) createBean:517, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) lambda$doGetBean$0:323, AbstractBeanFactory (org.springframework.beans.factory.support) getObject:-1, 1658980982 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$145) getSingleton:222, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support) doGetBean:321, AbstractBeanFactory (org.springframework.beans.factory.support) getBean:202, AbstractBeanFactory (org.springframework.beans.factory.support)
//5、這里開始創建SqlSessionTemplate實例 resolveCandidate:276, DependencyDescriptor (org.springframework.beans.factory.config) doResolveDependency:1287, DefaultListableBeanFactory (org.springframework.beans.factory.support) resolveDependency:1207, DefaultListableBeanFactory (org.springframework.beans.factory.support) autowireByType:1511, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) populateBean:1406, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) doCreateBean:594, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) createBean:517, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) lambda$doGetBean$0:323, AbstractBeanFactory (org.springframework.beans.factory.support) getObject:-1, 1658980982 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$145) getSingleton:222, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support) doGetBean:321, AbstractBeanFactory (org.springframework.beans.factory.support) getBean:202, AbstractBeanFactory (org.springframework.beans.factory.support)
//4、開始創建mapper接口代理實例 resolveCandidate:276, DependencyDescriptor (org.springframework.beans.factory.config) doResolveDependency:1287, DefaultListableBeanFactory (org.springframework.beans.factory.support) resolveDependency:1207, DefaultListableBeanFactory (org.springframework.beans.factory.support) autowireResource:537, CommonAnnotationBeanPostProcessor (org.springframework.context.annotation) getResource:513, CommonAnnotationBeanPostProcessor (org.springframework.context.annotation) getResourceToInject:653, CommonAnnotationBeanPostProcessor$ResourceElement (org.springframework.context.annotation) inject:224, InjectionMetadata$InjectedElement (org.springframework.beans.factory.annotation) inject:116, InjectionMetadata (org.springframework.beans.factory.annotation) postProcessProperties:334, CommonAnnotationBeanPostProcessor (org.springframework.context.annotation) populateBean:1422, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) doCreateBean:594, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) createBean:517, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) lambda$doGetBean$0:323, AbstractBeanFactory (org.springframework.beans.factory.support) getObject:-1, 1658980982 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$145) getSingleton:222, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support) doGetBean:321, AbstractBeanFactory (org.springframework.beans.factory.support) getBean:202, AbstractBeanFactory (org.springframework.beans.factory.support)
// 3、開始創建manager層bean resolveCandidate:276, DependencyDescriptor (org.springframework.beans.factory.config) doResolveDependency:1287, DefaultListableBeanFactory (org.springframework.beans.factory.support) resolveDependency:1207, DefaultListableBeanFactory (org.springframework.beans.factory.support) autowireResource:537, CommonAnnotationBeanPostProcessor (org.springframework.context.annotation) getResource:513, CommonAnnotationBeanPostProcessor (org.springframework.context.annotation) getResourceToInject:653, CommonAnnotationBeanPostProcessor$ResourceElement (org.springframework.context.annotation) inject:224, InjectionMetadata$InjectedElement (org.springframework.beans.factory.annotation) inject:116, InjectionMetadata (org.springframework.beans.factory.annotation) postProcessProperties:334, CommonAnnotationBeanPostProcessor (org.springframework.context.annotation) populateBean:1422, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) doCreateBean:594, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) createBean:517, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) lambda$doGetBean$0:323, AbstractBeanFactory (org.springframework.beans.factory.support) getObject:-1, 1658980982 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$145) getSingleton:222, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support) // 循環調用創建bean的方法 doGetBean:321, AbstractBeanFactory (org.springframework.beans.factory.support) getBean:202, AbstractBeanFactory (org.springframework.beans.factory.support)
// 2、開始創建service層bean resolveCandidate:276, DependencyDescriptor (org.springframework.beans.factory.config) // 根據解析到的依賴bean列表創建需要的bean doResolveDependency:1287, DefaultListableBeanFactory (org.springframework.beans.factory.support) resolveDependency:1207, DefaultListableBeanFactory (org.springframework.beans.factory.support) inject:640, AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement (org.springframework.beans.factory.annotation) //根據之前放到DefaultListableBeanFactory中的beanDefinitionMap集合中的對應bean的BeanDefinition信息獲得需要注入的bean列表 inject:116, InjectionMetadata (org.springframework.beans.factory.annotation) postProcessProperties:399, AutowiredAnnotationBeanPostProcessor (org.springframework.beans.factory.annotation) populateBean:1422, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) doCreateBean:594, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) createBean:517, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) lambda$doGetBean$0:323, AbstractBeanFactory (org.springframework.beans.factory.support) getObject:-1, 1658980982 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$145) getSingleton:222, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
//1、 開始創建單例controller層的bean doGetBean:321, AbstractBeanFactory (org.springframework.beans.factory.support) getBean:202, AbstractBeanFactory (org.springframework.beans.factory.support) preInstantiateSingletons:879, DefaultListableBeanFactory (org.springframework.beans.factory.support) finishBeanFactoryInitialization:878, AbstractApplicationContext (org.springframework.context.support)//這里開始創建bean refresh:550, AbstractApplicationContext (org.springframework.context.support) // 走到這里就和SpringMvc啟動調用的是同一個bean初始化方法了
(注:其實這里和springmvc啟動的不同之處就在用加載配置不同,加載完配置還是調用了統一的啟動容器,創建bean,自動裝配) refresh:141, ServletWebServerApplicationContext (org.springframework.boot.web.servlet.context) refresh:747, SpringApplication (org.springframework.boot) refreshContext:397, SpringApplication (org.springframework.boot) run:315, SpringApplication (org.springframework.boot) run:1226, SpringApplication (org.springframework.boot) run:1215, SpringApplication (org.springframework.boot) main:12, DemoApplication (com.example.mybatisdemo) 應用入口
下圖是springboot啟動需要自動裝配的集合內容,會緩存到beanFactory 的beanDefinitionMap中
springboot的指定bean工廠是DefaultListableBeanFactory
下面來總結下整個流程:
1、 AbstractApplicationContext中的refresh()方法執行自身的finishBeanFactoryInitialization()方法。這個方法執行了具體實例化bean的工作
2、finishBeanFactoryInitialization方法調用了bean工廠的對應方法對不同bean進行實例化。
3、spring的bean默認都是單例的,現在一單例bean的創建為例繼續跟蹤。spring調用了bean工廠的preInstantiateSingletons()方法。
4、在bean工程的創建實例的方法中循環創建了工廠實現緩存好的beanDefineNames列表中對應的bean.
0 = "org.springframework.context.annotation.internalConfigurationAnnotationProcessor" 1 = "org.springframework.context.annotation.internalAutowiredAnnotationProcessor" 2 = "org.springframework.context.annotation.internalCommonAnnotationProcessor" 3 = "org.springframework.context.event.internalEventListenerProcessor" 4 = "org.springframework.context.event.internalEventListenerFactory" 5 = "demoApplication" 6 = "org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory" 7 = "demoController" 8 = "demoManager" 9 = "demoServiceImpl" 10 = "org.springframework.boot.autoconfigure.AutoConfigurationPackages" 11 = "cfDirectRepaymentRecordMapper" 12 = "weeklyMapper" 13 = "org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration" 14 = "propertySourcesPlaceholderConfigurer" 15 = "org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration$TomcatWebSocketConfiguration" 16 = "websocketServletWebServerCustomizer" 17 = "org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration" 18 = "org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryConfiguration$EmbeddedTomcat" 19 = "tomcatServletWebServerFactory" 20 = "org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration" 21 = "servletWebServerFactoryCustomizer" 22 = "tomcatServletWebServerFactoryCustomizer" 23 = "org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor" 24 = "org.springframework.boot.context.internalConfigurationPropertiesBinderFactory" 25 = "org.springframework.boot.context.internalConfigurationPropertiesBinder" 26 = "org.springframework.boot.context.properties.ConfigurationPropertiesBeanDefinitionValidator" 27 = "org.springframework.boot.context.properties.ConfigurationBeanFactoryMetadata" 28 = "server-org.springframework.boot.autoconfigure.web.ServerProperties" 29 = "webServerFactoryCustomizerBeanPostProcessor" 30 = "errorPageRegistrarBeanPostProcessor" 31 = "org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration$DispatcherServletConfiguration" 32 = "dispatcherServlet" 33 = "spring.http-org.springframework.boot.autoconfigure.http.HttpProperties" 34 = "spring.mvc-org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties" 35 = "org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration$DispatcherServletRegistrationConfiguration" 36 = "dispatcherServletRegistration" 37 = "org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration" 38 = "org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration" 39 = "taskExecutorBuilder" 40 = "applicationTaskExecutor" 41 = "spring.task.execution-org.springframework.boot.autoconfigure.task.TaskExecutionProperties" 42 = "org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration" 43 = "defaultValidator" 44 = "methodValidationPostProcessor" 45 = "org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration" 46 = "error" 47 = "beanNameViewResolver" 48 = "org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration$DefaultErrorViewResolverConfiguration" 49 = "conventionErrorViewResolver" 50 = "org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration" 51 = "errorAttributes" 52 = "basicErrorController" 53 = "errorPageCustomizer" 54 = "preserveErrorControllerTargetClassPostProcessor" 55 = "spring.resources-org.springframework.boot.autoconfigure.web.ResourceProperties" 56 = "org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration" 57 = "requestMappingHandlerAdapter" 58 = "requestMappingHandlerMapping" 59 = "welcomePageHandlerMapping" 60 = "mvcConversionService" 61 = "mvcValidator" 62 = "mvcContentNegotiationManager" 63 = "mvcPathMatcher" 64 = "mvcUrlPathHelper" 65 = "viewControllerHandlerMapping" 66 = "beanNameHandlerMapping" 67 = "routerFunctionMapping" 68 = "resourceHandlerMapping" 69 = "mvcResourceUrlProvider" 70 = "defaultServletHandlerMapping" 71 = "handlerFunctionAdapter" 72 = "mvcUriComponentsContributor" 73 = "httpRequestHandlerAdapter" 74 = "simpleControllerHandlerAdapter" 75 = "handlerExceptionResolver" 76 = "mvcViewResolver" 77 = "mvcHandlerMappingIntrospector" 78 = "org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter" 79 = "defaultViewResolver" 80 = "viewResolver" 81 = "requestContextFilter" 82 = "org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration" 83 = "formContentFilter" 84 = "com.alibaba.druid.spring.boot.autoconfigure.stat.DruidStatViewServletConfiguration" 85 = "statViewServletRegistrationBean" 86 = "com.alibaba.druid.spring.boot.autoconfigure.stat.DruidWebStatFilterConfiguration" 87 = "webStatFilterRegistrationBean" 88 = "com.alibaba.druid.spring.boot.autoconfigure.stat.DruidFilterConfiguration" 89 = "statFilter" 90 = "com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure" 91 = "dataSource" 92 = "spring.datasource.druid-com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties" 93 = "spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties" 94 = "org.springframework.boot.autoconfigure.jdbc.metadata.DataSourcePoolMetadataProvidersConfiguration$HikariPoolDataSourceMetadataProviderConfiguration" 95 = "hikariPoolDataSourceMetadataProvider" 96 = "org.springframework.boot.autoconfigure.jdbc.metadata.DataSourcePoolMetadataProvidersConfiguration" 97 = "org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker" 98 = "org.springframework.boot.autoconfigure.jdbc.DataSourceInitializationConfiguration" 99 = "dataSourceInitializerPostProcessor"
public void preInstantiateSingletons() throws BeansException { if (this.logger.isTraceEnabled()) { this.logger.trace("Pre-instantiating singletons in " + this); } List<String> beanNames = new ArrayList(this.beanDefinitionNames); Iterator var2 = beanNames.iterator(); while(true) { String beanName; Object bean; do { while(true) { RootBeanDefinition bd; do { do { do { if (!var2.hasNext()) { var2 = beanNames.iterator(); while(var2.hasNext()) { beanName = (String)var2.next(); Object singletonInstance = this.getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged(() -> { smartSingleton.afterSingletonsInstantiated(); return null; }, this.getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } } return; } beanName = (String)var2.next(); bd = this.getMergedLocalBeanDefinition(beanName); } while(bd.isAbstract()); } while(!bd.isSingleton()); } while(bd.isLazyInit()); if (this.isFactoryBean(beanName)) { bean = this.getBean("&" + beanName); break; } this.getBean(beanName); } } while(!(bean instanceof FactoryBean)); FactoryBean<?> factory = (FactoryBean)bean; boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { SmartFactoryBean var10000 = (SmartFactoryBean)factory; ((SmartFactoryBean)factory).getClass(); isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext()); } else { isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit(); } if (isEagerInit) { this.getBean(beanName); } } }
5、在循環構造實例的方法中調用了從抽象父類AbstractBeanFactory繼承來的this.getBean(beanName);方法。
通過細心看代碼,通過工廠模式創建bean和通過類自身的構造方法創建bean的流程是不一樣的,這里通過在beanName上加&符作為區分

6、接下來看下我們自定義的一個controller類的實例化過程
1)spring使用AbstractAutowireCapableBeanFactory工廠創建controller類實例
2)通過doCreateBean方法創建bean:首先創建實例對象,然后方法內調用本類的populateBean方法對內部的依賴bean進行初始化
3)初始化過程中調用了AutowiredAnnotationBeanPostProcessor的postProcessProperties方法
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
//首先獲得所有被注解了的需要初始化的成員變量列表
InjectionMetadata metadata = this.findAutowiringMetadata(beanName, bean.getClass(), pvs); try {
metadata.inject(bean, beanName, pvs); return pvs; } catch (BeanCreationException var6) { throw var6; } catch (Throwable var7) { throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", var7); } }
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { Collection<InjectionMetadata.InjectedElement> checkedElements = this.checkedElements; Collection<InjectionMetadata.InjectedElement> elementsToIterate = checkedElements != null ? checkedElements : this.injectedElements; InjectionMetadata.InjectedElement element; if (!((Collection)elementsToIterate).isEmpty()) { for(Iterator var6 = ((Collection)elementsToIterate).iterator(); var6.hasNext(); element.inject(target, beanName, pvs)) { element = (InjectionMetadata.InjectedElement)var6.next(); if (logger.isTraceEnabled()) { logger.trace("Processing injected element of bean '" + beanName + "': " + element); } } } }

可以看到,這里具體操作是調用了AutowiredAnnotationBeanPostProcessor的內部類AutowiredFieldElement中重寫抽象類InjectedElement的inject方法
private class AutowiredFieldElement extends InjectedElement { private final boolean required; private volatile boolean cached = false; @Nullable private volatile Object cachedFieldValue; public AutowiredFieldElement(Field field, boolean required) { super(field, (PropertyDescriptor)null); this.required = required; } protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { Field field = (Field)this.member; Object value; if (this.cached) { value = AutowiredAnnotationBeanPostProcessor.this.resolvedCachedArgument(beanName, this.cachedFieldValue); } else { DependencyDescriptor desc = new DependencyDescriptor(field, this.required); desc.setContainingClass(bean.getClass()); Set<String> autowiredBeanNames = new LinkedHashSet(1); Assert.state(AutowiredAnnotationBeanPostProcessor.this.beanFactory != null, "No BeanFactory available"); TypeConverter typeConverter = AutowiredAnnotationBeanPostProcessor.this.beanFactory.getTypeConverter(); try { value = AutowiredAnnotationBeanPostProcessor.this.beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter); } catch (BeansException var12) { throw new UnsatisfiedDependencyException((String)null, beanName, new InjectionPoint(field), var12); } synchronized(this) { if (!this.cached) { if (value == null && !this.required) { this.cachedFieldValue = null; } else { this.cachedFieldValue = desc; AutowiredAnnotationBeanPostProcessor.this.registerDependentBeans(beanName, autowiredBeanNames); if (autowiredBeanNames.size() == 1) { String autowiredBeanName = (String)autowiredBeanNames.iterator().next(); if (AutowiredAnnotationBeanPostProcessor.this.beanFactory.containsBean(autowiredBeanName) && AutowiredAnnotationBeanPostProcessor.this.beanFactory.isTypeMatch(autowiredBeanName, field.getType())) { this.cachedFieldValue = new AutowiredAnnotationBeanPostProcessor.ShortcutDependencyDescriptor(desc, autowiredBeanName, field.getType()); } } } this.cached = true; } } } if (value != null) { ReflectionUtils.makeAccessible(field); field.set(bean, value); } } } }
而抽象類抽象類InjectedElement的inject方法內部的實現其實只是給他的成員變量賦空值,這里調用的是子類重后的方法,方法里再次調用beanFactory創建需要賦值的成員變量實例。
所以算是遞歸調用beanfactory創建需要的所有bean。




