zoukankan      html  css  js  c++  java
  • 跟跟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;
    
            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。

     

     


    
    

     






  • 相关阅读:
    Hadoop 的版本问题
    SSH 端口转发原理
    KM算法
    最大流算法小结
    pku 2195 KM算法求最小权二分匹配
    SAP(最短增广路算法) 最大流模板
    最大流模板
    pku 1459 最大流 SAP
    pku Drainage Ditches 简单最大流 直接套模板 注意可能有重边
    推荐:吴军 谷歌黑板报 《浪潮之颠》
  • 原文地址:https://www.cnblogs.com/tianhaichao/p/12202446.html
Copyright © 2011-2022 走看看