手写springIoc框架
Posted 求知若渴的蜗牛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手写springIoc框架相关的知识,希望对你有一定的参考价值。
springIoc的底层实现原理
1.读取bean的XML配置文件
2.使用beanId查找bean配置,并获取配置文件中class地址。
3.使用Java反射技术实例化对象
4.获取属性配置,使用反射技术进行赋值
使用人家spring框架读取对象
创建实体
package com.itmayiedu.service;
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;
}
}
创建spring的配置文件 application.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.service.UserEntity">
<property name="userId" value="0002"></property>
<property name="userName" value="张三"></property>
</bean>
<bean id="user2" class="com.itmayiedu.service.UserEntity">
<property name="userId" value="0002"></property>
<property name="userName" value="张三"></property>
</bean>
</beans>
读取配置文件
package com.itmayiedu.service;
import org.springframework.context.support.ClassPathXmlApplicationContext;
@SuppressWarnings("resource")
public class Main {
public static void main(String[] args) {
//1.读取springxml配置
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext(
"applicationContext.xml");
//2.获取bean对象
UserEntity userEntity = (UserEntity) classPathXmlApplicationContext.getBean("user1");
System.out.println(userEntity.getUserId()+"----"+userEntity.getUserName());
}
}
自己手写springIoc框架
编写配置文件user.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="user1" class="com.itmayiedu.entity.UserEntity">
<property name="userId" value="0001"></property>
<property name="userName" value="张三"></property>
</bean>
<bean id="user2" class="com.itmayiedu.entity.UserEntity">
<property name="userId" value="0002"></property>
<property name="userName" value="张三"></property>
</bean>
</beans>
编写读取user.xml的方法
package com.itmayiedu.classFrorm;
import java.lang.reflect.Field;
import java.util.List;
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 String xmlPath;
public ClassPathXmlApplicationContext(String xmlPath) {
this.xmlPath = xmlPath;
}
public Object getBean(String beanId) throws DocumentException, ClassNotFoundException, NoSuchFieldException,
SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException {
// spring 加载过程 或者spring ioc实现原理
// 1.读取xml配置文件
// 获取xml解析器
SAXReader saxReader = new SAXReader();
// this.getClass().getClassLoader().getResourceAsStream("xmlPath")
// 获取当前项目路径
Document read = saxReader.read(this.getClass().getClassLoader().getResourceAsStream(xmlPath));
// 获取跟节点对象
Element rootElement = read.getRootElement();
List<Element> elements = rootElement.elements();
Object obj = null;
for (Element sonEle : elements) {
// 2.获取到每个bean配置 获取class地址
String sonBeanId = sonEle.attributeValue("id");
if (!beanId.equals(sonBeanId)) {
continue;
}
String beanClassPath = sonEle.attributeValue("class");
// 3.拿到class地址 进行反射实例化对象 ,使用反射api 为私有属性赋值
Class<?> forName = Class.forName(beanClassPath);
obj = forName.newInstance();
// 拿到成员属性
List<Element> sonSoneleme = sonEle.elements();
for (Element element : sonSoneleme) {
String name = element.attributeValue("name");
String value = element.attributeValue("value");
// 使用反射api 为私有属性赋值
Field declaredField = forName.getDeclaredField(name);
//运行往私有成员赋值
declaredField.setAccessible(true);
declaredField.set(obj, value);
}
}
// 3.拿到class地址 进行反射实例化对象 ,使用反射api 为私有属性赋值
return obj;
}
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException,
IllegalArgumentException, IllegalAccessException, InstantiationException, DocumentException {
ClassPathXmlApplicationContext appLication = new ClassPathXmlApplicationContext("user.xml");
Object bean = appLication.getBean("user1");
UserEntity user = (UserEntity) bean;
System.out.println(user.getUserId() + "----" + user.getUserName());
}
}
创建对应的user实体省略了
以上是关于手写springIoc框架的主要内容,如果未能解决你的问题,请参考以下文章
从零开始手写 spring ioc 框架,深入学习 spring 源码