专栏首页码农架构Spring 源码脉络IOC/DI-容器的拓展

Spring 源码脉络IOC/DI-容器的拓展

通常,应用程序开发人员不需要为ApplicationContext实现类子类。相反,Spring IoC容器可以通过插入特殊集成接口的实现来扩展。接下来的将描述这些集成接口

1BeanFactory

2ApplicationContext

3Bean创建过程

4容器扩展

5、感知接口 *Aware

6、广播与监听

7、资源

8、运行环境抽象

Spring 容器的拓展三步走

  • 后置处理器 BeanPostProcessor
  • 后置BeanFactory处理器 BeanFactoryPostPorcessor
  • FactoryBean

分割线


1️⃣ 后置Bean处理器 BeanPostProcessor

应用程序上下文可以在其bean定义中自动检测BeanPostProcessor类型的bean,并将它们应用于随后创建的任何bean

  • 针对具体的bean进行处理
public interface BeanPostProcessor {
    Object postProcessBeforeInitialization(Object bean, String beanName) 
      throws BeansException;
    Object postProcessAfterInitialization(Object bean, String beanName) 
      throws BeansException;
}
调用逻辑
AbstractAutowireCapableBeanFactory.initializeBean
注册逻辑
PostProcessorRegistrationDelegate.registerBeanPostProcessors
  • MergedBeanDefinitionPostProcessor
void postProcessMergedBeanDefinition(
        RootBeanDefinition beanDefinition, 
        Class<?> beanType, 
        String beanName
);  
  • AutowiredAnnotationBeanPostProcessor 实现AutoWired注解的注入
  • InstantiationAwareBeanPostProcesso

BeanPostProcessor的子接口,它添加实例化之前的调用,以及在实例化之后但在设置显式属性或自动装配之前进行的调用。 通常用于抑制特定目标Bean的默认实例化,例如创建具有特殊TargetSource的代理(池目标,延迟初始化目标等),或实现其他注入策略,例如字段注入。

  • **AwareProcessor 实现感知接口
    • ApplicationContextAwareProcessor
    • ServletContextAwareProcessor
  • ScheduledAnnotationBeanPostProcessor

思维导图

2️⃣ 后置BeanFactory处理器 BeanFactoryPostPorcessor

  • 允许自定义修改应用程序上下文的bean定义,调整bean的属性
  • 自动检测,并在创建任何非BeanFactoryPostProcessor类型bean之前应用它们
调用逻辑:
AbstractApplicationContext.refresh()
AbstractApplicationContext.invokeBeanFactoryPostProcessors
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors
执行顺序:
先执行继承了BeanDefinitionRegistryPostProcessor接口的,再执行继承了BeanFactoryPostProcessor接口的实现;
先执行继承了PriorityOrdered的类,再执行继承了Ordered的类,最后执行其他的
  • BeanDefinitionRegistryPostProcessor bean注册处理器
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
    void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) 
      throws BeansException;
}

BeanDefinitionRegistry ,该类的作用主要是向注册表中注册 BeanDefinition 实例,完成 注册的过程。

public interface BeanDefinitionRegistry extends AliasRegistry {

    // 关键 -> 往注册表中注册一个新的 BeanDefinition 实例
    void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException;

    // 移除注册表中已注册的 BeanDefinition 实例
    void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

    // 从注册中取得指定的 BeanDefinition 实例
    BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

    // 判断 BeanDefinition 实例是否在注册表中(是否注册)
    boolean containsBeanDefinition(String beanName);

    // 取得注册表中所有 BeanDefinition 实例的 beanName(标识)
    String[] getBeanDefinitionNames();

    // 返回注册表中 BeanDefinition 实例的数量
    int getBeanDefinitionCount();

    // beanName(标识)是否被占用
    boolean isBeanNameInUse(String beanName);

}
  • 动态代理接口并注册到Spring容器
  • Mybatis mapper接口动态代理实现,MapperScannerConfigurer+MapperFactoryBean

3️⃣ FactoryBean

public interface FactoryBean<T> {
  //获取当前工厂创建的对象实例
  T getObject() throws Exception;
  //实例类型
  Class<?> getObjectType();
  //是否单例
  boolean isSingleton();
}
  • 自定义实例化逻辑
  • Mybatis mapper 接口动态代理实现,MapperFactoryBean

本文分享自微信公众号 - 码农架构(iByteCoding),作者:小码

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-04-16

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Kafka线上集群部署方案怎么做?

    Kafka 集群方案该怎么做。既然是集群,那必然就要有多个 Kafka 节点机器,因为只有单台机器构成的 Kafka 伪集群只能用于日常测试之用,根本无法满足实...

    码农架构
  • 深入浅出FaaS的两种进程模型

    上一篇我们通过一个 Node.js 纯 FaaS 的 Serverless 应用,给你介绍了 Serverless 引擎盖下的运作机制,总结来说,FaaS 依赖...

    码农架构
  • Apache Kafka 真的只是消息引擎吗?

    纵观 Kafka 的发展脉络,它的确是从消息引擎起家的,但正如文章标题所问,Apache Kafka 真的只是消息引擎吗?通常,在回答这个问题之前很多文章可能就...

    码农架构
  • 1044. 火星数字(20)

    地球人的0被火星人称为tret。 地球人数字1到12的火星文分别为:jan, feb, mar, apr, may, jun, jly, aug, sep,...

    AI那点小事
  • 引入Option优雅地保证健壮性

    REA的Ken Scambler在其演讲《2 Year of Real World FP at REA》中,总结了选择函数式编程的三个原因:Modularity...

    张逸
  • Spring IOC 容器源码分析 - 填充属性到 bean 原始对象

    本篇文章,我们来一起了解一下 Spring 是如何将配置文件中的属性值填充到 bean 对象中的。我在前面几篇文章中介绍过 Spring 创建 bean 的流程...

    田小波
  • 机器学习 - 精度评价

    Python sklearn.metrics 提供了很多任务的评价指标,如分类任务的混淆矩阵、平均分类精度、每类分类精度、总体分类精度、F1-score 等;以...

    AIHGF
  • 又一篇杂记

      很久以前写过一篇感想,当时表达了一些对于Cocos2d-x引擎即将3d化的担忧,之后自己也基本完全投入了Unity3D的怀抱,对于Cocos2d-x(或者现...

    用户2615200
  • 避免云浪费的12个提示

    Cloud Cruiser营销总监Katie Lenahan针对问题提出了以下建议。

    Dainty
  • iOS下JS与OC互相调用(七)--Cordova 基础

    在介绍Cordova之前,必须先提一下PhoneGap。PhoneGap 是Nitobi软件公司2008年推出的一个框架,旨在弥补web 和iOS 之间的不足,...

    Haley_Wong

扫码关注云+社区

领取腾讯云代金券