【小家Spring】AbstractAutowireCapableBeanFactory#populateBean实现Bean的属性赋值和initializeBean对Bean的初始化(下)

简介: 【小家Spring】AbstractAutowireCapableBeanFactory#populateBean实现Bean的属性赋值和initializeBean对Bean的初始化(下)

invokeAwareMethods:相关Aware接口为:BeanNameAware、BeanClassLoaderAware、BeanFactoryAware

这些都是spring将数据暴露出去的一种方式,我们直接实现这个接口就能拿到了~


  private void invokeAwareMethods(final String beanName, final Object bean) {
    if (bean instanceof Aware) {
      if (bean instanceof BeanNameAware) {
        ((BeanNameAware) bean).setBeanName(beanName);
      }
      if (bean instanceof BeanClassLoaderAware) {
        ClassLoader bcl = getBeanClassLoader();
        if (bcl != null) {
          ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
        }
      }
      if (bean instanceof BeanFactoryAware) {
        ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
      }
    }
  }


applyBeanPostProcessorsBeforeInitialization的重要实现解释如下:


//ApplicationContextAwareProcessor:核心处理为
  private void invokeAwareInterfaces(Object bean) {
    if (bean instanceof Aware) {
      if (bean instanceof EnvironmentAware) {
        ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
      }
      if (bean instanceof EmbeddedValueResolverAware) {
        ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
      }
      if (bean instanceof ResourceLoaderAware) {
        ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
      }
      if (bean instanceof ApplicationEventPublisherAware) {
        ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
      }
      if (bean instanceof MessageSourceAware) {
        ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
      }
      if (bean instanceof ApplicationContextAware) {
        ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
      }
    }
  }
//BeanValidationPostProcessor:对bean进行数据校验
  @Override
  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    if (!this.afterInitialization) {
      doValidate(bean);
    }
    return bean;
  }
//BootstrapContextAwareProcessor
  @Override
  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    if (this.bootstrapContext != null && bean instanceof BootstrapContextAware) {
      ((BootstrapContextAware) bean).setBootstrapContext(this.bootstrapContext);
    }
    return bean;
  }
//ServletContextAwareProcessor:
  @Override
  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    if (getServletContext() != null && bean instanceof ServletContextAware) {
      ((ServletContextAware) bean).setServletContext(getServletContext());
    }
    if (getServletConfig() != null && bean instanceof ServletConfigAware) {
      ((ServletConfigAware) bean).setServletConfig(getServletConfig());
    }
    return bean;
  }
//LoadTimeWeaverAwareProcessor
  @Override
  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    if (bean instanceof LoadTimeWeaverAware) {
      LoadTimeWeaver ltw = this.loadTimeWeaver;
      if (ltw == null) {
        Assert.state(this.beanFactory != null,
            "BeanFactory required if no LoadTimeWeaver explicitly specified");
        ltw = this.beanFactory.getBean(
            ConfigurableApplicationContext.LOAD_TIME_WEAVER_BEAN_NAME, LoadTimeWeaver.class);
      }
      ((LoadTimeWeaverAware) bean).setLoadTimeWeaver(ltw);
    }
    return bean;
  }
//InitDestroyAnnotationBeanPostProcessor:处理声明周期注解方法的处理器。有了它,就允许用注解代替去实现Spring的接口InitializingBean和DisposableBean了。
//比如@PostConstruct和@PreDestroy等
  @Override
  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
    try {
      metadata.invokeInitMethods(bean, beanName);
    }
    catch (InvocationTargetException ex) {
      throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
    }
    catch (Throwable ex) {
      throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
    }
    return bean;
  }


applyBeanPostProcessorsAfterInitialization的重要实现解释如下:


image.png


Aop相关的几个实现,这里先不做解释,等到后面AOP文章会专门解析~~~~~~


//ApplicationListenerDetector:把所有的ApplicationListener的Bean,都加入到addApplicationListener里面,放到广播器里面
  @Override
  public Object postProcessAfterInitialization(Object bean, String beanName) {
    if (bean instanceof ApplicationListener) {
      // potentially not detected as a listener by getBeanNamesForType retrieval
      Boolean flag = this.singletonNames.get(beanName);
      if (Boolean.TRUE.equals(flag)) {
        // singleton bean (top-level or inner): register on the fly
        this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
      }
      else if (Boolean.FALSE.equals(flag)) {
        if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
          // inner bean with other scope - can't reliably process events
          logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
              "but is not reachable for event multicasting by its containing ApplicationContext " +
              "because it does not have singleton scope. Only top-level listener beans are allowed " +
              "to be of non-singleton scope.");
        }
        this.singletonNames.remove(beanName);
      }
    }
    return bean;
  }
//BeanValidationPostProcessor:校验
  @Override
  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    if (this.afterInitialization) {
      doValidate(bean);
    }
    return bean;
  }
//ScheduledAnnotationBeanPostProcessor:解析方法中标注有@Scheduled注解的 然后加入当作一个任务进行执行
  @Override
  public Object postProcessAfterInitialization(final Object bean, String beanName) {
    Class<?> targetClass = AopProxyUtils.ultimateTargetClass(bean);
    if (!this.nonAnnotatedClasses.contains(targetClass)) {
      Map<Method, Set<Scheduled>> annotatedMethods = MethodIntrospector.selectMethods(targetClass,
          (MethodIntrospector.MetadataLookup<Set<Scheduled>>) method -> {
            Set<Scheduled> scheduledMethods = AnnotatedElementUtils.getMergedRepeatableAnnotations(
                method, Scheduled.class, Schedules.class);
            return (!scheduledMethods.isEmpty() ? scheduledMethods : null);
          });
      if (annotatedMethods.isEmpty()) {
        this.nonAnnotatedClasses.add(targetClass);
        if (logger.isTraceEnabled()) {
          logger.trace("No @Scheduled annotations found on bean class: " + bean.getClass());
        }
      }
      else {
        // Non-empty set of methods
        annotatedMethods.forEach((method, scheduledMethods) ->
            scheduledMethods.forEach(scheduled -> processScheduled(scheduled, method, bean)));
        if (logger.isDebugEnabled()) {
          logger.debug(annotatedMethods.size() + " @Scheduled methods processed on bean '" + beanName +
              "': " + annotatedMethods);
        }
      }
    }
    return bean;
  }
//SimpleServletPostProcessor:这个很有意思。 相当于当Servlet是以Bean的形式注入容器的时候,Bean初始化完成后,会自动调用它的init方法~~~~~~~~
//如果config为null,那么它传入可能为代理的DelegatingServletConfig
  @Override
  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    if (bean instanceof Servlet) {
      ServletConfig config = this.servletConfig;
      if (config == null || !this.useSharedServletConfig) {
        config = new DelegatingServletConfig(beanName, this.servletContext);
      }
      try {
        ((Servlet) bean).init(config);
      }
      catch (ServletException ex) {
        throw new BeanInitializationException("Servlet.init threw exception", ex);
      }
    }
    return bean;
  }



整个初始化流程如下

1.调用各类感知Aware接口


2.执行applyBeanPostProcessorsBeforeInitialization初始化前的 处置操作


3.调用InitializingBean接口初始化 (如果配置了method-init,则调用其方法初始化 )


4.调用applyBeanPostProcessorsAfterInitialization 初始化之后的处置操作


总结


populateBean和initializeBean完成了我们Spring IOC容器的核心内容:依赖注入。前面做的都是非常非常多的准备工作,同时这里也调用了可以参与Bean生命周期的各种钩子方法。

Spring非常非常优秀的一个设计:是我前面强调过多次的职责单一原则,每一个功能,甚至每一个步骤都由特殊的处理器(或者工具类)来完成。优秀的设计,成就了Spring它的扩展能力极强,我们甚至可以在不知道Spring原理的情况下,流畅的使用它的各项功能。(比如Spring AOP、声明式事务、Schedule等等)

相关文章
|
14天前
|
XML Java 测试技术
Spring IOC—基于注解配置和管理Bean 万字详解(通俗易懂)
Spring 第三节 IOC——基于注解配置和管理Bean 万字详解!
95 26
|
2月前
|
XML 安全 Java
|
2月前
|
存储 Java Spring
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
|
2月前
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
|
2月前
|
XML Java 数据格式
Spring容器Bean之XML配置方式
通过对以上内容的掌握,开发人员可以灵活地使用Spring的XML配置方式来管理应用程序的Bean,提高代码的模块化和可维护性。
73 6
|
2月前
|
XML Java 数据格式
🌱 深入Spring的心脏:Bean配置的艺术与实践 🌟
本文深入探讨了Spring框架中Bean配置的奥秘,从基本概念到XML配置文件的使用,再到静态工厂方式实例化Bean的详细步骤,通过实际代码示例帮助读者更好地理解和应用Spring的Bean配置。希望对你的Spring开发之旅有所助益。
157 3
|
2月前
|
安全 Java 开发者
Spring容器中的bean是线程安全的吗?
Spring容器中的bean默认为单例模式,多线程环境下若操作共享成员变量,易引发线程安全问题。Spring未对单例bean做线程安全处理,需开发者自行解决。通常,Spring bean(如Controller、Service、Dao)无状态变化,故多为线程安全。若涉及线程安全问题,可通过编码或设置bean作用域为prototype解决。
50 1
|
8月前
|
Java 开发者 Spring
解析Spring中Bean的生命周期
解析Spring中Bean的生命周期
73 2
|
8月前
|
XML druid Java
Spring5系列学习文章分享---第二篇(IOC的bean管理factory+Bean作用域与生命周期+自动装配+基于注解管理+外部属性管理之druid)
Spring5系列学习文章分享---第二篇(IOC的bean管理factory+Bean作用域与生命周期+自动装配+基于注解管理+外部属性管理之druid)
91 0
|
4月前
|
Java 开发者 Spring
Spring bean的生命周期详解!
本文详细解析Spring Bean的生命周期及其核心概念,并深入源码分析。Spring Bean是Spring框架的核心,由容器管理其生命周期。从实例化到销毁,共经历十个阶段,包括属性赋值、接口回调、初始化及销毁等。通过剖析`BeanFactory`、`ApplicationContext`等关键接口与类,帮助你深入了解Spring Bean的管理机制。希望本文能助你更好地掌握Spring Bean生命周期。
231 1