BestMeのブログ -2ページ目

BestMeのブログ

ブログの説明を入力します。

BeanFactory bf = new XmlBeanFactory(new ClassPathResource("beanFactoryTest.xml"));をきっかけ
(3.1からXmlBeanFactoryは非推奨になったのでXmlBeanDefinitionReaderにする)
XmlBeanDefinitionReader
役割
XmlリソースからBeanの定義情報を取り込む。
親interfaceのBeanDefinitionReaderのloadBeanDefinitionsがメインメソッド、この中から、doLoadBeanDefinitionsを呼び出して、

●ソース
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
//EncodedResourceの役割はEncodedResource.classのgetReaderメソッド(次を見てください)からわかる
return loadBeanDefinitions(new EncodedResource(resource));
}

//charsetが指定された場合、該当charsetを使ってInputStreamReaderを生成
public Reader getReader() throws IOException {
if (this.charset != null) {
return new InputStreamReader(this.resource.getInputStream(), this.charset);
}
else if (this.encoding != null) {
return new InputStreamReader(this.resource.getInputStream(), this.encoding);
}
else {
return new InputStreamReader(this.resource.getInputStream());
}
}

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
...
Document doc = doLoadDocument(inputSource, resource);
return registerBeanDefinitions(doc, resource);
...
}

//xmlを解析して、DOMオブジェクトを生成
protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {
//ここのdocumentLoaderはnew DefaultDocumentLoader();でした
//もちろんsetDocumentLoaderによって、設定できるけど
//内部的に、標準のJAXP-configured XML parserを利用して、DOMオブジェクトを取得
return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,
getValidationModeForResource(resource), isNamespaceAware());
}


//前で生成したDOMを使って、実際のBEANを生成
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
int countBefore = getRegistry().getBeanDefinitionCount();
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}

public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader {
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
logger.debug("Loading bean definitions");
Element root = doc.getDocumentElement();
doRegisterBeanDefinitions(root);
}

//<beans/>を始め、すべてのBeanをRegister
protected void doRegisterBeanDefinitions(Element root) {
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)) {
return;
}
}
}

//継承されるため、残っておく
preProcessXml(root);
//実際の処理、次を進む
parseBeanDefinitions(root, this.delegate);
//継承されるため、残っておく
postProcessXml(root);

this.delegate = parent;
}

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;
if (delegate.isDefaultNamespace(ele)) {
parseDefaultElement(ele, delegate);
}
else {
//カスタマイズタグの解析
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}


//この三つのデフォルトのタグの場合、parseDefaultElementを使って解析する
//<import resource="classpath:xxx" />  
//<bean id="xxx" class="xxx.xxx.xxx" />  
//<alias name="xxxx" alias="yyyyy"/>  
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);
}
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
doRegisterBeanDefinitions(ele);
}
}

//beanタグに対して
//<bean id="xxx" class="xxx.xxx.xxx" /> 
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// ここから本番
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
}