spring源码之bean解析
程序员文章站
2022-12-23 17:33:00
源码分析入口: ......
源码分析入口:
beanfactory bf = new xmlbeanfactory(new classpathresource("bean.xml")); person p = bf.getbean("person", person.class);//创建bean的引用对象
1. new classpathresource("bean.xml")
|-- interface inputstreamsource |-- inputstream getinputstream(); |-- resource extends inputstreamsource |-- boolean exists(); // 存在性 |-- boolean isreadable(); // 可读性 |-- boolean isopen(); // 是否处于打开状态 |-- classpathresource implements resource{ @override inputstream getinputstream() { if (this.clazz != null){ is = this.clazz.getresourceasstream(this.path); } else { is = this.classloader.getresourceasstream(this.path); } } } |-- filesystemresource implements resource{ @override inputstream getinputstream() { return new fileinputstream(this.file); } } ...
2. new xmlbeanfactory(new classpathresource("bean.xml"))
|-- xmlbeanfactory(resource resource, beanfactory parentbeanfactory) |-- super(parentbeanfactory) { // 忽略给定接口的自动装配 super(); ignoredependencyinterface(beannameaware.class); ignoredependencyinterface(beanfactoryaware.class); ignoredependencyinterface(beanclassloaderaware.class); } |-- this.reader.loadbeandefinitions(resource) { // 通过属性来记录已经加载的资源 this.resourcecurrentbeingloaded -> new threadlocal<set<encodedresource>>; set<encodedresource> currentresources = this.resourcecurrentbeingloaded.get(); ... // 真正处理业务 return doloadbeandefinitions(inputsource, encodedresource.getresource()); } |-- doloadbeandefinitions(inputsource, encodedresource.getresource()) { // 加载xml文件得到对应的document document doc = doloaddocument(inputsource, resource); // 根据返回的document对象注册bean信息 registerbeandefinitions(doc, resource) { // 使用默认的defaultbeandefinitiondocumentreader实例化beandefinitiondocumentreader beandefinitiondocumentreader documentreader = createbeandefinitiondocumentreader(); // 记录统计前beandefiniton的加载个数 int countbefore = getregistry().getbeandefinitioncount(); // 加载及注册bean documentreader.registerbeandefinitions(doc, createreadercontext(resource)) { this.readercontext = readercontext; element root = doc.getelement(); doregisterbeandefinitions(root) { // 处理profile if (root.getelement("profile").hastext()) ... // 专门处理解析 beandefinitionparserdelegate parent = this.delegate; this.delegate = createhelper(readercontext, root, parent); // begin preprocessxml(root); // 钩子方法 parsebeandefinitions(root, this.delegate) { // 对beans的处理 if (delegate.isdefaultnamespace(root)) { // 默认标签 nodelist nl = root.getchildnodes(); for (int i = 0; i < nl.length(); i++) { node node = nl.item(i); if (node instanceof element) { element ele = (element) node; // 对bean的处理 parsedefaultelement(ele, delegate) { // 对import标签处理 if (delegate.nodenameequals(ele, import_element)){ importbeandefinitionresource(ele); } // 对alias标签处理 else if (delegate.nodenameequals(ele, alias_element)){ processaliasregistration(ele); } // 对bean标签处理 else if (delegate.nodenameequals(ele, bean_element)){ processbeandefinition(ele, delegate) { // 委托beandefinitionparserdelegate类解析,bdholder实例包含class、name、id、alias之类的属性 beandefinitionholder bdholder = delegate.parsebeandefinitionelement(ele) { // 解析id属性 string id = ele.getattribute(id_attribute); // 解析name属性 string nameattr = ele.getattribute(name_attribute); // 分割name属性 list<string> aliases = new arraylist<string>(); if (stringutils.haslength(aliases)) { string[] namearr = stringutils.tokenizedtostringarray(nameattr, ","); aliases.addall(namearr); } string beanname = id; if (!stringutils.hastext(beanname) && !aliases.isempty()) { beanname = aliases.remove(0); //?? } if (containingbean == null) { checknameuniqueness(beanname, aliases, ele); } // 进一步解析其他所有属性并统一封装至genericbeandefinition abstractbeanparsebeandefinition beandefinition = parsebeandefinitionelement(ele, beanname, containingbean) { try { this.parsestate.push(new beanentry(beanname)); string classname = null; // 解析class属性 if (ele.hasattribute(class_attribute)) { classname = ele.getattribute(class_attribute).trim(); } // 解析parent属性 string parent = null; if (ele.hasattribute(parent_attribute)) { parent = ele.getattribute(parent_attribute).trim(); } // 创建用于属性承载的beandefinition abstractbeandefinition bd = createbeandefinition(classname, parent) { beandefinitionreaderutils.createbeandefinition(parentname, classname, this.readercontext.getbeanclassloader()) { genericbeandefinition bd = new genericbeandefinition(); // parentname可能为空 bd.setparentname(parentname); if (classname != null) { if (classloader != null) { bd.setbeanclass(classutil.forname(classname, classloader)); } else { bd.setbeanclassname(classname); } } return bd; } } // 硬编码解析默认的bean属性 parsebeandefinitionattributes(ele, beanname, containingbean, bd) { // 解析scope属性 // 解析singleton属性 bd.setscope(ele.getattribute(scope_attribute) || ele.getattribute(singleton_attribute) || containingbean.getscope()); // 解析abstract属性 bd.setabstract(ele.getattribute(abstract_attribute)); // 解析lazy-init属性 bd.setlazyinit(lazy-init); // 解析autowire属性 // 解析dependency-check属性 // 解析dependency-on属性 // 解析autowire-candidate属性 // 解析primary属性 // 解析init-method属性 // 解析detory-method属性 // 解析factory-method属性 // 解析factory-bean属性 ... } // 提取description bd.setdescription(domutils.getchildelementvaluebytagname(ele, description_element)); // 解析元数据 parsemetaelements(ele, bd); // 解析lookup-method parselookupoverriedsubelements(ele, bd.getmethodoverries()); // 解析replacted-method属性 parsereplactedmethodsubelements(ele, bd.getmethodoverries()); // 解析构造函数参数 parseconstructorargelements(ele, bd); // 解析property子元素 parsepropertyelements(ele, bd); // 解析qualifier子元素 parsequalifierelements(ele, bd); bd.setresource(this.readercontext.getresource()); bd.setsource(extractsource(ele)); return bd; } catch (e) { throw e; } finally { this.parsestate.pop(); } return null; } if (beandefinition != null) { if (!stringutils.hastext(beanname)) { // 未指定beanname,使用默认规则为此bean生成beanname if (containingbean != null) { // 不存在name beanname = beandefinitionreaderutils.generatebeanname(beandefinition, this.readercontext.getregistry(), true); } else { beanname = this.readercontext.generatebeanname(beandefinition); string beanclassname = beandefinition.getbeanclassname(); if (beanclassname != null && beanname.startswith(beanclassname) && beanname.length() > beanclassname.length() && !this.readercontext.getregistry().isbeannameinuse(beanclassname)) { aliases.add(beanclassname); } } } // 将获取到的信息封装到beandefinitionholder中 string[] aliasesarray = stringutils.tostringarray(aliases); return new beandefinitionholder(beandefinition, beanname, aliasesarray); } return null; } if (bdholder != null) { // bdholder不为空情况下,若存在默认标签的子节点下再有自定义属性,还需要再次注册 bdholder = delegate.decoratebeandefinitionifrequired(ele, bdholder); try { // 注册操作委托beandefinitionreaderutils.registerbeandefinition方法 beandefinitionreaderutils.registerbeandefinition(bdholder, getreadercontext().getregistry()); } catch (e) { throw e; } // 发出响应事件,通知想关的监听器,这个bean已经加载完成了 getreadercontext().firecomponentregistered(new beancomponentdefinition(bdholder)); } } } // 对beans标签处理 else if (delegate.nodenameequals(ele, nested_beans_element)){ doregisterbeandefinitions(ele); } } } else { // 对bean的处理 delegate.parsecustomelement(ele); } } } else { // 用户自定义标签 // 对bean的处理 delegate.parsecustomelement(ele); } } postprocessxml(root); // 钩子方法 // end this.delegate = parent; } } // 记录本次加载的beandefinition个数 return getregistry().getbeandefinitioncount() - countbefore; } }
上一篇: 菜鸟学Python第一天
下一篇: 解决sqlserver数据库显示单个用户
推荐阅读
-
Spring中Bean的生命周期使用解析
-
JSP 开发之Spring Boot 动态创建Bean
-
spring5 源码深度解析----- 被面试官给虐懵了,竟然是因为我不懂@Configuration配置类及@Bean的原理
-
Spring学习之Bean的装配多种方法
-
Spring MVC源码(三) ----- @RequestBody和@ResponseBody原理解析
-
基于Spring注解的上下文初始化过程源码解析(一)
-
Spring源码解析之ConfigurableApplicationContext
-
angularjs 源码解析之injector
-
angularjs 源码解析之scope
-
SpringBoot 源码解析 (七)----- Spring Boot的核心能力 - SpringBoot如何实现SpringMvc的?