有参数构造,无参数构造,字段,set方法实现这个spring的ioc容器管理

通过反射机制来实现配置文件的读取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);
	
	/**
	 * 在改方法里面一共有创建对象把这个对象放到一个map集合当中
	 * 给这个对象的字段进行赋值 如果有这个set方法的话就给这个set方法进行调
	 *这个方法是存在缺陷的,你的构造方法的方法一定要按照在这个顺序进行写入这个配置文件否者就会出现异常
	 * @param XmlPath 这个地方你需要给我传递一个路径
	 * @param clazz   这个值是不应该含有的没关系
	 * @throws Exception 抛出一个异常
	 */
	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);
			}
		});
	}
	
	/**
	 * 给这个对象做一个进一步的转型
	 *
	 * @param classPath 目标的id
	 * @param clazz     转型的类型
	 * @param <T>       返回一个泛型
	 * @return 返回值类型设置
	 */
	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);
		}
	}
	
	/**
	 * 通过id获取这个对象
	 *
	 * @param classPath
	 * @return
	 */
	@Deprecated
	@Override
	public Object getBean(String classPath) {
		return mapObj.get(classPath);
	}
	
	/**
	 * 判断这个方法是否含有这个set方法如果有的话就调用他的set方法给这个对象进行赋值
	 *
	 * @param clazz      哪一个class类 目标类
	 * @param pathMethod 目标的set方法
	 * @param parameters 参数类型
	 * @return
	 */
	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;
		}
	}
	
	/**
	 * 通过有参数的构造方法来创建对象
	 *
	 * @param clazz    目标类
	 * @param elements bean标签
	 * @param id       传递一个id用来?????
	 */
	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("你的构造方法的顺序有问题");
			
		}
	}
	
	/**
	 * 这个方法就用来给这个进行转换
	 *
	 * @param value  这个是值
	 * @param simpleName  这个是一个简单得类名
	 * @return
	 */
	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>
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值