1.实现将DefaultListableBeanFactory类注入到当前AbstractBeanDefinitionReader中
2.取出xml内容,并生成beanfinition实例对象,注入到DefaultListableBeanFactory类中的map中。
package org.springframework.beans.factory.xml;
import cn.hutool.core.util.StrUtil;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.util.StringUtils;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanReference;
import org.springframework.beans.factory.supper.AbstractBeanDefinitionReader;
import org.springframework.beans.factory.supper.BeanDefinitionRegistry;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
public static final String BEAN_ELEMENT = "bean";
public static final String PROPERTY_ELEMENT = "property";
public static final String ID_ATTRIBUTE = "id";
public static final String NAME_ATTRIBUTE = "name";
public static final String CLASS_ATTRIBUTE = "class";
public static final String VALUE_ATTRIBUTE = "value";
public static final String REF_ATTRIBUTE = "ref";
public static final String INIT_METHOD_ATTRIBUTE = "init-method";
public static final String DESTROY_METHOD_ATTRIBUTE = "destroy-method";
public static final String SCOPE_ATTRIBUTE = "scope";
public static final String LAZYINIT_ATTRIBUTE = "lazyInit";
public static final String BASE_PACKAGE_ATTRIBUTE = "base-package";
public static final String COMPONENT_SCAN_ELEMENT = "component-scan";
public XmlBeanDefinitionReader(BeanDefinitionRegistry registry) {
super(registry);
}
public XmlBeanDefinitionReader(BeanDefinitionRegistry registry, ResourceLoader resourceLoader) {
super(registry, resourceLoader);
}
@Override
public void loadBeanDefinitions(Resource resource) throws BeansException {
try {
InputStream inputStream = resource.getInputStream();
doLoadBeanDefinitions(inputStream);
} catch (IOException | DocumentException ex) {
throw new BeansException("IOException parsing XML document from " + resource, ex);
}
}
@Override
public void loadBeanDefinitions(String location) throws BeansException {
ResourceLoader resourceLoader = getResourceLoader();
Resource resource = resourceLoader.getResource(location);
loadBeanDefinitions(resource);
}
public void doLoadBeanDefinitions(InputStream inputStream) throws DocumentException {
SAXReader reader = new SAXReader();
Document document = reader.read(inputStream);
Element root = document.getRootElement();
//自动扫描组件
Element scanComponent = root.element(COMPONENT_SCAN_ELEMENT);
if (scanComponent != null) {
String backPackage = scanComponent.attributeValue(BASE_PACKAGE_ATTRIBUTE);
if (StrUtil.isNotEmpty(backPackage)) {
scanPackage(backPackage);
}
}
//扫描bean
List<Element> beanList = root.elements(BEAN_ELEMENT);
for (Element bean : beanList) {
String beanId = bean.attributeValue(ID_ATTRIBUTE);
String beanName = bean.attributeValue(NAME_ATTRIBUTE);
String className = bean.attributeValue(CLASS_ATTRIBUTE);
String initMethodName = bean.attributeValue(INIT_METHOD_ATTRIBUTE);
String destroyMethodName = bean.attributeValue(DESTROY_METHOD_ATTRIBUTE);
String beanScope = bean.attributeValue(SCOPE_ATTRIBUTE);
String lazyInit = bean.attributeValue(LAZYINIT_ATTRIBUTE);
Class<?> clazz;
try {
//寻找class类
clazz = Class.forName(className);
} catch (ClassNotFoundException e) {
throw new BeansException("Cannot find class [" + className + "]");
}
//ID优先name
beanName = StrUtil.isNotEmpty(beanId) ? beanId : beanName;
if (StrUtil.isEmpty(beanName)) {
beanName = StrUtil.lowerFirst(clazz.getSimpleName());
}
//生成bean实例
BeanDefinition beanDefinition = new BeanDefinition(clazz);
//设置初始化init-methods
beanDefinition.setInitMethodName(initMethodName);
//初始化销毁方式
beanDefinition.setDestroyMethodName(destroyMethodName);
//设置beanScope
if (StrUtil.isNotEmpty(beanScope)) {
beanDefinition.setScope(beanScope);
}
//设置类的属性
List<Element> propertyList = bean.elements(PROPERTY_ELEMENT);
for (Element propertyItem : propertyList) {
String propertyNameAttribute = propertyItem.attributeValue(NAME_ATTRIBUTE);
String propertyValueAttribute = propertyItem.attributeValue(VALUE_ATTRIBUTE);
String propertyRefAttribute = propertyItem.attributeValue(REF_ATTRIBUTE);
//类设置的属性值不能为空
if (StrUtil.isEmpty(propertyNameAttribute)) {
throw new BeansException("The name attribute cannot be null or empty");
}
//如果是实例引用,则引入对象
Object value = propertyValueAttribute;
if (StrUtil.isNotEmpty(propertyRefAttribute)) {
//组装参考示例
value = new BeanReference(propertyRefAttribute);
}
//追加bean属性内容
PropertyValue propertyValue = new PropertyValue(propertyNameAttribute, value);
beanDefinition.getPropertyValues().addPropertyValues(propertyValue);
}
//类名不能相同
if (getRegistry().containsBeanDefinition(beanName)) {
//beanName不能重名
throw new BeansException("Duplicate beanName[" + beanName + "] is not allowed");
}
//向DefaultListableBeanFactory中的Map注册
getRegistry().registerBeanDefinition(beanName,beanDefinition);
}
}
/**
* 自动扫描组件目录
*
* @param scanPath
*/
public void scanPackage(String scanPath) {
}
}
3.AbstractBeanDefinitionReader:实现调用注册接口去操作bean相关操作
package org.springframework.beans.factory.supper;
import org.springframework.beans.factory.BeansException;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
public abstract class AbstractBeanDefinitionReader implements BeanDefinitionReader {
private final BeanDefinitionRegistry registry;
private ResourceLoader resourceLoader;
public AbstractBeanDefinitionReader(BeanDefinitionRegistry definitionRegistry, ResourceLoader resourceLoader) {
this.registry = definitionRegistry;
this.resourceLoader = resourceLoader;
}
public AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, new DefaultResourceLoader());
}
@Override
public BeanDefinitionRegistry getRegistry() {
return registry;
}
@Override
public void loadBeanDefinitions(String[] locations) throws BeansException {
for (String location : locations) {
loadBeanDefinitions(location);
}
}
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
@Override
public ResourceLoader getResourceLoader() {
return resourceLoader;
}
}
4.测试
标签:xml,String,spring,org,bean,ATTRIBUTE,import,public,加载 From: https://www.cnblogs.com/jichenghui/p/17935730.html