zoukankan      html  css  js  c++  java
  • spring源码分析

    一、xml中bean的解析

    1,加载配置文件

    BeanFactory bf = new XmlBeanFactory(new ClassPathResource("abc.xml"));

    ClassPathResource中将xml文件封装为Resource类型;然后调用XmlBeanFactory中的XmlBeanDefinitionReader(reader)的方法:this.reader.loadBeanDefinitions(resource)

    真正加载配置资源文件

    loadBeanDefinitions(resource)中,真正加载资源文件doLoadBeanDefinitions(inputSource, encodedResource.getResource());

    doLoadBeanDefinitions(inputSource, encodedResource.getResource())中,首先是验证xml的格式,然后加载resource文件得到对应的Document文件,根据返回的Document对象,

    在registerBeanDefinitions(doc, resource)中注册bean信息。

    public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
    		BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
    //记录统计前的BeanDefinition的加载个数 int countBefore = getRegistry().getBeanDefinitionCount();
    //加载及注册bean(核心)registerBeanDefinitions()

    documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
                    //记录本次加载的BeanDefinition的个数
    		return getRegistry().getBeanDefinitionCount() - countBefore;
    	}
    //加载注册bean的核心方法(其实就是解析xml)
    public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
    this.readerContext = readerContext;
    logger.debug("Loading bean definitions");
    Element root = doc.getDocumentElement();
    doRegisterBeanDefinitions(root);
    }

    //xml中的bean都是在这里加载的
    /**
    * Register each bean definition within the given root {@code <beans/>} element.
    */
    protected void doRegisterBeanDefinitions(Element root) {
    // Any nested <beans> elements will cause recursion in this method. In
    // order to propagate and preserve <beans> default-* attributes correctly,
    // keep track of the current (parent) delegate, which may be null. Create
    // the new (child) delegate with a reference to the parent for fallback purposes,
    // then ultimately reset this.delegate back to its original (parent) reference.
    // this behavior emulates a stack of delegates without actually necessitating one.
    BeanDefinitionParserDelegate parent = this.delegate;
    this.delegate = createDelegate(getReaderContext(), root, parent);

    if (this.delegate.isDefaultNamespace(root)) {
    String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
    if (StringUtils.hasText(profileSpec)) {
    String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
    profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
    if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
    if (logger.isInfoEnabled()) {
    logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec +
    "] not matching: " + getReaderContext().getResource());
    }
    return;
    }
    }
    }

    preProcessXml(root);
    parseBeanDefinitions(root, this.delegate);
    postProcessXml(root);

    this.delegate = parent;
    }

     AbastractBeanDefinition中封装了所有类的xml默认标签配置属性,GenericBeanDefinition是其子类实现,解析xml文件默认标签配置属性的DefaultBeanDefinitionDocumentReader

    processBeanDefinition(),然后调BeanDefinitionParserDelegate的parseBeanDefinitionElement()真正解析xml中的bean配置;

    解析完成之后,注册bean,BeanDefinitionReaderUtils.registerBeanDefinition()

    注册的实质:beanName为key,beanDefinition为value放入map
    /** Map of bean definition objects, keyed by bean name */
    	private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);
    因为beanDefinitionMap是全局变量,之前这里是synchronized(this.beanDefinitionMap);现在spring4以后要ConcurrentHashMap来处理并发问题

     spring源码底层用了大量 反射

    例如

    public NamespaceHandler resolve(String namespaceUri){}这段代码 ,好好看看

    isAssignableFrom()方法与instanceof关键字的区别总结为以下两个点:

    isAssignableFrom()方法是从类继承的角度去判断,instanceof关键字是从实例继承的角度去判断 

    isAssignableFrom()方法是判断是否为某个类的父类,instanceof关键字是判断是否某个类的子类。

    解析自定义xml标签:

    1、创建一个解析器parser 继承AbstractSingleBeanDefinitionParser

    2、创建一个Handler,继承NameSpaceHandlerSupport,重写init方法(引入parser解析器);作用:当遇到自定义标签时,将元素Element丢给自定义得parser解析

    一、bean 的加载

    1、AbstractBeanFactory中的getBean()

    @Override
    	public Object getBean(String name) throws BeansException {
    		return doGetBean(name, null, null, false);
    	}
    

     AbstractBeanFactory中的doGetBean() 

    //该方法时将存储XML配置文件的GenericBeanDefinition转化为RootBeanDefinition
    final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    

     创建bean实例也是在该方法中,一种单例模式,一种是原型模式,大量源码贴上

    protected <T> T doGetBean(
    final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
    throws BeansException {

    final String beanName = transformedBeanName(name);
    Object bean;

    // Eagerly check singleton cache for manually registered singletons.
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
    if (logger.isDebugEnabled()) {
    if (isSingletonCurrentlyInCreation(beanName)) {
    logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
    "' that is not fully initialized yet - a consequence of a circular reference");
    }
    else {
    logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
    }
    }
    bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    else {
    // Fail if we're already creating this bean instance:
    // We're assumably within a circular reference.
    if (isPrototypeCurrentlyInCreation(beanName)) {
    throw new BeanCurrentlyInCreationException(beanName);
    }

    // Check if bean definition exists in this factory.
    BeanFactory parentBeanFactory = getParentBeanFactory();
    if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
    // Not found -> check parent.
    String nameToLookup = originalBeanName(name);
    if (args != null) {
    // Delegation to parent with explicit args.
    return (T) parentBeanFactory.getBean(nameToLookup, args);
    }
    else {
    // No args -> delegate to standard getBean method.
    return parentBeanFactory.getBean(nameToLookup, requiredType);
    }
    }

    if (!typeCheckOnly) {
    markBeanAsCreated(beanName);
    }

    try {
    final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    checkMergedBeanDefinition(mbd, beanName, args);

    // Guarantee initialization of beans that the current bean depends on.
    String[] dependsOn = mbd.getDependsOn();
    if (dependsOn != null) {
    for (String dep : dependsOn) {
    if (isDependent(beanName, dep)) {
    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
    }
    registerDependentBean(dep, beanName);
    try {
    getBean(dep);
    }
    catch (NoSuchBeanDefinitionException ex) {
    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
    }
    }
    }
    // Create bean instance.
    if (mbd.isSingleton()) {
    sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
    @Override
    public Object getObject() throws BeansException {
    try {
    return createBean(beanName, mbd, args);
    }
    catch (BeansException ex) {
    // Explicitly remove instance from singleton cache: It might have been put there
    // eagerly by the creation process, to allow for circular reference resolution.
    // Also remove any beans that received a temporary reference to the bean.
    destroySingleton(beanName);
    throw ex;
    }
    }
    });
    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    }
    else if (mbd.isPrototype()) {
    // It's a prototype -> create a new instance.
    Object prototypeInstance = null;
    try {
    beforePrototypeCreation(beanName);
    prototypeInstance = createBean(beanName, mbd, args);
    }
    finally {
    afterPrototypeCreation(beanName);
    }
    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
    }

    else {
    String scopeName = mbd.getScope();
    final Scope scope = this.scopes.get(scopeName);
    if (scope == null) {
    throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
    }
    try {
    Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
    @Override
    public Object getObject() throws BeansException {
    beforePrototypeCreation(beanName);
    try {
    return createBean(beanName, mbd, args);
    }
    finally {
    afterPrototypeCreation(beanName);
    }
    }
    });
    bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
    }
    catch (IllegalStateException ex) {
    throw new BeanCreationException(beanName,
    "Scope '" + scopeName + "' is not active for the current thread; consider " +
    "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
    ex);
    }
    }
    }
    catch (BeansException ex) {
    cleanupAfterBeanCreationFailure(beanName);
    throw ex;
    }
    }
    // Check if required type matches the type of the actual bean instance.
    if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
    try {
    return getTypeConverter().convertIfNecessary(bean, requiredType);
    }
    catch (TypeMismatchException ex) {
    if (logger.isDebugEnabled()) {
    logger.debug("Failed to convert bean '" + name + "' to required type '" +
    ClassUtils.getQualifiedName(requiredType) + "'", ex);
    }
    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
    }
    }
    return (T) bean;
    }
    //执行顺序
    //1、Object sharedInstance = getSingleton(beanName); 从缓存中获取单例bean
    //2、bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);从bean的实例中获取
    //3、sharedInstance = getSingleton(beanName, new ObjectFactory<Object>();当缓存中没取到单例时,在该方法中从头开始bean加载

      上面的取单例

    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    		Object singletonObject = this.singletonObjects.get(beanName);
    		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
    			synchronized (this.singletonObjects) {
    				singletonObject = this.earlySingletonObjects.get(beanName);
    				if (singletonObject == null && allowEarlyReference) {
    					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
    					if (singletonFactory != null) {
    						singletonObject = singletonFactory.getObject();
    						this.earlySingletonObjects.put(beanName, singletonObject);
    						this.singletonFactories.remove(beanName);
    					}
    				}
    			}
    		}
    		return (singletonObject != NULL_OBJECT ? singletonObject : null);
    	}
    //singeltonObjects :保存beanName和bean实例
    //singletonFactories:保存beanName和bean的工厂
    //earlySingletonObjects: 也是保存beanName和bean实例之间的关系,于singletonObjects的不同之处在于,当一个单例的bean被放到这里之后,那么当bean还在创建过程中,
    就可以通过getBean方法获取到了,其目的是用来检测循环引用

     createBean(beanName, mbd, args);

    protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
    		if (logger.isDebugEnabled()) {
    			logger.debug("Creating instance of bean '" + beanName + "'");
    		}
    		RootBeanDefinition mbdToUse = mbd;
    
    		// Make sure bean class is actually resolved at this point, and
    		// clone the bean definition in case of a dynamically resolved Class
    		// which cannot be stored in the shared merged bean definition.
    		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
    			mbdToUse = new RootBeanDefinition(mbd);
    			mbdToUse.setBeanClass(resolvedClass);
    		}
    
    		// Prepare method overrides.
    		try {
    			mbdToUse.prepareMethodOverrides();
    		}
    		catch (BeanDefinitionValidationException ex) {
    			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
    					beanName, "Validation of method overrides failed", ex);
    		}
    
    		try {
    			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
    			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    			if (bean != null) {
    				return bean;
    			}
    		}
    		catch (Throwable ex) {
    			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
    					"BeanPostProcessor before instantiation of bean failed", ex);
    		}
    
    		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    		if (logger.isDebugEnabled()) {
    			logger.debug("Finished creating instance of bean '" + beanName + "'");
    		}
    		return beanInstance;
    	}
    

      

     

  • 相关阅读:
    Java基础之开发工具Eclipse的使用
    Java基础之身份证验证
    如何理解“程序=算法+数据结构”这句话
    JDBC
    Java与其它语言的比较
    Java整体之JavaEE
    Java项目之项目模板(登录注册)
    二进制
    计算机发展历程
    Spring错误:org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.Bi
  • 原文地址:https://www.cnblogs.com/mmh760/p/11724433.html
Copyright © 2011-2022 走看看