通过反射机制来实现配置文件的读取spring(含有字段的赋值,构造方法的赋值,set方法的赋值,需要了解一下的我已经把依赖放到文件最后面)
package com.project.Util.TowApplication;
import com.project.Util.ApplicationXmlContext;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.expression.spel.ast.StringLiteral;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MyClassPathXmlApplicationContext implements ApplicationXmlContext {
Map<String, Object> mapObj = new HashMap<>();
static Logger logger = LoggerFactory.getLogger(MyClassPathXmlApplicationContext.class);
public MyClassPathXmlApplicationContext(String XmlPath, Class<?> clazz) throws Exception {
SAXReader saxReader = new SAXReader();
InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(XmlPath);
Document document = saxReader.read(in);
List<Element> list = document.selectNodes("//bean");
for (Element element : list) {
String id = element.attributeValue("id");
String aClass = element.attributeValue("class");
Class<?> clazzs = Class.forName(aClass);
Constructor<?> constructor = clazzs.getDeclaredConstructor();
Object obj = constructor.newInstance();
mapObj.put(id, obj);
}
list.forEach(element -> {
List<Element> propertys = element.elements("property");
List<Element> constructorArg = element.elements("constructor-arg");
String aClass = element.attributeValue("class");
String id = element.attributeValue("id");
Object obj = mapObj.get(id);
Class<?> aClass1 = obj.getClass();
if (propertys.size() != 0) {
propertys.forEach(property -> {
try {
Field field = aClass1.getDeclaredField(property.attributeValue("name"));
field.setAccessible(true);
String value = property.attributeValue("value");
String refValue = property.attributeValue("ref");
String s = property.attributeValue("name").toUpperCase().charAt(0) + property.attributeValue("name").substring(1);
String SetMethod = "set" + s;
boolean ismethodSet = isMethodSet(aClass1, SetMethod, field.getType());
if (value != null) {
String simpleName = field.getType().getSimpleName();
Object oj = value;
switch (simpleName) {
case "int", "Integer":
oj = Integer.parseInt(value);
break;
case "byte", "Byte":
oj = Byte.parseByte(value);
break;
case "boolean", "Boolean":
oj = Boolean.parseBoolean(value);
break;
case "short", "Short":
oj = Short.parseShort(value);
break;
case "double", "Double":
oj = Double.parseDouble(value);
break;
case "float", "Float":
oj = Float.parseFloat(value);
break;
case "char", "CharSet":
oj = Character.valueOf(value.charAt(0));
break;
case "long", "Long":
oj = Long.parseLong(value);
break;
default:
break;
}
if (ismethodSet) {
Method method = aClass1.getDeclaredMethod(SetMethod, field.getType());
method.invoke(obj, oj);
} else {
field.set(obj, oj);
}
}
if (refValue != null) {
if (ismethodSet) {
Method method = aClass1.getDeclaredMethod(SetMethod, field.getType());
method.invoke(obj, mapObj.get(refValue));
} else {
field.set(obj, mapObj.get(refValue));
}
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
throw new RuntimeException(e);
}
});
} else if (constructorArg.size() != 0) {
ConstructorParameters(aClass1, constructorArg, id);
}
});
}
public <T> T getBean(String classPath, Class<T> clazz) {
Object bean = mapObj.get(classPath);
if (clazz.isInstance(bean)) {
return clazz.cast(bean);
} else {
throw new ClassCastException("Bean of type " + clazz.getName() + " not found for path: " + classPath);
}
}
@Deprecated
@Override
public Object getBean(String classPath) {
return mapObj.get(classPath);
}
public static boolean isMethodSet(Class<?> clazz, String pathMethod, Class<?> parameters) {
try {
Method method = clazz.getDeclaredMethod(pathMethod, parameters);
return true;
} catch (NoSuchMethodException e) {
e.getMessage();
return false;
}
}
public void ConstructorParameters(Class<?> clazz, List<Element> elements, String id) {
List<Class<?>> listClass = new ArrayList<>();
List<String> stringList = new ArrayList<>();
elements.forEach(element -> {
String name = element.attributeValue("name");
String value = element.attributeValue("value");
String ref=element.attributeValue("ref");
if (value!=null) {
stringList.add(value);
}
if (ref!=null)
{
stringList.add(ref);
}
try {
Field declaredField = clazz.getDeclaredField(name);
Class<?> fieldType = declaredField.getType();
listClass.add(fieldType);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
});
try {
List<Object> objectList=new ArrayList<>();
Object o=null;
Object o1=null;
Constructor<?> constructor=null;
switch (elements.size()) {
case 1:
Constructor<?> constructor1 = clazz.getDeclaredConstructor(listClass.get(0));
o = parseTypes(stringList.get(0), listClass.get(0).getSimpleName());
o1 = constructor1.newInstance(o);
break;
case 2:
constructor = clazz.getDeclaredConstructor(listClass.get(0), listClass.get(1));
for (int i = 0; i < listClass.size(); i++) {
o = parseTypes(stringList.get(i), listClass.get(i).getSimpleName());
objectList.add(o);
}
o1 = constructor.newInstance(objectList.get(0), objectList.get(1));
break;
case 3:
constructor = clazz.getDeclaredConstructor(listClass.get(0), listClass.get(1),listClass.get(2));
for (int i = 0; i < listClass.size(); i++) {
o = parseTypes(stringList.get(i), listClass.get(i).getSimpleName());
objectList.add(o);
}
o1 = constructor.newInstance(objectList.get(0), objectList.get(1),objectList.get(2));
break;
case 4:
constructor = clazz.getDeclaredConstructor(listClass.get(0), listClass.get(1), listClass.get(2), listClass.get(3));
logger.info(listClass.get(3).toString());
for (int i = 0; i < listClass.size(); i++) {
o = parseTypes(stringList.get(i), listClass.get(i).getSimpleName());
objectList.add(o);
}
logger.info( objectList.get(3).toString());
o1 = constructor.newInstance(objectList.get(0), objectList.get(1), objectList.get(2), objectList.get(3));
break;
}
mapObj.put(id,o1);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("你的构造方法的顺序有问题");
}
}
private Object parseTypes(String value, String simpleName) {
Object oj = value;
switch (simpleName) {
case "int", "Integer":
oj = Integer.parseInt(value);
break;
case "byte", "Byte":
oj = Byte.parseByte(value);
break;
case "boolean", "Boolean":
oj = Boolean.parseBoolean(value);
break;
case "short", "Short":
oj = Short.parseShort(value);
break;
case "double", "Double":
oj = Double.parseDouble(value);
break;
case "float", "Float":
oj = Float.parseFloat(value);
break;
case "char", "CharSet":
oj = Character.valueOf(value.charAt(0));
break;
case "long", "Long":
oj = Long.parseLong(value);
break;
default:
oj=mapObj.get(value);
break;
}
return oj;
}
}
依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>Spring-001</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!--context-->
<dependencies>
<!-- <dependency>-->
<!-- <groupId>org.springframework</groupId>-->
<!-- <artifactId>spring-context</artifactId>-->
<!-- <version>6.1.11</version>-->
<!-- </dependency>-->
<!-- junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<!-- 解析xml文件的依赖-->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<!-- jason-->
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.2.0</version>
</dependency>
<!-- 配置一下日志问价-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.17.1</version>
</dependency>
</dependencies>
</project>