1.新建一个springboot项目
<groupId>com.springioc</groupId>
<artifactId>spring-ioc</artifactId>
<version>1.0-SNAPSHOT</version>
2.在pom文件中引入
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.10</version>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
3.创建一个User对象
package com.entity;
public class User {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
'}';
}
}
4.在resource文件中创建一个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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id = "user1" class="com.entity.User">
<property name="id" value="10"/>
<property name="name" value="牛牛"/>
</bean>
<bean id = "user2" class="com.entity.User">
<property name="id" value="10"/>
<property name="name" value="方方"/>
</bean>
</beans>
5.创建一个ClassPathXmlApplicationContext类实现装在bean并赋值返回一个bean实例
package com;
import com.entity.User;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.List;
/**
* Created by vn0790t on 2020/5/15.
*/
public class ClassPathXmlApplicationContext {
private String ID; ;
private String CLASSA;
private String NAME;
private String VALUE;
public ClassPathXmlApplicationContext(){
init();
}
public void init(){
ID = "id";
CLASSA = "class";
NAME = "name";
VALUE = "value";
}
public Object getBean(String beanName) throws Exception {
SAXReader reader = new SAXReader();
//定位到resources目录
URL resource = this.getClass().getClassLoader().getResource("application.xml");
File file = new File(resource.getFile());
//读取application.xml配置文件
Document document = reader.read(file);
//获取标签beans(一级标签)
Element rootElement = document.getRootElement();
//获取beans下的子标签bean(二级标签)
List<Element> elements = rootElement.elements();
for (Element element : elements){
//获取bean标签中id属性的值
String id = element.attributeValue(ID);
//如果不是要找的beanName就结束本次循环,开始下次循环
if(!id.equals(beanName)){
continue;
}
//获取bean标签中的class属性的值
String claessPath = element.attributeValue(CLASSA);
Class<?> forName = Class.forName(claessPath);
//使用无参构造函数创建bean对象
Object newInstance = forName.newInstance();
//获取bean下的子集标签property(三级标签)
List<Element> eson = element.elements();
for (Element e : eson){
//获取属性名name的值
String name = e.attributeValue(NAME);
//获取属性名value的值
String value = e.attributeValue(VALUE);
//获取bean对象的属性
Field field = forName.getDeclaredField(name);
//设置权限(因为属性是私有化的,所以需要设置权限)
field.setAccessible(true);
//将bean对象的属性赋值
field.set(newInstance,value);
}
return newInstance;
}
return null;
}
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext();
try {
User user= (User)classPathXmlApplicationContext.getBean("user1");
System.out.println(user);
} catch (Exception e) {
e.printStackTrace();
}
}
}
6.SpringIOC底层原理
1.读取bean的XML配置文件
2.使用beanId查找bean配置,并获取配置文件中class地址。
3.使用Java反射技术实例化对象
4.获取属性配置,使用反射技术进行赋值。
详细步骤如下:
1.利用传入的参数获取xml文件的流,并且利用dom4j解析成Document对象
2.对于Document对象获取根元素对象<beans>后对下面的<bean>标签进行遍历,判断是否有符合的id.
3.如果找到对应的id,相当于找到了一个Element元素,开始创建对象,先获取class属性,根据属性值利用反射建立对象.
4.遍历<bean>标签下的property标签,并对属性赋值.注意,需要单独处理int,float类型的属性.因为在xml配置中这些属性都是以字符串的形式来配置的,因此需要额外处理.
5.如果属性property标签有ref属性,说明某个属性的值是一个对象,那么根据id(ref属性的值)去获取ref对应的对象,再给属性赋值.
6.返回建立的对象,如果没有对应的id,或者<beans>下没有子标签都会返回null