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接口。
BeanFactory:接口定义了基本的Ioc容器的基本方法
eg:getBean(String name),containsBean(String name),isSingleton(String name),getAliases(String name),获取bean,判断作用域,获取别名等方法。
BeanFactory的三个子接口分别为HierarchicalBeanFactory,AutowireCapableBeanFactory,ListableBeanFactoryHierarchicalBeanFactory(分层):使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类
step2:DefaultBeanDefinitionDocumentReader源码116行,doRegisterBeanDefinitions方法,用BeanDefinitionParserDelegate 处理委托类去解析Document中的Element。
step3:DefaultBeanDefinitionDocumentReader源码178行,parseDefaultElement方法
根据处理委托类,解析xml中的bean,根据标签的名称调用相应的处理方法。
step4:DefaultBeanDefinitionDocumentReader源码294行,processBeanDefinition方法
生成BeanDefinition的持有者,将BeanDefinition的持有者和defaultListableBeanFactory传入registerBeanDefinition方法中,将BeanDefinition注册到defaultListableBeanFactory中
3.3
TestBean testBean = (TestBean)defaultListableBeanFactory.getBean("testBean");
此句代码通过bean名称通过newInstance得到相应的对象。
step1: AbstractBeanFactory类 234行 doGetBean方法,
从BeanFactory实例中回去“testBean”名称的BeanDefinition实例。根据名称在单例注册表中查找时候有缓存,没有则创建bean,添加到缓存中。
step2:AbstractAutowireCapableBeanFactory类中446行createBean,1008行createBeanInstance方法
此段代码是Class.forName()的应用,加载beanName的Class文件
根据不同方式去实例化bean(本博客走的是默认构造器)
step3:AbstractAutowireCapableBeanFactory类中1085行instantiateBean方法
根据实例化策略(SimpleInstantiationStrategy)去实例化具体的bean,返回bean的包装类BeanWrapper
step4:SimpleInstantiationStrategy类中 59行 instantiate方法
获取具体类的构造函数对具体类进行实例化。
本博客是自己学习源码理解,理解的程度不深。如果有不正确的地方或遗漏的地方。请各位多多指点。