跟跟Springboot启动容器,自动装配的过程

Posted 田海超

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了跟跟Springboot启动容器,自动装配的过程相关的知识,希望对你有一定的参考价值。

------本文只作为跟代码的一个参考,建议可以根据思路在指定类中断点调试学习----

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);
    }
重写的add方法
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();
        }

    }
PropertiesLoaderUtils解析不同配置文件的方法
根据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"
List beanNames中实际装的值

 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);
            }
        }
    }
bean工厂中的preInstantiateSingletons()方法

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;

        springboot自动装配

Springboot自动装配的原理

SpringBoot启动及自动装配原理

spring boot自动装配原理@EnableAutoConfiguration

聊聊什么是SpringBoot 的自动装配原理

从源码中理解Spring Boot自动装配原理