Spring配置xml-beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--配置Monster对象/JavaBean-->
<!--class属性:指定类的全路径-底层使用反射创建对象(指定无参构造器)-->
<!--id属性:该对象在容器中的id,通过id获取到该对象-->
<!--property属性:用于给该对象的属性赋值 value如果为空,则为默认值-->
<bean class="spring.bean.Monster" id="monster01">
<property name="id" value="1"/>
<property name="name" value="牛魔王"/>
<property name="skill" value="横冲直撞"/>
</bean>
</beans>
简单模拟Spring原生容器的底层实现机制
1.使用了DOM4J库,得到节点,获取标签的配置的类的全路径
2.通过反射创建对象实例
3.获取property标签的属性值,通过对象的set方法为对象的属性赋值
4.将bean标签配置的id当作key,当前对象实例当作value保存到HashMap容器中
5.在静态代码块中,调用该方法,初始化容器
6.定义getBean方法获取容器中的对象实例
package spring.context;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import spring.bean.Monster;
import java.io.File;
import java.util.HashMap;
import java.util.List;
/**
* ClassName: HspApplicationContext
* Package: spring.context
* Description:
* 使用DOM4J技术读取Src下的beans.xml配置文件的信息,并通过反射创建该对象实例
* 并得到该对象的属性,通过set方法为该对象的属性赋值,并将id和该对象实例添加到容器中
*
* @Author 王文福
* @Create 2024/1/31 0:41
* @Version 1.0
*/
public class HspApplicationContext {
//key Bean标签的id属性 value Monster对象
private static HashMap<String, Object> container = new HashMap<>();
/**
* 通过id,得到该对象
*
* @param id:
* @return Object
* @author "卒迹"
* @description TODO
* @date 2:00
*/
public static Object getBean(String id) {
return container.get(id);
}
/**
* 通过id,得到该对象
*
* @param id:
* @return Object
* @author "卒迹"
* @description TODO
* @date 2:00
*/
public static <T> T getBean(String id, Class<T> aClass) {
return (T) container.get(id);
}
static {
try {
getInstance();//初始化容器-存放xml标签配置的对象
} catch (DocumentException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
/**
* 通过反射,初始化JavaBean对象
*
* @param :
* @return void
* @author "卒迹"
* @description TODO
* @date 1:50
*/
@Test
public static void getInstance() throws DocumentException, ClassNotFoundException, InstantiationException, IllegalAccessException {
//1.得到类的加载路径
String path = HspApplicationContext.class.getResource("/").getPath();
SAXReader saxReader = new SAXReader();
//2.通过类的加载路径,得到beans.xml
Document document = saxReader.read(new File(path + "beans.xml"));
System.out.println(document);
//根节点
Element rootElement = document.getRootElement();
//子节点
List<Element> elements = rootElement.elements();
for (Element element : elements) {
//验证获取的是否是bean标签
if ("bean".equals(element.getName())) {
//获取bean标签的属性class
String beanPath = element.attributeValue("class");
//通过反射该对象实例-必须提供无参构造器
Monster monster = (Monster) Class.forName(beanPath.trim()).newInstance();
//获取bean标签的属性id
String beanId = element.attributeValue("id");
//得到该Bean标签的子标签的property的属性name和value
//name:该对象的属性 value:该对象的属性值
List<Element> propertyList = element.elements("property");
//得到该bean标签下的所有的子标签property
for (Element property : propertyList) {
if ("property".equals(property.getName())) {
//得到所有property的属性值,通过对象的set方法为该对象赋值
String name = property.attributeValue("name");
String value = property.attributeValue("value");
//todo 验证属性名是否与对象的属性名一致...
if ("id".equals(name)) {
monster.setId(Integer.parseInt(value));
} else if ("name".equals(name)) {
monster.setName(value);
} else if ("skill".equals(name)) {
monster.setSkill(value);
}
}
}
//打印Monster-验证是否通过set方法赋值
//System.out.println(monster);
//将Monster对象以及id当作key和value保存到容器中
//添加的条件:monster不为空并且Bean标签的id不为空,并且当前容器中不存在该对象
if (null != monster && beanId != null && container.get(beanId) == null) {
container.put(beanId, monster);
}
}
}
}
}
代码测试:
package spring.test;
import spring.bean.Monster;
import spring.context.HspApplicationContext;
/**
* ClassName: HspApplicationContextTest
* Package: spring.test
* Description:
*
* @Author 王文福
* @Create 2024/1/31 2:06
* @Version 1.0
*/
public class HspApplicationContextTest {
public static void main(String[] args) {
Monster monster01 = HspApplicationContext.getBean("monster01", Monster.class);
System.out.println(monster01);
}
}