springロードbeanプロセスのソースコードの簡易解剖
この文章は主にbeanにロードする過程を話します。実はIOCです。控えめです。
大切なものを全部取り出しました。一歩下を見ると、springがbean.xmlに入るという原理が分かります。
候杰のMFCのような感じがします。
観覧ルール
次のコードを表します。
最近上で呼び出されるコードの詳細を表示します。
beanを得る方法については、もちろん皆さんも知っています。一番下の階に行くとmap.getです。
万流が終わりますね。。。。
大切なものを全部取り出しました。一歩下を見ると、springがbean.xmlに入るという原理が分かります。
候杰のMFCのような感じがします。
観覧ルール
次のコードを表します。
最近上で呼び出されるコードの詳細を表示します。
public class XmlBeanFactory extends DefaultListableBeanFactory {
// bean , this , bean , this bean, 。 bean XmlBeanFactory ( DefaultListableBeanFactory)。
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
super(parentBeanFactory);
// xml
this.reader.loadBeanDefinitions(resource); // ->
}
}
public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
//
public int loadBeanDefinitions(Resource resource) throws BeansException {
InputStream is = null;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(this.validating);
DocumentBuilder docBuilder = factory.newDocumentBuilder();
docBuilder.setErrorHandler(this.errorHandler);
if (this.entityResolver != null) {
docBuilder.setEntityResolver(this.entityResolver);
}
is = resource.getInputStream();
// Xerces xml, dom
Document doc = docBuilder.parse(is);
//registerBeanDefinitions dom
return registerBeanDefinitions(doc, resource); //
}
//
public int registerBeanDefinitions(Document doc, Resource resource) throws BeansException {
XmlBeanDefinitionParser parser = (XmlBeanDefinitionParser) BeanUtils.instantiateClass(this.parserClass);
// parserClass DefaultXmlBeanDefinitionParser.class
return parser.registerBeanDefinitions(this, doc, resource); // ->
}
}
public class DefaultXmlBeanDefinitionParser implements XmlBeanDefinitionParser {
// bean.xml ,
public static final String AUTOWIRE_BY_NAME_VALUE = "byName";
public static final String AUTOWIRE_BY_TYPE_VALUE = "byType";
public static final String DEFAULT_LAZY_INIT_ATTRIBUTE = "default-lazy-init";
public static final String DEFAULT_DEPENDENCY_CHECK_ATTRIBUTE = "default-dependency-check";
public static final String DEFAULT_AUTOWIRE_ATTRIBUTE = "default-autowire";
public static final String NAME_ATTRIBUTE = "name";
public static final String ALIAS_ATTRIBUTE = "alias";
public static final String BEAN_ELEMENT = "bean";
public static final String ID_ATTRIBUTE = "id";
public static final String PARENT_ATTRIBUTE = "parent";
public static final String CLASS_ATTRIBUTE = "class";
public static final String SINGLETON_ATTRIBUTE = "singleton";
public static final String LAZY_INIT_ATTRIBUTE = "lazy-init";
public static final String AUTOWIRE_ATTRIBUTE = "autowire";
//...
//
public int registerBeanDefinitions(BeanDefinitionReader reader, Document doc, Resource resource) throws BeanDefinitionStoreException {
this.beanDefinitionReader = reader;
this.resource = resource;;
Element root = doc.getDocumentElement();
//...
// bean
int beanDefinitionCount = parseBeanDefinitions(root);// ->
// beanDefinitionCount <bean></bean>
//...
return beanDefinitionCount;
}
protected int parseBeanDefinitions(Element root) throws BeanDefinitionStoreException {
//Xerces <bean>
NodeList nl = root.getChildNodes();
int beanDefinitionCounter = 0;
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if // ...
//..
else if (BEAN_ELEMENT.equals(node.getNodeName())) {// , bean
beanDefinitionCounter++;
// , 。1. bean BeanDefinitionHolder
BeanDefinitionHolder bdHolder = parseBeanDefinitionElement(ele);// 1.->
//2. XmlBeanFactory
BeanDefinitionReaderUtils.registerBeanDefinition(
bdHolder, this.beanDefinitionReader.getBeanFactory()); // 2. ->
}
}
}
return beanDefinitionCounter;
}
// 1. , , bean,
protected BeanDefinitionHolder parseBeanDefinitionElement(Element ele) throws BeanDefinitionStoreException {
//...
// bean parseBeanDefinitionElement 。 spring bean BeanDefinition BeanDefinition BeanDefinitionHolder
BeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName);//
//...
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
}
// , , <bean> attribute 。
protected BeanDefinition parseBeanDefinitionElement(Element ele, String beanName) throws BeanDefinitionStoreException {
try {
// <bean> <property>, 。
MutablePropertyValues pvs = parsePropertyElements(ele, beanName);
// BeanDefinition AbstractBeanDefinition
AbstractBeanDefinition bd = BeanDefinitionReaderUtils.createBeanDefinition(
className, parent, cargs, pvs, this.beanDefinitionReader.getBeanClassLoader());
//...
return bd;
}
catch (/*...*/)
//...
}
}
}
//bean 。。。。
// 2. , , 。
public class BeanDefinitionReaderUtils {
public static void registerBeanDefinition(
BeanDefinitionHolder bdHolder, BeanDefinitionRegistry beanFactory) throws BeansException {
//beanFactory XmlBeanFactory, DefaultListableBeanFactory registerBeanDefinition
beanFactory.registerBeanDefinition(bdHolder.getBeanName(), bdHolder.getBeanDefinition()); //
//...
}
}
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry {
/** Whether to allow re-registration of a different definition with the same name */
private boolean allowBeanDefinitionOverriding = true;
/** Map of bean definition objects, keyed by bean name */
// bean , Map, 。
private final Map beanDefinitionMap = new HashMap();
// List bean , 。
/** List of bean definition names, in registration order */
private final List beanDefinitionNames = new ArrayList();
//
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
//...
Object oldBeanDefinition = this.beanDefinitionMap.get(beanName);
if (oldBeanDefinition != null) {
// allowBeanDefinitionOverriding bean.xml bean , allowBeanDefinitionOverriding true, 。
if (!this.allowBeanDefinitionOverriding) {
throw new BeanDefinitionStoreException(...);
}
else {
//... bean
}
}
else {
// List bean
this.beanDefinitionNames.add(beanName);
}
// bean map 。 。
this.beanDefinitionMap.put(beanName, beanDefinition);
}
//...
}
//
実際にspringはbean.xmlを一つのmapに解析することです。beanを得る方法については、もちろん皆さんも知っています。一番下の階に行くとmap.getです。
万流が終わりますね。。。。