spring源码解读
1、IOC(控制反转)、AOP(切面)、DI (依赖注入)是spring的核心部分Spring是一种设计思想的体现,发生了“主从换位”的变化。应用程序由主动的创建对象,转换称了从IOC容器里获取对象,对象的创建、解析和注册都由Spring来替用户实现,用户只管定义。2、IoC容器的设计与实现--Bean组件与Context组件使用Spring时,它首先替我们完成的时IOC容器的...
1、IOC(控制反转)、AOP(切面)、DI (依赖注入)是spring的核心部分
Spring是一种设计思想的体现,发生了“主从换位”的变化。应用程序由主动的创建对象,转换称了从IOC容器里获取对象,对象的创建、解析和注册都由Spring来替用户实现,用户只管定义。
2、IoC容器的设计与实现--Bean组件与Context组件
使用Spring时,它首先替我们完成的时IOC容器的初始化,初始化的过程包括定义(BeanDefinition)、载入定义(loadBeanDefinitions,包含了解析的方法)、注册定义(registerBeanDefinitions),注册最后落实到代码中就是
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);
this.beanDefinitionMap.put(beanName, beanDefinition);
注册到map集合中, 将BeanName作为键, BeanDefinition作为值保存。接下来看具体的源码,加深IOC容器初始化的过程理解
2.1Bean组件
bean组件在Spring的org.springframework.beans包下。IOC容器的初始化就在这个包里完成的,定义、载入、注册,对于使用者来说只要完成bean的定义就可以了,其他两个由 Spring 在内部帮我们完成了,对我们来说是透明的。
bean的定义我们不多说,可以用配置文件定义bean,也可以用注解的方式,接下来我们看下Spring的做了那些操作:
2.1.2 BeanFactory概述
BeanFactory是Spring bean容器的根接口.提供获取bean,是否包含bean,是否单例与原型,获取bean类型,bean 别名的方法 。
2.1.3BeanFactory的继承关系
我们可以看到DefaultListableBeanFactory 是最终的实现类,它实现了所有的接口,它也是Spring框架里核心的类之一
2.1.4BeanDefinition概述
BeanDefinition是一个接口类,Bean 的定义主要由 BeanDefinition 实现,项目启动首先是读取bean的xml配置文件,然后解析xml文件中的各种bean的定义,将xml文件中的每一个<bean />元素分别转换解析成一个BeanDefinition对象,其中保存了从配置文件中读取到的该bean的各种信息,以后所有的操作都是对这个对象的操作。
2.1.5 BeanDefinitionReader概述
BeanDefinitionReader同样也是接口类,读取xml配置文件,解析为BeanDefinition对象过程是繁琐的,整个解析过程主要通过下图中的类完成:
2.1.6BeanDefinitionHolder概述
BeanDefinitionHolder是一个class实现类,BeanDefinitionHolder对象中持有的BeanDefinition实例的引用,还有beanName,还有bean的别名
先对这几个类有个大体的了解,接下来从源码中看它们实际的作用。
2.1.7Bean Definition从加载、解析、处理、注册到BeanFactory的过程,也就是IOC容器的初始化过程
- Bean Definition加载
用配置文件的方式定义bean ,首先要做的就是读取xml文件public static void main(String[] args){//直接使用BeanFactory 作为容器 String xmlPath = "applicationContext.xml"; BeanFactory factory = new XmlBeanFactory(new ClassPathResource(xmlPath)); userService = (UserService) factory.getBean("userService"); userService.add(); }
在XmlBeanDefinitionReader类中 &1.loadBeanDefinitions方法从xml文件中加载beanDefinition,将Resource转化为EncodedResource对象,交给它的重载方法来做加载前的准备,实际去加载xml文件的是方法doLoadBeanDefinitions(InputSource inputSource, Resource resource), public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException{ .... return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); .... } &2.doLoadBeanDefinitions方法中加载得到一个Document对象,把Document和resource交给registerBeanDefinitions完成注册 protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource){ .... Document doc = doLoadDocument(inputSource, resource); return registerBeanDefinitions(doc, resource); .... } &3.registerBeanDefinitions(Document doc, Resource resource)方法,这里实际上是创建了一个BeanDefinitionDocumentReader对象然后让它来完成。public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader(); int countBefore = getRegistry().getBeanDefinitionCount(); documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); return getRegistry().getBeanDefinitionCount() - countBefore; }
- Bean Definition解析
在DefaultBeanDefinitionDocumentReader类中
DefaultBeanDefinitionDocumentReader 是BeanDefinitionDocumentReader的实现类,这个类来实际的解析<bean/>标签
&1.registerBeanDefinitions()也做的前期准备,真正去解析文件的方法是doRegisterBeanDefinitions()
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
....
doRegisterBeanDefinitions(root);
}
&2.doRegisterBeanDefinitions方法将</beans>节点下的每一个<bean/>相对应的bean definition注册。但是真正做这件事的是另一个方法 parseBeanDefinitions(root, this.delegate);
&3.<beans/>中还包含<bean/>元素,需要对bean元素进行解析,protected void doRegisterBeanDefinitions(Element root){ .... parseBeanDefinitions(root, this.delegate); .... }
parseBeanDefinitions方法中调用来
parseDefaultElement方法来完成对<bean/>元素的解析,具体分解析过程有processBeanDefinition(ele, delegate)方法来实现,就是对beanDefinition的处理。 - Bean Definition处理
在DefaultBeanDefinitionDocumentReader类中
&1.processBeanDefinition方法中将Element对象转化成了BeanDefinitionHolder对象。这个BeanDefinitionHolder对象中持有的BeanDefinition实例的引用,还有beanName,还有bean的别名。
然后将BeanDefinitionHolder对象和特定的bean工厂作为参数交给BeanDefinitionReaderUtils类来处理来进行注册。到了实际的注册步骤啦protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); if (bdHolder != null) { bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { // Register the final decorated instance. BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); } catch (BeanDefinitionStoreException ex) { getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, ex); } // Send registration event. getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); } }
- Bean Definition注册
在BeanDefinitionReaderUtils类中public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {// Register bean definition under primary name.
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());// Register aliases for bean name, if any.
DefaultListableBeanFactory类中,在这个方法中,将BeanDefinition 注册到了ConcurrentHashMap对象中了。注册完成
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
参考:
更多推荐
所有评论(0)