📄 defaultxmlbeandefinitionparser.java
字号:
}
}
}
return beanDefinitionCount;
}
/**
* Parse an "import" element and load the bean definitions
* from the given resource into the bean factory.
*/
protected void importBeanDefinitionResource(Element ele) throws BeanDefinitionStoreException {
String location = ele.getAttribute(RESOURCE_ATTRIBUTE);
// Resolve system properties: e.g. "${user.dir}"
location = SystemPropertyUtils.resolvePlaceholders(location);
if (ResourcePatternUtils.isUrl(location)) {
int importCount = getBeanDefinitionReader().loadBeanDefinitions(location);
if (logger.isDebugEnabled()) {
logger.debug("Imported " + importCount + " bean definitions from URL location [" + location + "]");
}
}
else {
// No URL -> considering resource location as relative to the current file.
try {
Resource relativeResource = getResource().createRelative(location);
int importCount = getBeanDefinitionReader().loadBeanDefinitions(relativeResource);
if (logger.isDebugEnabled()) {
logger.debug("Imported " + importCount + " bean definitions from relative location [" + location + "]");
}
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"Invalid relative resource location [" + location + "] to import bean definitions from", ex);
}
}
}
/**
* Allow the XML to be extensible by processing any custom element types last,
* after we finished processing the bean definitions. This method is a natural
* extension point for any other custom post-processing of the XML.
* <p>Default implementation is empty. Subclasses can override this method to
* convert custom elements into standard Spring bean definitions, for example.
* Implementors have access to the parser's bean definition reader and the
* underlying XML resource, through the corresponding accessors.
* @see #getBeanDefinitionReader()
* @see #getResource()
*/
protected void postProcessXml(Element root) throws BeanDefinitionStoreException {
}
/**
* Parse a standard bean definition into a BeanDefinitionHolder,
* including bean name and aliases.
* <p>Bean elements specify their canonical name as "id" attribute
* and their aliases as a delimited "name" attribute.
* <p>If no "id" specified, uses the first name in the "name" attribute
* as canonical name, registering all others as aliases.
* <p>Callers should specify whether this element represents an inner bean
* definition or not by setting the <code>isInnerBean</code> argument appropriately
*/
protected BeanDefinitionHolder parseBeanDefinitionElement(Element ele, boolean isInnerBean)
throws BeanDefinitionStoreException {
String id = ele.getAttribute(ID_ATTRIBUTE);
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
List aliases = new ArrayList();
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, BEAN_NAME_DELIMITERS);
aliases.addAll(Arrays.asList(nameArr));
}
String beanName = id;
if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
beanName = (String) aliases.remove(0);
if (logger.isDebugEnabled()) {
logger.debug("No XML 'id' specified - using '" + beanName +
"' as bean name and " + aliases + " as aliases");
}
}
BeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName);
if (!StringUtils.hasText(beanName) && beanDefinition instanceof AbstractBeanDefinition) {
beanName = BeanDefinitionReaderUtils.generateBeanName(
(AbstractBeanDefinition) beanDefinition, this.beanDefinitionReader.getBeanFactory(), isInnerBean);
if (logger.isDebugEnabled()) {
logger.debug("Neither XML 'id' nor 'name' specified - " +
"using generated bean name [" + beanName + "]");
}
}
String[] aliasesArray = StringUtils.toStringArray(aliases);
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
}
/**
* Parse the BeanDefinition itself, without regard to name or aliases.
*/
protected BeanDefinition parseBeanDefinitionElement(Element ele, String beanName)
throws BeanDefinitionStoreException {
String className = null;
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
className = ele.getAttribute(CLASS_ATTRIBUTE);
}
String parent = null;
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
try {
ConstructorArgumentValues cargs = parseConstructorArgElements(ele, beanName);
MutablePropertyValues pvs = parsePropertyElements(ele, beanName);
AbstractBeanDefinition bd = BeanDefinitionReaderUtils.createBeanDefinition(
className, parent, cargs, pvs, getBeanDefinitionReader().getBeanClassLoader());
if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, BEAN_NAME_DELIMITERS));
}
if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
}
if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
}
String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE);
if (DEFAULT_VALUE.equals(dependencyCheck)) {
dependencyCheck = getDefaultDependencyCheck();
}
bd.setDependencyCheck(getDependencyCheck(dependencyCheck));
String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
if (DEFAULT_VALUE.equals(autowire)) {
autowire = getDefaultAutowire();
}
bd.setAutowireMode(getAutowireMode(autowire));
if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
if (!"".equals(initMethodName)) {
bd.setInitMethodName(initMethodName);
}
}
else {
if (getDefaultInitMethod() != null) {
bd.setInitMethodName(getDefaultInitMethod());
bd.setEnforceInitMethod(false);
}
}
if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {
String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
if (!"".equals(destroyMethodName)) {
bd.setDestroyMethodName(destroyMethodName);
}
}
else {
if (getDefaultDestroyMethod() != null) {
bd.setDestroyMethodName(getDefaultDestroyMethod());
bd.setEnforceDestroyMethod(false);
}
}
parseLookupOverrideSubElements(ele, beanName, bd.getMethodOverrides());
parseReplacedMethodSubElements(ele, beanName, bd.getMethodOverrides());
bd.setResourceDescription(getResource().getDescription());
if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
}
if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
bd.setSingleton(TRUE_VALUE.equals(ele.getAttribute(SINGLETON_ATTRIBUTE)));
}
String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
if (DEFAULT_VALUE.equals(lazyInit) && bd.isSingleton()) {
// Just apply default to singletons, as lazy-init has no meaning for prototypes.
lazyInit = getDefaultLazyInit();
}
bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
return bd;
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (ClassNotFoundException ex) {
throw new BeanDefinitionStoreException(
getResource(), beanName, "Bean class [" + className + "] not found", ex);
}
catch (NoClassDefFoundError err) {
throw new BeanDefinitionStoreException(
getResource(), beanName, "Class that bean class [" + className + "] depends on not found", err);
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
getResource(), beanName, "Unexpected failure during bean definition parsing", ex);
}
}
protected int getDependencyCheck(String att) {
int dependencyCheckCode = AbstractBeanDefinition.DEPENDENCY_CHECK_NONE;
if (DEPENDENCY_CHECK_ALL_ATTRIBUTE_VALUE.equals(att)) {
dependencyCheckCode = AbstractBeanDefinition.DEPENDENCY_CHECK_ALL;
}
else if (DEPENDENCY_CHECK_SIMPLE_ATTRIBUTE_VALUE.equals(att)) {
dependencyCheckCode = AbstractBeanDefinition.DEPENDENCY_CHECK_SIMPLE;
}
else if (DEPENDENCY_CHECK_OBJECTS_ATTRIBUTE_VALUE.equals(att)) {
dependencyCheckCode = AbstractBeanDefinition.DEPENDENCY_CHECK_OBJECTS;
}
// Else leave default value.
return dependencyCheckCode;
}
protected int getAutowireMode(String att) {
int autowire = AbstractBeanDefinition.AUTOWIRE_NO;
if (AUTOWIRE_BY_NAME_VALUE.equals(att)) {
autowire = AbstractBeanDefinition.AUTOWIRE_BY_NAME;
}
else if (AUTOWIRE_BY_TYPE_VALUE.equals(att)) {
autowire = AbstractBeanDefinition.AUTOWIRE_BY_TYPE;
}
else if (AUTOWIRE_CONSTRUCTOR_VALUE.equals(att)) {
autowire = AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR;
}
else if (AUTOWIRE_AUTODETECT_VALUE.equals(att)) {
autowire = AbstractBeanDefinition.AUTOWIRE_AUTODETECT;
}
// Else leave default value.
return autowire;
}
/**
* Parse constructor-arg sub-elements of the given bean element.
*/
protected ConstructorArgumentValues parseConstructorArgElements(Element beanEle, String beanName)
throws BeanDefinitionStoreException {
NodeList nl = beanEle.getChildNodes();
ConstructorArgumentValues cargs = new ConstructorArgumentValues();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element && CONSTRUCTOR_ARG_ELEMENT.equals(node.getNodeName())) {
parseConstructorArgElement((Element) node, beanName, cargs);
}
}
return cargs;
}
/**
* Parse property sub-elements of the given bean element.
*/
protected MutablePropertyValues parsePropertyElements(Element beanEle, String beanName)
throws BeanDefinitionStoreException {
NodeList nl = beanEle.getChildNodes();
MutablePropertyValues pvs = new MutablePropertyValues();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element && PROPERTY_ELEMENT.equals(node.getNodeName())) {
parsePropertyElement((Element) node, beanName, pvs);
}
}
return pvs;
}
/**
* Parse lookup-override sub-elements of the given bean element.
*/
protected void parseLookupOverrideSubElements(Element beanEle, String beanName, MethodOverrides overrides)
throws BeanDefinitionStoreException {
NodeList nl = beanEle.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element && LOOKUP_METHOD_ELEMENT.equals(node.getNodeName())) {
Element ele = (Element) node;
String methodName = ele.getAttribute(NAME_ATTRIBUTE);
String beanRef = ele.getAttribute(BEAN_ELEMENT);
overrides.addOverride(new LookupOverride(methodName, beanRef));
}
}
}
/**
* Parse replaced-method sub-elements of the given bean element.
*/
protected void parseReplacedMethodSubElements(Element beanEle, String beanName, MethodOverrides overrides)
throws BeanDefinitionStoreException {
NodeList nl = beanEle.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element && REPLACED_METHOD_ELEMENT.equals(node.getNodeName())) {
Element replacedMethodEle = (Element) node;
String name = replacedMethodEle.getAttribute(NAME_ATTRIBUTE);
String callback = replacedMethodEle.getAttribute(REPLACER_ATTRIBUTE);
ReplaceOverride replaceOverride = new ReplaceOverride(name, callback);
// Look for arg-type match elements.
List argTypeEles = DomUtils.getChildElementsByTagName(replacedMethodEle, ARG_TYPE_ELEMENT);
for (Iterator it = argTypeEles.iterator(); it.hasNext();) {
Element argTypeEle = (Element) it.next();
replaceOverride.addTypeIdentifier(argTypeEle.getAttribute(ARG_TYPE_MATCH_ATTRIBUTE));
}
overrides.addOverride(replaceOverride);
}
}
}
/**
* Parse a constructor-arg element.
*/
protected void parseConstructorArgElement(Element ele, String beanName, ConstructorArgumentValues cargs)
throws BeanDefinitionStoreException {
Object val = parsePropertyValue(ele, beanName, null);
String indexAttr = ele.getAttribute(INDEX_ATTRIBUTE);
String typeAttr = ele.getAttribute(TYPE_ATTRIBUTE);
if (StringUtils.hasLength(indexAttr)) {
try {
int index = Integer.parseInt(indexAttr);
if (index < 0) {
throw new BeanDefinitionStoreException(getResource(), beanName, "'index' cannot be lower than 0");
}
if (StringUtils.hasLength(typeAttr)) {
cargs.addIndexedArgumentValue(index, val, typeAttr);
}
else {
cargs.addIndexedArgumentValue(index, val);
}
}
catch (NumberFormatException ex) {
throw new BeanDefinitionStoreException(getResource(), beanName,
"Attribute 'index' of tag 'constructor-arg' must be an integer");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -