zoukankan      html  css  js  c++  java
  • springboot启动源码解析

    执行流程图源文件:https://www.processon.com/view/link/5b825917e4b0d4d65be7066a

    springboot版本为2.0.7

    @SpringBootApplication启动类

    @SpringBootApplication
    public class StartBootTestApplication {
        public static void main(String[] args) {
    //第一个参数为Spring容器配置类,第二个参数为命令行参数 SpringApplication.run(StartBootTestApplication.
    class,args); } }
    this.webApplicationType = WebApplicationType.deduceFromClasspath();
    WebApplicationType是选择服务的启动类型通过他可以选择性的嵌入不同的服务器
    有三种类型:
    1.NONE:这个应用不能用作web应用 而且不能使用内置的web服务器服务
    2.SERVLET:这个应用用以web应用并且使用内置的web服务器
    3.REACTIVE:应用程序应该作为反应性web应用程序运行,并且应该启动嵌入式反应性web服务器
    this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
    加载所有初始化器,
    上下文前置处理prepareContext会触发
    this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
    初始化ApplicationListener类型的监听器
    上下文刷新refreshContext会触发

    /**
    *SpringApplication
    */
    //
    构造器初始化 public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) { this.sources = new LinkedHashSet(); //横幅模式 OFF,CONSOLE,LOG; 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.resourceLoader = resourceLoader; Assert.notNull(primarySources, "PrimarySources must not be null"); this.primarySources = new LinkedHashSet(Arrays.asList(primarySources)); //应用类型NONE,SERVLET,REACTIVE;存在DispatcherHandler,不存在DispatcherServlet,ServletContainer,则为REACTIVE //不存在javax.servlet.Servlet", "org.springframework.web.context.ConfigurableWebApplicationContext,则为NONE,则为SERVLET
    this.webApplicationType = WebApplicationType.deduceFromClasspath();
    //spring.factories文件中org.springframework.context.ApplicationContextInitializer=
    //org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,
    //org.springframework.boot.context.ContextIdApplicationContextInitializer,
    //org.springframework.boot.context.config.DelegatingApplicationContextInitializer,
    //org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer
    this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
    //org.springframework.context.ApplicationListener=
    //org.springframework.boot.ClearCachesApplicationListener,
    //org.springframework.boot.builder.ParentContextCloserApplicationListener,
    //org.springframework.boot.context.FileEncodingApplicationListener,
    //org.springframework.boot.context.config.AnsiOutputApplicationListener,
    //org.springframework.boot.context.config.ConfigFileApplicationListener,
    //org.springframework.boot.context.config.DelegatingApplicationListener,
    //org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,
    //org.springframework.boot.context.logging.LoggingApplicationListener,
    //org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener 进行初始化
    this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
    //推论出主类main
    this.mainApplicationClass = this.deduceMainApplicationClass();
    }

     spring启动开始,执行run

    SpringApplicationRunListeners listeners = this.getRunListeners(args);
    SpringApplicationRunListeners 初始化准备事件体系(观察者模式)
     
    //核心开始运行
    public ConfigurableApplicationContext run(String... args) {
    //秒表,用于记录启动时间,记录每个任务 的时间,
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    //spring应用上下文,spring容器
    ConfigurableApplicationContext context = null;
    //自定义SpringApplication启动错误的回调接口
    Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
    //java.awt.headless模式 默认为true开启
    this.configureHeadlessProperty();
    //开启监听
    //org.springframework.boot.SpringApplicationRunListener=
    //org.springframework.boot.context.event.EventPublishingRunListener
    SpringApplicationRunListeners listeners = this.getRunListeners(args);
    //
    listeners.starting();
    try {
    //参数封装,在命令行下启动应用带的参数,如--server.port
    ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
    //环境准备 1.加载外部化配置的资源到environment 2.触发ApplicationEnvironmentPreparedEvent事件
    ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
    //配置系统属性spring.beaninfo.ignore
    this.configureIgnoreBeanInfo(environment);
    //打印横幅
    Banner printedBanner = this.printBanner(environment);
    //创建ApplicationContext 根据webApplicationType
    //SERVLET:
    // contextClass = Class.forName("org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext");
    //REACTIVE:
    // contextClass = Class.forName("org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext");
    // default:
    // contextClass = Class.forName("org.springframework.context.annotation.AnnotationConfigApplicationContext");
    /**
    *AnnotationConfigServletWebServerApplicationContext层级关系-》ServletWebServerApplicationContext-》GenericWebApplicationContext
    *-》GenericApplicationContext-》AbstractApplicationContext
    */
    //部分属性:reader、scanner、beanFactory进行了实例化
    context = this.createApplicationContext();
    //实例化 用来支持报告关于启动的错误
    //# Error Reporters
    //org.springframework.boot.SpringBootExceptionReporter=
    //org.springframework.boot.diagnostics.FailureAnalyzers
    exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
    //ApplicationContext准备 加载
    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 ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) {
    //创建环境 SERVLET StandardServletEnvironment; REACTIVE StandardReactiveWebEnvironment; StandardEnvironment
    ConfigurableEnvironment environment = this.getOrCreateEnvironment();
    this.configureEnvironment((ConfigurableEnvironment)environment, applicationArguments.getSourceArgs());
    listeners.environmentPrepared((ConfigurableEnvironment)environment);
    this.bindToSpringApplication((ConfigurableEnvironment)environment);
    if (!this.isCustomEnvironment) {
    environment = (new EnvironmentConverter(this.getClassLoader())).convertEnvironmentIfNecessary((ConfigurableEnvironment)environment, this.deduceEnvironmentClass());
    }
    
    ConfigurationPropertySources.attach((Environment)environment);
    return (ConfigurableEnvironment)environment;
    }
    //ApplicationContext准备 加载
    private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
    //设置上下文的environment
    context.setEnvironment(environment);
    //应用上下文后处理
    this.postProcessApplicationContext(context);
    //在context refresh之前,对其应用ApplicationContextInitializer
    this.applyInitializers(context);
    //上下文准备(目前是空实现,有待扩展)
    listeners.contextPrepared(context);
    //打印启动日志和启动应用profile
    if (this.logStartupInfo) {
    this.logStartupInfo(context.getParent() == null);
    this.logStartupProfileInfo(context);
    }
    //向beanFactory注册单例bean:命令行参数bean
    ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
    beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
    if (printedBanner != null) {
    //向beanFactory注册单例bean:banner bean 
    beanFactory.registerSingleton("springBootBanner", printedBanner);
    }
    
    if (beanFactory instanceof DefaultListableBeanFactory) {
    ((DefaultListableBeanFactory)beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
    }
    
    Set<Object> sources = this.getAllSources();
    Assert.notEmpty(sources, "Sources must not be empty");
    //把bean加载到应用上下文中
    this.load(context, sources.toArray(new Object[0]));
    //向上下文中添加applicationListener,并广播ApplicationPerpareEvent事件
    listeners.contextLoaded(context);
    }    
    /**
    *AbstractApplicationContext
    */ 
    //刷新
    public void refresh() throws BeansException, IllegalStateException {
    Object var1 = this.startupShutdownMonitor;
    synchronized(this.startupShutdownMonitor) {
    //1.刷新前准备 校验
    this.prepareRefresh();
    //2.获取DefaultListableBeanFactory实例
    ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
    //3.beanFactory加载配置
    this.prepareBeanFactory(beanFactory);
    
    try {
    //4.BeanFactory准备工作完成后进行的后置准备工作
    //beanFactory后置处理,重写ApplicationContext的postProcessBeanFactory方法 未做处理
    this.postProcessBeanFactory(beanFactory);
    /********以上是BeanFactory的创建及预准备工作********/
    
    //核心:执行BeanFactoryPostProcessor的方法:
    //BeanFactoryPostProcessor:BeanFactory的后置处理器,在BeanFactory标准初始化之后执行的;
    //他的重要两个接口:BeanFactoryPostProcessor、BeanDefitionRegistryPostProcessor
    this.invokeBeanFactoryPostProcessors(beanFactory);
    //注册BeanPostProcessor(Bean的后置处理器)
    this.registerBeanPostProcessors(beanFactory);
    //7 初始化MessageSource组件(做国际化功能:消息绑定,消息解析)
    this.initMessageSource();
    //8初始化事件派发器
    this.initApplicationEventMulticaster();
    //9子类重写这个方法,在容器刷新的时候可以自定义逻辑
    this.onRefresh();
    //10.给容器中所有项目里面的ApplicationListener注册进来
    this.registerListeners();
    //11.初始化所有剩下的单实例bean
    this.finishBeanFactoryInitialization(beanFactory);
    //12.完成beanFactory的初始化创建工作:IOC容器就创建完成
    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();
    }
    
    }
    } 
    /**
    *AbstractApplicationContext
    */ 
    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    //1 设置BeanFactory的类加载器
    beanFactory.setBeanClassLoader(this.getClassLoader());
    //2 设置支持表达式解析器
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
    //3 添加部分BeanPostProcessor
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    //4 设置忽略的自动装配的接口EnvironmentAware、EmbeddedValueResolverAware、xxx;
    //这些接口的实现类不能通过类型来自动注入
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    //5 注册可以解析的自动装配:我们能直接在任何组件中自动注入:
    //BeanFactory/ResourceLoader、ApplicationEventPublisher、ApplicationContext
    //使用:
    //@Autowired
    //BeanFactory beanFactory
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);
    //6 添加BeanPostProcessor后置处理器
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
    //7 添加编译时AspectJ
    if (beanFactory.containsBean("loadTimeWeaver")) {
    beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
    beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
    //8 注册组件
    if (!beanFactory.containsLocalBean("environment")) {
    beanFactory.registerSingleton("environment", this.getEnvironment());
    }
    
    if (!beanFactory.containsLocalBean("systemProperties")) {
    beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
    }
    
    if (!beanFactory.containsLocalBean("systemEnvironment")) {
    beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());
    }
    
    }
    /**
    *AbstractApplicationContext
    */ 
    //执行BeanFactoryPostProcessor的后置处理器方法
    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());
    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) {
    beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
    beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
    
    }
    /**
    *PostProcessorRegistrationDelegate
    
    */
    public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    Set<String> processedBeans = new HashSet();
    ArrayList regularPostProcessors;
    ArrayList registryProcessors;
    int var9;
    ArrayList currentRegistryProcessors;
    String[] postProcessorNames;
    //1.判断beanFactory是否为BeanDefinitionRegistry,beanFactory为DefaultListableBeanFactory,
    //而DefaultListableBeanFactory实现了BeanDefinitionRegistry接口
    if (beanFactory instanceof BeanDefinitionRegistry) {
    //强转成BeanDefinitionRegistry
    BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;
    //保存BeanFactoryPostProcessor类型的后置处理器
    regularPostProcessors = new ArrayList();
    //保存BeanDefinitionRegistryPostProcessor类型的后置处理器
    registryProcessors = new ArrayList();
    Iterator var6 = beanFactoryPostProcessors.iterator();
    //循环遍历beanFactoryPostProcessors
    while(var6.hasNext()) {
    BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var6.next();
    //判断是否BeanDefinitionRegistryPostProcessor
    if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
    //强转BeanDefinitionRegistryPostProcessor
    BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor;
    //调用后置方法
    registryProcessor.postProcessBeanDefinitionRegistry(registry);
    //添加到集合当中
    registryProcessors.add(registryProcessor);
    } else {
    //没有实现BeanDefinitionRegistryPostProcessor接口,添加到regularPostProcessors集合中
    regularPostProcessors.add(postProcessor);
    }
    }
    //定义一个集合保存当前准备创建的BeanDefinitionRegistryPostProcessor
    currentRegistryProcessors = new ArrayList();
    //第一步:去容器中获取BeanDefinitionRegistryPostProcessor的bean的处理器名称
    postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    String[] var16 = postProcessorNames;
    var9 = postProcessorNames.length;
    
    int var10;
    String ppName;
    //循环遍历获取BeanDefinitionRegistryPostProcessor的类型名称
    for(var10 = 0; var10 < var9; ++var10) {
    ppName = var16[var10];
    //判断是否实现了PriorityOrdered接口
    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    //调用getBean方法获取该对象加入currentRegistryProcessors集合中
    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    //同时加入processedBeans集合中
    processedBeans.add(ppName);
    }
    }
    //对currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor进行排序
    sortPostProcessors(currentRegistryProcessors, beanFactory);
    //保存到registryProcessors中
    registryProcessors.addAll(currentRegistryProcessors);
    /**
    *核心:典型的BeanDefinitionRegistryPostProcessor是ConfigurationClassPostProcessor
    *用于进行bean定义的加载 ->processConfigBeanDefinitions方法
    */
    invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
    //1清除当前临时集合currentRegistryProcessors
    currentRegistryProcessors.clear();
    //又在容器中获取BeanDefinitionRegistryPostProcessor的bean处理器名称
    postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    var16 = postProcessorNames;
    var9 = postProcessorNames.length;
    
    for(var10 = 0; var10 < var9; ++var10) {
    ppName = var16[var10];
    //没被处理过 且实现了Ordered接口
    if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
    //调用getBean方法获取该对象加入currentRegistryProcessors集合中
    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    //同时加入processedBeans集合中
    processedBeans.add(ppName);
    }
    }
    //对currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor进行排序
    sortPostProcessors(currentRegistryProcessors, beanFactory);
    //保存到registryProcessors中
    registryProcessors.addAll(currentRegistryProcessors);
    //调用后置处理方法
    invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
    //2清除当前临时集合currentRegistryProcessors
    currentRegistryProcessors.clear();
    boolean reiterate = true;
    //调用没有实现任何优先级接口的BeanDefinitionRegistryPostProcessor
    while(reiterate) {
    //进入循环把reiterate更新为false
    reiterate = false;
    //在容器中获取BeanDefinitionRegistryPostProcessor的bean处理器名称
    postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    String[] var19 = postProcessorNames;
    var10 = postProcessorNames.length;
    
    for(int var26 = 0; var26 < var10; ++var26) {
    String ppName = var19[var26];
    //没有被处理过的
    if (!processedBeans.contains(ppName)) {
    //调用getBean方法获取该对象加入currentRegistryProcessors集合中
    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    //同时加入processedBeans集合中
    processedBeans.add(ppName);
    
    reiterate = true;
    }
    }
    ////对currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor进行排序
    sortPostProcessors(currentRegistryProcessors, beanFactory);
    //保存到registryProcessors中
    registryProcessors.addAll(currentRegistryProcessors);
    //调用后置处理方法
    invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
    //3清除当前临时集合currentRegistryProcessors
    currentRegistryProcessors.clear();
    }
    //调用实现了BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口的方法
    invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory);
    //调用实现了BeanFactoryPostProcessor接口的方法
    invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
    } else {
    //beanFactory没有实现了BeanDefinitionRegistry 直接调用beanFactoryPostProcessor接口的方法进行后置处理器
    invokeBeanFactoryPostProcessors((Collection)beanFactoryPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
    }
    //最后 获取容器中所有的BeanFactoryPostProcessor
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    //保存实现了priorityOrdered接口
    regularPostProcessors = new ArrayList();
    //保存实现了Ordered接口
    registryProcessors = new ArrayList();
    currentRegistryProcessors = new ArrayList();
    postProcessorNames = postProcessorNames;//错误代码
    int var20 = postProcessorNames.length;
    
    String ppName;
    for(var9 = 0; var9 < var20; ++var9) {
    ppName = postProcessorNames[var9];
    //没被处理过
    if (!processedBeans.contains(ppName)) {
    //判断是否实现了PriorityOrdered
    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    regularPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
    //判断是否实现了Ordered
    } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
    registryProcessors.add(ppName);
    } else {
    //没有任何优先级接口
    currentRegistryProcessors.add(ppName);
    }
    }
    }
    
    sortPostProcessors(regularPostProcessors, beanFactory);
    //先调用BeanFactoryPostProcessor实现了priorityOrdered接口
    invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList();
    Iterator var21 = registryProcessors.iterator();
    
    while(var21.hasNext()) {
    String postProcessorName = (String)var21.next();
    orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    //再调用BeanFactoryPostProcessor实现了Ordered接口
    sortPostProcessors(orderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors((Collection)orderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList();
    Iterator var24 = currentRegistryProcessors.iterator();
    
    while(var24.hasNext()) {
    ppName = (String)var24.next();
    nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
    }
    //最后调用没有实现任何方法接口
    invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
    beanFactory.clearMetadataCache();
    }
    BeanDefinitionRegistryPostProcessor接口实现类:ConfigurationClassPostProcessor(比较重要)
    ConfigurationClassPostProcessor类处理带有@Configuration配置类,使用方法processConfigBeanDefinitions,参照https://www.cnblogs.com/mufeng07/p/12165616.html
    ConfigurationClassPostProcessor类解析参照:https://www.cnblogs.com/mufeng07/p/12172549.html
  • 相关阅读:
    纯js面试题
    js面试题汇总:
    css面试题-圣杯布局
    6.1 React组件 Component的两个问题
    7.1 React异步加载
    vscode插件配置jsx:
    6.2 React renderProps 和 HOC组件优化
    2.5 React高阶组件HOC
    04 Python学习之数据类型-bytes
    03 Python学习之Python基础
  • 原文地址:https://www.cnblogs.com/mufeng07/p/12134288.html
Copyright © 2011-2022 走看看