1.创建实体类以及XML文件
package entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class WJZ {
private Integer age;//年龄
private Integer height;//身高
private String xueyuan;//学院
private Boolean IsSingle;//是否单身
private String sex;//性别
}
<?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">
<bean id="wjz" class="entity.WJZ">
<property name="age" value="20"></property>
<property name="height" value="168"></property>
<property name="xueyuan" value="IOT"></property>
<property name="IsSingle" value="true"></property>
<property name="sex" value="男"></property>
</bean>
</beans>
2.解析XML文件将相应的对象放到IOC容器中
首先创建自己的ApplicationContext实现ApplicationContext接口。然后创建一个map容器作为IOC容器,通过自己的ApplicationContext构造器解析这个xml文件,然后得到document对象。要想解析xml文件需要通过dom4j所以我们在pom中导入他的依赖
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
public class WJZApplicationContext implements ApplicationContext {
private Map<String,Object> iocMap;
public WJZApplicationContext(String path) {
iocMap = new HashMap<String, Object>();
parseXML(path);
}
private void parseXML(String path){
SAXReader saxReader = new SAXReader();
try {
Document document = saxReader.read("src/main/resources/"+path);
System.out.println(document);
} catch (DocumentException e) {
e.printStackTrace();
}
}
通过SAXReader解析xml并将xml文件封装在document对象中,运行看一下这个document对象
得到这样的结果说明已经得到了正确的document对象。下一步我们就要通过拿到bean对象并将其放在IOC容器中。要想拿到bean对象我们必须先拿到beans通过beans迭代出它内部所有的bean对象然后依次放入IOC容器中
//拿到xml文件的根节点这个根节点是beans
Element root = document.getRootElement();
这步为了拿到beans标签
拿到beans标签后我们就可以进一步的得到它里面的bean通过bean的全类名创建bean的类然后再通过反射创建它的对象然后再将它放入IOC容器中通过getBean方法获取。
private void parseXML(String path){
SAXReader saxReader = new SAXReader();
try {
Document document = saxReader.read("src/main/resources/"+path);
Element root = document.getRootElement();
Iterator<Element> rootIter = root.elementIterator();
while(rootIter.hasNext()){
Element bean = rootIter.next();
//拿到这个bean的id和全类名通过反射创建对象
String id = bean.attributeValue("id");
String className = bean.attributeValue("class");
Class clazz = Class.forName(className);//拿到这个类
Constructor constructor = clazz.getConstructor();//拿到构造器通过构造器创建对象
Object newInstance = constructor.newInstance();
iocMap.put(id,newInstance);
}
} catch (DocumentException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
@Override
public Object getBean(String s) throws BeansException {
return iocMap.get(s);
}
public static void main(String[] args) {
ApplicationContext applicationContext = new WJZApplicationContext("wjzioc.xml");
Object wjz = applicationContext.getBean("wjz");
System.out.println(wjz);
}
最后得到结果
3.为拿到的对象赋值
首先我们要获得标签里面的属性名和属性值,然后通过反射获取set方法通过set方法赋值。
Iterator<Element> beanIter = bean.elementIterator();
while(beanIter.hasNext()){
Element property = beanIter.next();
//拿到他们的属性名,属性值
String propertyName = property.attributeValue("name");
String propertyValue = property.attributeValue("value");
//拿到该对象的set方法对属性进行赋值
String methodName = "set"+propertyName.substring(0,1).toUpperCase() + propertyName.substring(1);
Field field = clazz.getDeclaredField(propertyName);
//通过方法名和参数类型获取方法
Method method = clazz.getMethod(methodName, field.getType());
Object value = propertyValue;
//由于所有从<property>中获取的propertyValue都是String,所以我们要根据他们的真实类型进行转换
String name = field.getType().getName();
if ("java.lang.Integer".equals(name)) {
value = Integer.parseInt(propertyValue);
} else if ("java.lang.Boolean".equals(name)) {
value = Boolean.parseBoolean(propertyValue);
}
method.invoke(newInstance,value);
}
这里面要注意的一点就是property标签里value的值都是String类型的但是在我们的类中却不一定所以我们要判断一下他们的真实类型然后进行转换再赋值给对象。这样一个简易的只能获取对象的IOC容器就大功告成了。
public static void main(String[] args) {
ApplicationContext applicationContext = new WJZApplicationContext("wjzioc.xml");
Object wjz = applicationContext.getBean("wjz");
System.out.println(wjz);
}
结果显示这个人20岁身高168,IOT学院,单身,性别男。