SpringIOC的底层原理:
1、解析xml文件——使用dom4j
2、通过bean id查找到对象的xml节点,并获取该xml上class节点属性——获取根节点后遍历得到二级节点
3、通过java的反射机制初始化类
4、使用java的反射机制为私有属性赋值——遍历二级节点获得三级节点 API对应:List<Element> ele3 = element.elements();
applicationContext.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" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="user1" class="com.itmayiedu.entity.UserEntity">
<property name="userId" value="001"></property>
<property name="userName" value="张三"></property>
</bean>
<bean id="user2" class="com.itmayiedu.entity.UserEntity">
<property name="userId" value="002"></property>
<property name="userName" value="李四"></property>
</bean>
</beans>
UserEntity.java
package com.itmayiedu.entity;
public class UserEntity {
private String userId;
private String userName;
public UserEntity(){
System.out.println("无参构造函数....");
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
@Override
public String toString() {
return "UserEntity [userId=" + userId + ", userName=" + userName + "]";
}
}
springioc实现类
import java.lang.reflect.Field;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.itmayiedu.entity.UserEntity;
public class ClassPathXmlApplicationContext {
private static String PATH;
private static String ID;
private static String CLASS;
private static String NAME;
private static String VALUE;
private void init(){
this.ID = "id";
this.CLASS = "class";
this.NAME = "name";
this.VALUE = "value";
}
/**
* @param applicationContext.xml的路径
*/
public ClassPathXmlApplicationContext(String path) {
init();
this.PATH = path;
}
public ClassPathXmlApplicationContext() {}
public Object getBean(String id) throws DocumentException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException{
if(StringUtils.isBlank(id)){
return null;
}
//获取saxRead对象
SAXReader saxReader = new SAXReader();
//获取当前路径
Document doc = saxReader.read(this.getClass().getClassLoader().getResource(PATH));
//获取根节点<beans>
Element rootEle = doc.getRootElement();
List<Element> elements = rootEle.elements();
for(Element element : elements){
//遍历出来的就是二级节点,寻找属性id
String beanId = element.attributeValue(ID);
if(beanId==null && !beanId.equals(id)){
//跳过本次循环
continue;
}
//找到该id,获取该id对应的class属性
String beanClass = element.attributeValue(CLASS);
if(beanClass == null) {
throw new RuntimeException("没有找到该id="+id+"中对应的class");
}
//找到了class,则进行反射初始化操作
Class<?> classForName = Class.forName(beanClass);
//反射初始化对象
Object instance = classForName.newInstance();
//为property赋值,三级节点
List<Element> ele3 = element.elements();
for(Element ele : ele3){
//<property></property>
String name = ele.attributeValue(NAME);
String value = ele.attributeValue(VALUE);
Field field = classForName.getDeclaredField(name);
field.setAccessible(true);
field.set(instance, value);
}
return instance;
}
return null;
}
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, DocumentException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserEntity user = (UserEntity) context.getBean("user1");
System.out.println(user);
}
}
打印结果:
无参构造函数....
UserEntity [userId=001, userName=张三]