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实例也是在该方法中,一种单例模式,一种是原型模式

	// 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);
				}

  

 

01-05 00:31
查看更多