Spring源码分析IOC实现一BeanFactory

Spring源码分析IOC实现一BeanFactory

1. BeanFactory

Spring Ioc中最核心的接口BeanFactory和ApplicationContext 一般BeanFactory是Spring内部使用的而ApplicationContext是对开发者使用的。通常BeanFactory称为Ioc容器,ApplicationContext 称为Spring容器。
通常我们学习时候创建BeanFactory通常代码如下。

//1 创建 默认的DefaultListableBeanFactory
DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
//2 通过Spring 的Resource接口加载classpath下的配置文件
Resource resource = new ClassPathResource("test.xml");
//3 创建BeanDefinition的读取器 将beanFactory 做为参数
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(defaultListableBeanFactory);
// 4 通过xmlBeanDefinitionReader 加载xml中所配置的bean标签中的类,
// 并且创建BeanDefintion类放入beanFactory中
xmlBeanDefinitionReader.loadBeanDefinitions(resource);
// 5 从beanFactory 得到xml中配置的bean,第一次加载时,通过反射创建bean
// 并且缓存(Singleton 作用域)。第二次从缓存中取bean
TestBean testBean =(TestBean)defaultListableBeanFactory.getBean("testBean");
        testBean.sayHello();

2.BeanFactory接口

这里只分析BeanFacoty相关接口,排除ApplicationContext接口。
BeanFacoty相关结构

  • BeanFactory:接口定义了基本的Ioc容器的基本方法
    eg:getBean(String name),containsBean(String name),isSingleton(String name),getAliases(String name),获取bean,判断作用域,获取别名等方法。
    BeanFactory的三个子接口分别为HierarchicalBeanFactory,AutowireCapableBeanFactory,ListableBeanFactory

  • HierarchicalBeanFactory(分层):使BeanFactory具有双亲容器的功能。
    eg:getParentBeanFactory(),containsLocalBean(String name)得到父容器,是否包含某个容器

  • AutowireCapableBeanFactory(能自动装配):这个接口为BeanFactory实现了自动装配功能。
    eg:createBean(Class beanClass),根据Class创建bean,autowireBean(Object existingBean)自动装配bean实例,configureBean(Object existingBean, String beanName)根据给的实例,名称配置bean等方法。

  • ListableBeanFactory(可列表):使BeanFactory具有可列表性,可枚举所有的bean实例
    eg: getBeanDefinitionNames()返回工厂中定义的所有bean的名称findAnnotationOnBean(String beanName, Class<\A> annotationType) 在指定的bean上找注释类型的注释。

    从类图接口可以看出多层次接口定义最终实现的是DefaultListableBeanFactory 主要的类。我们从HierarchicalBeanFactory向下查看继承结构。
    
  • ConfigurableBeanFactory(可配置):提供了配置BeanFactory功能。
    eg:setParentBeanFactory(BeanFactory parentBeanFactory) 设置父BeanFactory,
    setBeanClassLoader(ClassLoader beanClassLoader);设置bean的加载器
    setTypeConverter(TypeConverter typeConverter);设置类型转换器
    setCacheBeanMetadata(boolean cacheBeanMetadata); 是否需要缓存bean metadata
    setBeanExpressionResolver(BeanExpressionResolver resolver); bean definition的表达式解析器
    setConversionService(ConversionService conversionService); 类型转化器
    addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);属性编辑器
    addBeanPostProcessor(BeanPostProcessor beanPostProcessor); Bean处理器
    registerScope(String scopeName, Scope scope); 作用域定义等等。
    同时继承了HierarchicalBeanFactory 和 SingletonBeanRegistry 这两个接口,即同时继承了分层和单例类注册的功能。
  • ConfigurableListableBeanFactory(可列表的配置):提供给可列表的容器的配置功能。
    eg:ignoreDependencyType(Class<\?> type);忽略自动连接的给定依赖类型:
    registerResolvableDependency(Class<\?> dependencyType, Object autowiredValue);给依赖注册一个自动装配类型。等等。

    BeanFactory所有的接口都分析完了,接下来就是三个具体类AbstractBeanFactory,AbstractAutowireCapableBeanFactory,DefaultListableBeanFactory。
    
  • AbstractBeanFactory:继承了FactoryBeanRegistrySupport实现ConfigurableBeanFactory接口
    AbstractBeanFactory实现了ConfigurableBeanFactory接口,而ConfigurableBeanFactory接口继承了HierarchicalBeanFactory,BeanFactory接口。
    所以AbstractBeanFactory 抽象类有 基本,双亲,可配置 容器的相关属性和方法实现。

  • AbstractAutowireCapableBeanFactory:继承了AbstractBeanFactory并实现AutowireCapableBeanFactory接口
    AbstractAutowireCapableBeanFactory具有AbstractBeanFactory相关特性以外,还具有可装配特性。

DefaultListableBeanFactory 继承了 AbstractAutowireCapableBeanFactory实现ConfigurableListableBeanFactory, BeanDefinitionRegistry
DefaultListableBeanFactory 是最终的实现类它具有BeanFactory所有的特性。还实现了BeanDefinitionRegistry bean定义注册接口。

3.源码分析

3.1
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(defaultListableBeanFactory);
//内部源码
    protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) {
        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        this.registry = registry;
        // Determine ResourceLoader to use.
        if (this.registry instanceof ResourceLoader) {
            this.resourceLoader = (ResourceLoader) this.registry;
        }
        else {
            this.resourceLoader = new PathMatchingResourcePatternResolver();
        }
        // Inherit Environment if possible
        if (this.registry instanceof EnvironmentCapable) {
            this.environment = ((EnvironmentCapable) this.registry).getEnvironment();
        }
        else {
            this.environment = new StandardEnvironment();
        }
    }

首先看此段代码源码:
1.DefaultListableBeanFactory实现了BeanDefinitionRegistry,AliasRegistry接口,具有对bean定义(beanDefinition),别名(alias)的注册和删除相关功能。
2.并将defaultListableBeanFactory对象赋值到xmlBeanDefinitionReader(bean定义读取器)中。


3.2
xmlBeanDefinitionReader.loadBeanDefinitions(resource);

此句代码通过xmlBeanDefinitionReader类读取resource资源中的配置,将resource中的<\bean>标签读取出来,并且注册到defaultListableBeanFactory中。
顺序:加载—注册—解析—处理—注册到defaultListableBeanFactory中
源码太多只列出关键部分
step1:XmlBeanDefinitionReader源码388行,doLoadBeanDefinitions方法。
将Resource资源加载成Document类进行注册BeanDefinition类
1
step2:DefaultBeanDefinitionDocumentReader源码116行,doRegisterBeanDefinitions方法,用BeanDefinitionParserDelegate 处理委托类去解析Document中的Element。
2
step3:DefaultBeanDefinitionDocumentReader源码178行,parseDefaultElement方法
根据处理委托类,解析xml中的bean,根据标签的名称调用相应的处理方法。
3
step4:DefaultBeanDefinitionDocumentReader源码294行,processBeanDefinition方法
生成BeanDefinition的持有者,将BeanDefinition的持有者和defaultListableBeanFactory传入registerBeanDefinition方法中,将BeanDefinition注册到defaultListableBeanFactory中
4
5


3.3
TestBean testBean = (TestBean)defaultListableBeanFactory.getBean("testBean");

此句代码通过bean名称通过newInstance得到相应的对象。
step1: AbstractBeanFactory类 234行 doGetBean方法,
1
从BeanFactory实例中回去“testBean”名称的BeanDefinition实例。根据名称在单例注册表中查找时候有缓存,没有则创建bean,添加到缓存中。
step2:AbstractAutowireCapableBeanFactory类中446行createBean,1008行createBeanInstance方法
22
此段代码是Class.forName()的应用,加载beanName的Class文件
2
根据不同方式去实例化bean(本博客走的是默认构造器)
step3:AbstractAutowireCapableBeanFactory类中1085行instantiateBean方法
3
根据实例化策略(SimpleInstantiationStrategy)去实例化具体的bean,返回bean的包装类BeanWrapper
step4:SimpleInstantiationStrategy类中 59行 instantiate方法
4
5
获取具体类的构造函数对具体类进行实例化。

本博客是自己学习源码理解,理解的程度不深。如果有不正确的地方或遗漏的地方。请各位多多指点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值