• Springboot 启动Bean如何被加载


    1.启动类

    SpringApplication.run(TianMaoApplication.class, args);
    1. public ConfigurableApplicationContext run(String... args) {
    2. long startTime = System.nanoTime();
    3. DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
    4. ConfigurableApplicationContext context = null;
    5. this.configureHeadlessProperty();
    6. SpringApplicationRunListeners listeners = this.getRunListeners(args);
    7. listeners.starting(bootstrapContext, this.mainApplicationClass);
    8. try {
    9. ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
    10. ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
    11. this.configureIgnoreBeanInfo(environment);
    12. Banner printedBanner = this.printBanner(environment);
    13. context = this.createApplicationContext();
    14. context.setApplicationStartup(this.applicationStartup);
    15. this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
    16. this.refreshContext(context);
    17. this.afterRefresh(context, applicationArguments);
    18. Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
    19. if (this.logStartupInfo) {
    20. (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), timeTakenToStartup);
    21. }
    22. listeners.started(context, timeTakenToStartup);
    23. this.callRunners(context, applicationArguments);
    24. } catch (Throwable var12) {
    25. this.handleRunFailure(context, var12, listeners);
    26. throw new IllegalStateException(var12);
    27. }
    28. try {
    29. Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
    30. listeners.ready(context, timeTakenToReady);
    31. return context;
    32. } catch (Throwable var11) {
    33. this.handleRunFailure(context, var11, (SpringApplicationRunListeners)null);
    34. throw new IllegalStateException(var11);
    35. }
    36. }
    context = this.createApplicationContext(); 创建ApplicationContent

    然后执行refresh() 这个很重要

    1. public void refresh() throws BeansException, IllegalStateException {
    2. synchronized(this.startupShutdownMonitor) {
    3. StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
    4. this.prepareRefresh();
    5. ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
    6. this.prepareBeanFactory(beanFactory);
    7. try {
    8. //会调用后置处理 去扫包 注册 获取Bean定义
    9. this.postProcessBeanFactory(beanFactory);
    10. StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
    11. this.invokeBeanFactoryPostProcessors(beanFactory);
    12. this.registerBeanPostProcessors(beanFactory);
    13. beanPostProcess.end();
    14. this.initMessageSource();
    15. this.initApplicationEventMulticaster();
    16. this.onRefresh();
    17. this.registerListeners();
    18. this.finishBeanFactoryInitialization(beanFactory);
    19. this.finishRefresh();
    20. } catch (BeansException var10) {
    21. if (this.logger.isWarnEnabled()) {
    22. this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var10);
    23. }
    24. this.destroyBeans();
    25. this.cancelRefresh(var10);
    26. throw var10;
    27. } finally {
    28. this.resetCommonCaches();
    29. contextRefresh.end();
    30. }
    31. }
    32. }

    run 的时候会执行 服务端口的读取,打印banner 等操作

    1. @FunctionalInterface
    2. public interface ApplicationContextFactory {
    3. ApplicationContextFactory DEFAULT = (webApplicationType) -> {
    4. try {
    5. switch(webApplicationType) {
    6. case SERVLET:
    7. return new AnnotationConfigServletWebServerApplicationContext();
    8. case REACTIVE:
    9. return new AnnotationConfigReactiveWebServerApplicationContext();
    10. default:
    11. return new AnnotationConfigApplicationContext();
    12. }
    13. } catch (Exception var2) {
    14. throw new IllegalStateException("Unable create a default ApplicationContext instance, you may need a custom ApplicationContextFactory", var2);
    15. }
    16. };
    17. ConfigurableApplicationContext create(WebApplicationType webApplicationType);
    18. static ApplicationContextFactory ofContextClass(Class contextClass) {
    19. return of(() -> {
    20. return (ConfigurableApplicationContext)BeanUtils.instantiateClass(contextClass);
    21. });
    22. }
    23. static ApplicationContextFactory of(Supplier supplier) {
    24. return (webApplicationType) -> {
    25. return (ConfigurableApplicationContext)supplier.get();
    26. };
    27. }
    28. }

    这面是创建了AnnotationConfigServletWebServerApplicationContext

    这面要说下 AnnotationConfigServletWebServerApplicationContext 

    private final AnnotatedBeanDefinitionReader reader;
    private final ClassPathBeanDefinitionScanner scanner;

    定义了这两个,如run 代码所示 refresh 时候调用这个初始化之后会执行后置处理

    1. protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    2. super.postProcessBeanFactory(beanFactory);
    3. if (this.basePackages != null && this.basePackages.length > 0) {
    4. this.scanner.scan(this.basePackages);
    5. }
    6. if (!this.annotatedClasses.isEmpty()) {
    7. this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
    8. }
    9. }

    scanner 会先扫包 看如下的代码注释

    1. protected Set doScan(String... basePackages) {
    2. Assert.notEmpty(basePackages, "At least one base package must be specified");
    3. Set beanDefinitions = new LinkedHashSet();
    4. String[] var3 = basePackages;
    5. int var4 = basePackages.length;
    6. for(int var5 = 0; var5 < var4; ++var5) {
    7. String basePackage = var3[var5];
    8. Set candidates = this.findCandidateComponents(basePackage);
    9. Iterator var8 = candidates.iterator();
    10. while(var8.hasNext()) {
    11. //先去获取bean的定义
    12. BeanDefinition candidate = (BeanDefinition)var8.next();
    13. ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
    14. candidate.setScope(scopeMetadata.getScopeName());
    15. //生成beanName
    16. String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
    17. //执行bean定义的后置操作
    18. if (candidate instanceof AbstractBeanDefinition) {
    19. this.postProcessBeanDefinition((AbstractBeanDefinition)candidate, beanName);
    20. }
    21. //@Bean 的读取
    22. if (candidate instanceof AnnotatedBeanDefinition) {
    23. AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition)candidate);
    24. }
    25. if (this.checkCandidate(beanName, candidate)) {
    26. BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
    27. //如果是scope 是target_class 需要注册一个代理进去 用来以后创建新对象
    28. definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    29. beanDefinitions.add(definitionHolder);
    30. this.registerBeanDefinition(definitionHolder, this.registry);
    31. }
    32. }
    33. }
    34. return beanDefinitions;
    35. }

    reader 去注册包

    1. private void doRegisterBean(Class beanClass, @Nullable String name, @Nullable Class[] qualifiers, @Nullable Supplier supplier, @Nullable BeanDefinitionCustomizer[] customizers) {
    2. AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
    3. if (!this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
    4. abd.setInstanceSupplier(supplier);
    5. ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
    6. abd.setScope(scopeMetadata.getScopeName());
    7. String beanName = name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry);
    8. AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
    9. int var10;
    10. int var11;
    11. if (qualifiers != null) {
    12. Class[] var9 = qualifiers;
    13. var10 = qualifiers.length;
    14. //设置primary 设置懒加载 设置 Qualifier
    15. for(var11 = 0; var11 < var10; ++var11) {
    16. Classextends Annotation> qualifier = var9[var11];
    17. if (Primary.class == qualifier) {
    18. abd.setPrimary(true);
    19. } else if (Lazy.class == qualifier) {
    20. abd.setLazyInit(true);
    21. } else {
    22. abd.addQualifier(new AutowireCandidateQualifier(qualifier));
    23. }
    24. }
    25. }
    26. if (customizers != null) {
    27. BeanDefinitionCustomizer[] var13 = customizers;
    28. var10 = customizers.length;
    29. for(var11 = 0; var11 < var10; ++var11) {
    30. BeanDefinitionCustomizer customizer = var13[var11];
    31. customizer.customize(abd);
    32. }
    33. }
    34. BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
    35. definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    36. //去设置别名等操作 最后的所有bean都会被放到一个set集合
    37. BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
    38. }
    39. }

    所有的bean 都会被放到 

    AnnotationConfigServletWebServerApplicationContext
    private final Set> annotatedClasses; (应该吧什么时候初始化还没看到来)

  • 相关阅读:
    shell脚本之正则表达式
    LOGO特训营 第三节 首字母创意手法
    【深度学习】基于YOLOV5模型的图像识别-目标检测的性能指标详解与计算方法
    (定时器/计数器)&中断系统(详解与使用)
    大数据Doris(七):Doris安装与部署规划
    【课程作业】西瓜书 机器学习课后习题 : 第六章
    选择种植常规水稻?谋定·国稻种芯:为什么农民放弃杂交水稻
    笙默考试管理系统-MyExamTest----codemirror(35)
    Android Studio 实现登录注册-源代码 (连接MySql数据库)
    RS485协议和Modbus协议有什么区别?工业网关能用吗?
  • 原文地址:https://blog.csdn.net/weixin_38845058/article/details/134413459