spring原始碼學習筆記之容器的基本實現(一)
This will typically be used by application contexts to register * dependencies that are resolved in other ways, like BeanFactory through * BeanFactoryAware or ApplicationContext through ApplicationContextAware. *
By default, only the BeanFactoryAware interface is ignored.
* For further types to ignore, invoke this method for each type.
* @see org.springframework.beans.factory.BeanFactoryAware
* @see org.springframework.context.ApplicationContextAware
*/
public void ignoreDependencyInterface(Class> ifc) {
//放入集合
this.ignoredDependencyInterfaces.add(ifc);
}
```
將傳入的值方法一個set集合(對就是ignoredDependencyInterfaces這個集合).
第二步過濾部分的原始碼
```
/**
* Return an array of non-simple bean properties that are unsatisfied.
* These are probably unsatisfied references to other beans in the
* factory. Does not include simple properties like primitives or Strings.
* @param mbd the merged bean definition the bean was created with
* @param bw the BeanWrapper the bean was created with
* @return an array of bean property names
* @see org.springframework.beans.BeanUtils#isSimpleProperty
*/
protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
// 方法的第一個引數AbstractBeanDefinition mbd 可以理解為2.1.1舉的例子類A
// 聲明瞭一個集合
Set This implementation excludes properties defined by CGLIB and
* properties whose type matches an ignored dependency type or which
* are defined by an ignored dependency interface.
* @param pd the PropertyDescriptor of the bean property
* @return whether the bean property is excluded
* @see #ignoreDependencyType(Class)
* @see #ignoreDependencyInterface(Class)
*/
protected boolean isExcludedFromDependencyCheck(PropertyDescriptor pd) {
return (AutowireUtils.isExcludedFromDependencyCheck(pd) ||
this.ignoredDependencyTypes.contains(pd.getPropertyType()) ||
// 這裡使用了第一步存入的集合
AutowireUtils.isSetterDefinedInInterface(pd, this.ignoredDependencyInterfaces));
}
```
看條件 AutowireUtils.isSetterDefinedInInterface(pd, this.ignoredDependencyInterfaces),這裡使用了我們第一步存入的集合,接近真相了,繼續追蹤
```
/**
* Return whether the setter method of the given bean property is defined
* in any of the given interfaces.
* @param pd the PropertyDescriptor of the bean property pd就是某個物件的一個屬性
* @param interfaces the Set of interfaces (Class objects)
* @return whether the setter method is defined by an interface
*/
public static boolean isSetterDefinedInInterface(PropertyDescriptor pd, Set Creates a new instance of the parser class and invokes
* {@code registerBeanDefinitions} on it.
* @param doc the DOM document
* @param resource the resource descriptor (for context information)
* @return the number of bean definitions found
* @throws BeanDefinitionStoreException in case of parsing errors
* @see #loadBeanDefinitions
* @see #setDocumentReaderClass
* @see BeanDefinitionDocumentReader#registerBeanDefinitions
*/
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
//1. 生成BeanDefinitionDocumentReader
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
// 返回註冊列表中註冊的bean的數量
int countBefore = getRegistry().getBeanDefinitionCount();
//2. 通過生成的BeanDefinitionDocumentReader註冊beanDefinition
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
// 這裡返回的是新註冊的bean的數量
//3. 返回最新的註冊的bean的數量
return getRegistry().getBeanDefinitionCount() - countBefore;
}
```
registerBeanDefinitions(Document doc, Resource resource)主要做了三件事:
1. 生成BeanDefinitionDocumentReader
```
private Class extends BeanDefinitionDocumentReader> documentReaderClass =
DefaultBeanDefinitionDocumentReader.class;
/**
* Create the {@link BeanDefinitionDocumentReader} to use for actually
* reading bean definitions from an XML document.
* The default implementation instantiates the specified "documentReaderClass".
* @see #setDocumentReaderClass
*/
protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() {
return BeanUtils.instantiateClass(this.documentReaderClass);
}
```
可以看出這裡生成的BeanDefinitionDocumentReader實際上是DefaultBeanDefinitionDocumentReader型別的
2. 通過生成的BeanDefinitionDocumentReader註冊beanDefinition(也就是我們下一節要分析的主角)
```
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
```
這裡要留意一下createReaderContext(resource)方法
```
/**
* Create the {@link XmlReaderContext} to pass over to the document reader.
*/
public XmlReaderContext createReaderContext(Resource resource) {
return new XmlReaderContext(resource, this.problemReporter, this.eventListener,
this.sourceExtractor, this, getNamespaceHandlerResolver());
}
```
注意第五個引數this,相當於把自己(XmlBeanDefinitionReader)也傳遞給了BeanDefinitionDocumentReader,方便後續呼叫
3. 返回最新的註冊的bean的數量
```
return getRegistry().getBeanDefinitionCount() - countBefore;
```
這裡的getRegistry()是哪裡來的,當時有點懵,找了一會才明白... 是這麼來的
```
public class XmlBeanFactory extends DefaultListableBeanFactory {
// 看XmlBeanDefinitionReader構造方法的引數this
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
/**
* Create a new XmlBeanFactory with the given resource,
* which must be parsable using DOM.
* @param resource XML resource to load bean definitions from
* @throws BeansException in case of loading or parsing errors
*/
public XmlBeanFactory(Resource resource) throws BeansException {
this(resource, null);
}
/**
* Create a new XmlBeanFactory with the given input stream,
* which must be parsable using DOM.
* @param resource XML resource to load bean definitions from
* @param parentBeanFactory parent bean factory
* @throws BeansException in case of loading or parsing errors
*/
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
super(parentBeanFactory);
this.reader.loadBeanDefinitions(resource);
}
}
```
嗯... 答案就在XmlBeanDefinitionReader的構造方法中
```
/**
* Create new XmlBeanDefinitionReader for the given bean factory.
* @param registry the BeanFactory to load bean definitions into,
* in the form of a BeanDefinitionRegistry
*/
public XmlBeanDefinitionReader(BeanDefinitionRegistry registry) {
super(registry);
}
```
這裡劃重點,因為後續得到的BeanDefinition還需要使用registry(實際上是XmlBeanFactory)去註冊BeanDefinition
XmlBeanDefinitionReader實現的功能到這裡告一段落了, 進入下一個類DefaultBeanDefinitionDocumentReader
### 2.3 DefaultBeanDefinitionDocumentReader
```
/**
* This implementation parses bean definitions according to the "spring-beans" XSD
* (or DTD, historically).
* Opens a DOM Document; then initializes the default settings
* specified at the {@code 、