Spring_Resource 解析bean过程

Resources

将不同来源的资源抽象成URL,通过注册不同的handler来处理不同来源的资源的读取逻辑。
Resouces接口抽象了所有Spring内部使用到的底层资源。
在resource加载了配置文件之后,将读取配置文件的工作交给了后续的XXXReader。

例子
XmlBeanFactory

1.Resource 获取配置文件资源
2.构造XmlBeanDefinitionReader
3.获取inputStream并构造InputResource
4.调用核心方法doLoadBeanDefinitions
this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());

doLoadBeanDefinitions(){
1.获取对XML文件的验证模式。
getValidationModeForResource
2.加载XML文件,并得到对应的Document。
this.doLoadDocument(inputSource, resource);
3.根据返回的Document注册Bean信息。
this.registerBeanDefinitions(doc, resource);
}

registerBeanDefinitions

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
		//创建子类,DefaultBeanDefinitionDocumentReader
		//BeanDefinitionDocumentReader 重要的在于提取root
        BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader();
        int countBefore = this.getRegistry().getBeanDefinitionCount();
        //此处的registerBeanDefinitions其实是调用BeanDefinitionDocumentReader的doRegisterBeanDefinitions()
        documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
        return this.getRegistry().getBeanDefinitionCount() - countBefore;
    }

doRegisterBeanDefinitions
核心解析类

protected void doRegisterBeanDefinitions(Element root) {
        BeanDefinitionParserDelegate parent = this.delegate;
        this.delegate = this.createDelegate(this.getReaderContext(), root, parent);
        if (this.delegate.isDefaultNamespace(root)) {
            String profileSpec = root.getAttribute("profile");
            if (StringUtils.hasText(profileSpec)) {
                String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, ",; ");
                //应该是判断当前的环境是否支持这种profile
                if (!this.getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
                    if (this.logger.isDebugEnabled()) {
                        this.logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + this.getReaderContext().getResource());
                    }

                    return;
                }
            }
        }
		
		//空实现 ,模板方法 ,交给子类选择处理
        this.preProcessXml(root);
        //核心解析类
        this.parseBeanDefinitions(root, this.delegate);
        //空实现 ,模板方法 ,交给子类选择处理
        this.postProcessXml(root);
        this.delegate = parent;
    }

parseBeanDefinitions

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
        if (delegate.isDefaultNamespace(root)) {
            NodeList nl = root.getChildNodes();

            for(int i = 0; i < nl.getLength(); ++i) {
                Node node = nl.item(i);
                if (node instanceof Element) {
                    Element ele = (Element)node;
                    //判断如果是默认的标签,则使用默认的解析方法
                    //里面有对四种标签属性的解析 import alias bean beans  最常用的为this.processBeanDefinition(ele, delegate);
                    if (delegate.isDefaultNamespace(ele)) {
                        this.parseDefaultElement(ele, delegate);
                    } else {
                   		/否则使用用户自定义的解析方法
                        delegate.parseCustomElement(ele);
                    }
                }
            }
        } else {
            delegate.parseCustomElement(root);
        }
    }

processBeanDefinition

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
		//此处完成了对XML的标签解析,包括bean的id,name.....
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
        if (bdHolder != null) {
        	//bean使用了默认解析方法,但是属性却使用了自定义的标签
            bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);

            try {
            	//将解析完的BeanDeginition注册到BeanDeginitionRegistry	
                BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());
            } catch (BeanDefinitionStoreException var5) {
                this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);
            }

            this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
        }

    }

registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry())
注册BeanDeginition
registry.registerBeanDefinition主要步骤如下:
1.对AbstractBeanDefinition的校验。
2.对beanName已经注册的情况的处理,如果bean不允许被覆盖,则抛出异常,否则直接覆盖。
3.加入map缓存(ConcurrentHashMap,预防并发问题)
4.清除解析之前留下的对应beanName的缓存。

public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
        String beanName = definitionHolder.getBeanName();
        //使用beanName注册BeanDefinition
     	//主要逻辑为将beanDefinition放入map中,beanName作为key
        registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
        //注册所有别名
        String[] aliases = definitionHolder.getAliases();
        if (aliases != null) {
            String[] var4 = aliases;
            int var5 = aliases.length;

            for(int var6 = 0; var6 < var5; ++var6) {
                String alias = var4[var6];
                registry.registerAlias(beanName, alias);
            }
        }

    }

BeanDefinition

在这里插入图片描述
AbstractBeanDefinition里面定了了大量的属性。

public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor implements BeanDefinition, Cloneable {
    public static final String SCOPE_DEFAULT = "";
    public static final int AUTOWIRE_NO = 0;
    public static final int AUTOWIRE_BY_NAME = 1;
    public static final int AUTOWIRE_BY_TYPE = 2;
    public static final int AUTOWIRE_CONSTRUCTOR = 3;
    /** @deprecated */
    @Deprecated
    public static final int AUTOWIRE_AUTODETECT = 4;
    public static final int DEPENDENCY_CHECK_NONE = 0;
    public static final int DEPENDENCY_CHECK_OBJECTS = 1;
    public static final int DEPENDENCY_CHECK_SIMPLE = 2;
    public static final int DEPENDENCY_CHECK_ALL = 3;
    public static final String INFER_METHOD = "(inferred)";
    @Nullable
    private volatile Object beanClass;
    //bean的作用域
    @Nullable
    private String scope;
    private boolean abstractFlag;
    //是否懒加载
    @Nullable
    private Boolean lazyInit;
    private int autowireMode;
    private int dependencyCheck;
    @Nullable
    private String[] dependsOn;
    private boolean autowireCandidate;
    private boolean primary;
    private final Map<String, AutowireCandidateQualifier> qualifiers;
    @Nullable
    private Supplier<?> instanceSupplier;
    private boolean nonPublicAccessAllowed;
    private boolean lenientConstructorResolution;
    @Nullable
    private String factoryBeanName;
    @Nullable
    private String factoryMethodName;
    @Nullable
    private ConstructorArgumentValues constructorArgumentValues;
    @Nullable
    private MutablePropertyValues propertyValues;
    private MethodOverrides methodOverrides;
    @Nullable
    private String initMethodName;
    @Nullable
    private String destroyMethodName;
    private boolean enforceInitMethod;
    private boolean enforceDestroyMethod;
    private boolean synthetic;
    private int role;
    @Nullable
    private String description;
    @Nullable
    private Resource resource;

	......
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值