请选择 进入手机版 | 继续访问电脑版
搜索
房产
装修
汽车
婚嫁
健康
理财
旅游
美食
跳蚤
二手房
租房
招聘
二手车
教育
茶座
我要买房
买东西
装修家居
交友
职场
生活
网购
亲子
情感
龙城车友
找美食
谈婚论嫁
美女
兴趣
八卦
宠物
手机

九、Spring之BeanFactory源码分析(一)

[复制链接]
查看: 64|回复: 0

1万

主题

2万

帖子

4万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
46386
发表于 2019-11-9 16:01 | 显示全部楼层 |阅读模式
Spring之BeanFactory源码分析(一)

留意:该漫笔内容完全引自https://blog.csdn.net/u014634338/article/details/82865644,写的很好,很是感激,复制过来算是个积聚,怕今后找不到。
BeanFactory

BeanFactory供给的是最底子的IOC容器的功用,BeanFactory 只是一个接口类,并没有给出容器的具体实现,固然,它有差别的实现类,来界说大要扩大某个功用。这篇文章的配角就是它啦。
启动IOC容器

下面是一段简单的代码,经过编程启动IOC 容器:
  1. public void TestDefaultListableBeanFactory(){  ClassPathResource resource  = new ClassPathResource("spring.xml");  DefaultListableBeanFactory factory = new DefaultListableBeanFactory();  XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);  reader.loadBeanDefinitions(resource);  MyBean bean = factory.getBean(MyBean.class);  System.out.println(bean.toString());}
复制代码
spring.xml 设备文件里面很简单:
  1. [/code]这样,我们便可以经过factory工具来操纵DefaultListableBeanFactory 这个IOC容器了,在操纵IOC容器时,必要以下步伐:
  2. 1)建立IOC设备文件的笼统资本,即设备文件
  3. 2)建立一个BeanFactory,这里操纵DefaultListableBeanFactory
  4. 3)建立一个载入BeanDefinition的读取器,这里操纵XmlBeanDefinitionReader 来载入XML文件形式的BeanDefinition。
  5. 4)从界说好的资本位置读取设备信息,具体的分析进程由XmlBeanDefinitionReader 来完成。
  6. 经过一个简短的代码便可以启动spring,焦点就在于DefaultListableBeanFactory,临时就不间接跟踪流程了,还是来看看全部BeanFactory的筹划。
  7. [size=4]BeanFactory 类结构系统[/size]
  8. BeanFactory,从名字上也很好大白,生产治理 bean 的工场(容器),它负责生产和治理各个 bean 实例。
  9. 我们来看下和 BeanFactory 接口关连的重要的继续结构:
  10. [align=center][img]http://img.blog.ztgreat.cn/document/spring/20180913103759.png[/img][/align]
  11. 上面的继续关系去除了现在不必要的类。
  12. emmmmm,这图看着有颔首大,渐渐来,先重要关注左侧部分,梳理一下各个BeanFactory的职能,怎样梳理?,看源码咯。
  13. [size=3]BeanFactory[/size]
  14. BeanFactory 是顶级接口,界说了IOC容器最底子的形式。
  15. [code]public interface BeanFactory {    //这里可以临时不用管    String FACTORY_BEAN_PREFIX = "&";    Object getBean(String name) throws BeansException;    ... //省略此外方式}
复制代码
界说了一些底子接口,例如 获得bean,固然另有一些此外接口,这里就不列出了,必要自己去了解一下。
至于 FACTORY_BEAN_PREFIX 这个其实在这里可以疏忽,这里还是简单提一下,假如不大白也无妨,与BeanFactory很类似的有一个叫FactoryBean的类,从名字上很轻易肴杂,BeanFactory 首先是Factoyr,而FactoryBean 是bean,只是 是一种特别的bean, 这类特别的bean会生产另一种bean, 对于普通的bean,经过BeanFactory 的 getBean方式可以获得这个bean,而对于FactoryBean 来说,经过getBean 获得的是 FactoryBean 生产的bean,而不是FactoryBean 自己,假如想要获得FactoryBean 自己,那末可以加前缀&,那末spring 就大白,本来你是必要FactoryBean 。这个大要会在背面AOP的部分,展开来说,这里就先说这么多了。
ListableBeanFactory
  1. public interface ListableBeanFactory extends BeanFactory {    // 对于给定的名字能否含有BeanDefinition    boolean containsBeanDefinition(String beanName);    // 返回工场的BeanDefinition总数    int getBeanDefinitionCount();        // 返回工场中全数Bean的名字    String[] getBeanDefinitionNames();    // 返回对于指定典范 获得bean的名字    String[] getBeanNamesForType(ResolvableType type);        //获得包含某个注解 bean的名字    String[] getBeanNamesForAnnotation(Class requiredType, Class type);        //疏忽自动装配的接口    void ignoreDependencyInterface(Class ifc);    //返回注册的Bea界说    BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;    Iterator getBeanNamesIterator();    ...//疏忽部分方式}
复制代码
工场接口ConfigurableListableBeanFactory同时继续了3个接口,ListableBeanFactory、AutowireCapableBeanFactory 和 ConfigurableBeanFactory,可以说功用以及很周全了。
对于BeanFactory 系统中左侧部分,大略差不多了,现在看看右半边情况
BeanDefinitionRegistry

望文生义,这个是注册 BeanDefinition的
  1. public interface BeanDefinitionRegistry extends AliasRegistry {    //给定bean称号,注册一个新的bean界说    void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)            throws BeanDefinitionStoreException;    //按照指定Bean名移除对应的Bean界说    void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;    按照指定bean名获得对应的Bean界说    BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;    查找,指定的Bean名能否包含Bean界说    boolean containsBeanDefinition(String beanName);    //返回本容器内全数注册的Bean界说称号    String[] getBeanDefinitionNames();    //指定Bean名能否被注册过。    int getBeanDefinitionCount();   //指定Bean名能否被注册过。    boolean isBeanNameInUse(String beanName);}
复制代码
这个接口很简单,就是对BeanDefinition的操纵,但是我们还没有了解BeanDefinition 的结构,可是并不影响我们分析,由于从名字就晓得这个指代的是一个bean的界说,也就是将xml中的bean 翻译成了具体的数据结构。
现在回过甚来,我们再看看DefaultListableBeanFactory类图
九、Spring之BeanFactory源码分析(一)  游戏 20180913103759

对于左侧部分,则是各类功用的BeanFactory,右侧部分则是对BeanDefinition的功用操纵,中心部分则是单例Bean功用办事,中心部分我们没有分析源代码,可是经过名字我们已经很好的晓得了它的功用,而FactoryBeanRegistrySupport 则表示了对 FactoryBean的支持,(FactoryBean在前面BeanFactory简单提了一下哟)
现在对每个BeanFactory的职能心田大要有谱了,这样在背面的时候,才晓得这个功用属于哪个模块,而不至于脑壳一团浆糊。
对于DefaultListableBeanFactory 我们并没有取分析它,由于DefaultListableBeanFactory 中实现了上面接口中的全数方式,触及了很多细节,从代码角度来看的话,那真的是很难一下分析透,可是假如从功用模块上来看的话,我们也晓得了它大要可以干什么,可以说是一个比力成熟的容器了,既然现在我们晓得了装bean的容器了,那末bean又从那边来呢,固然是xml,可是xml又怎样转换成数据结构的呢,这个就必要回到我们最开的代码了:
  1. public void TestDefaultListableBeanFactory(){  ClassPathResource resource  = new ClassPathResource("spring.xml"); //3  DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); //5  XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);//7  reader.loadBeanDefinitions(resour ce);//9  MyBean bean = factory.getBean(MyBean.class); //11  System.out.println(bean.toString());}
复制代码
现在第5,11行代码我们已经大略清楚了,重要的还剩3,4,9行代码了,这个就先留到背面再来吧。
BeanDefinition

Bean的界说重要由BeanDefinition来描摹的,作为Spring中用于包装Bean的数据结构,先来看看BeanDefinition一个继续结构吧(非完整继续结构)
九、Spring之BeanFactory源码分析(一)  游戏 20180913111748

一个BeanDefinition描摹了一个bean的实例,包含属性值,机关方式参数值和继续自它的类的更多信息。
BeanDefinition 源码浅析
  1. //标准单例感化域 标识符:“singleton”。String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;//标准原型感化域的范围标识符:“prototype”。String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;//表示BeanDefinition是利用步伐重要部分的脚色提醒。 凡是对应于用户界说的bean。int ROLE_APPLICATION = 0;//表示BeanDefinition是某些大型设备的支持部分的脚色提醒,凡是是一个内部ComponentDefinition。//当检察某个特定的ComponentDefinition时,以为bean很是垂危,//以便在检察利用步伐的团体设备时可以也许意想到这一点。int ROLE_SUPPORT = 1;//脚色提醒表白一个BeanDefinition是供给一个完全背景的脚色,而且与终极用户没有关系。
复制代码
ROLE_SUPPORT =1现实上就是说,我这个Bean是用户的,是从设备文件中过来的。
ROLE_INFRASTRUCTURE = 2 就是说 这Bean是Spring自己的,
上面是BeanDifinition的一些底子属性信息,一个就是标识下当前Bean的感化域,此外就是标识一下这个Bean是内部的还是内部的。下面来看这个接口为其子类都供给了哪些具体的活动方式:
1.当前Bean的className get&set方式
  1. //指定此bean界说的bean类称号。//类称号可以在bean factory前期处置惩罚中点窜,凡是用它的分析变体更换本来的类称号。void setBeanClassName(String beanClassName);//返回此bean界说确当前bean类称号。//必要留意的是,这不愿定是在运转时操纵的现实类名,以防子类界说覆盖/继续其父类的类名。//此外,这大要只是挪用工场方式的类,大要它 在挪用方式的工场bean援用的情况下甚至大如果空的。//是以,不要以为这是在运转时界说的bean典范,而只是将其用于在零丁的bean界说级别举行分析。String getBeanClassName();
复制代码
2.Bean的感化域get&set方式
  1. //覆盖此bean的方针范围,指定一个新的范围称号。void setScope(String scope);//返回此bean确当前方针感化域的称号,假如没有肯定,返回nullString getScope();
复制代码
3.懒加载的get&set方式
  1. //设备这个bean能否应当被耽误初始化。假如{false},那末这个bean将在启动时由bean工场实例化,//这些工场尝试单例的立即初始化。//懒加载 void setLazyInit(boolean lazyInit);//返回这个bean能否应当被耽误初始化,即不是在启动时立即实例化。只适用于单例bean。boolean isLazyInit();
复制代码
4.依靠关系设备
  1. //设备这个bean依靠被初始化的bean的名字。 bean工场将保证这些bean首先被初始化。//void setDependsOn(String... dependsOn);//返回这个bean依靠的bean称号。String[] getDependsOn();
复制代码
5.能否是自动转配设备
  1. //设备这个bean能否是获得自动装配到其他bean的候选人。//必要留意是,此标志旨在仅影响基于典范的自动装配。//它不会影响按称号的显式援用,即使指定的bean没有标志为autowire候选,也可以治理这个题目。//是以,假如称号婚配,经过称号的自动装配将注入一个bean。void setAutowireCandidate(boolean autowireCandidate);//返回这个bean能否是自动装配到其他bean的候选者。就是能否在其他类中操纵autowired来注入当前Bean的//能否为被自动装配 boolean isAutowireCandidate();
复制代码
并没有完全罗列 BeanDifinition 中的方式大要属性,大略大白 Bean的界说重要由BeanDefinition来描摹的,作为Spring中用于包装Bean的数据结构便可以了,关于BeanDifinition 的更多接口实现,这个按照自己情况去看看便可以了。
小结

了解了BeanFactory的大略结构后,来看看下面一段简单代码,相信大白就加倍深入了:
  1. public void TestDefaultListableBeanFactory(){  DefaultListableBeanFactory factory = new DefaultListableBeanFactory();  AbstractBeanDefinition beanDefinition = new RootBeanDefinition(MyBean.class);  factory.registerBeanDefinition("myBean",beanDefinition);  //可以经过机关方式注入依靠,固然我们这里没有  //beanDefinition.setConstructorArgumentValues();  //可以经过 setter 方式注入依靠,固然我们这里也没有  //beanDefinition.setPropertyValues();  MyBean bean = factory.getBean(MyBean.class);  System.out.println(bean.toString());}
复制代码
在前面我们用的ClassPathResource,XmlBeanDefinitionReader 从文件中读取的bean设备信息,现在我们晓得了BeanDifinition 以及BeanDefinitionRegistry,那末实在我们可以手动注册BeanDifinition ,这样我在最起头的代码底子上,又再次细分了功用了,条理也加倍的清楚了。
总结

我们从 DefaultListableBeanFactory 动身,大略了解了一下 BeanFactory的系统结构,BeanFactory有三个直系支属:
ListableBeanFactory(可罗列的容器(多格式查询)),HierarchicalBeanFactory(分条理容器,可有父容器),AutowireCapableBeanFactory(自动装配容器),这三个容器界说了BeanFactory的底子脸孔,在这个三个直系支部下面又派生了两个复杂的容器:ConfigurableBeanFactory,ConfigurableListableBeanFactory,可设备的(可操纵)的容器,经过这两个BeanFactory 可有点窜容器中的bean,功用又加倍高级了,集成了单例bean 办事,以及BeanDefinition 注册办事,那末对于 DefaultListableBeanFactory 来说,此时它就是一个可注册,可设备,可获得的BeanFactory ,就容器方面而言功用已经健全了。

免责声明:假如加害了您的权益,请联系站长,我们会实时删除侵权内容,感谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Copyright © 2006-2014 妈妈网-中国妈妈第一,是怀孕、育儿、健康等知识交流传播首选平台 版权所有 法律顾问:高律师 客服电话:0791-88289918
技术支持:迪恩网络科技公司  Powered by Discuz! X3.2
快速回复 返回顶部 返回列表