1.创建工程
目录如下
2.引入依赖:dom4 j和 jaxen 依赖
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zy</groupId>
<artifactId>s06</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<repositories>
<repository>
<id>aliyun</id>
<name>aliyun</name>
<url>https://maven.aliyun.com/repository/public</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<!--dom4j是Java的xml解析组件-->
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.1</version>
</dependency>
<!--jaxen是Xpath表达式解释器-->
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.1.6</version>
</dependency>
</dependencies>
</project>
3.创建实体类
package com.zy.spring.ioc.entity;
public class Apple {
//创建实体类
private String title;
private String color;
private String origin;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getOrigin() {
return origin;
}
public void setOrigin(String origin) {
this.origin = origin;
}
}
4.配置bean
在resources目录下创建applicationContext.xml文件
<?xml version="1.0" encoding="UTF-8"?> <!--beans为根节点--> <beans> <!-- bean是beans的子节点--> <bean id="sweetApple" class="com.zy.spring.ioc.entity.Apple"> <property name="title" value="红富士"/> <property name="color" value="红色"/> <property name="origin" value="欧洲"/> </bean> </beans>
6.创建接口ApplicationContext
package com.zy.spring.ioc.context;
public interface ApplicationContext {
public Object getBean(String beanId);
}
7.创建类ClassPathXmlApplicationContext实现ApplicationContext接口
package com.zy.spring.ioc.context;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ClassPathXmlApplicationContext implements ApplicationContext {
//创建一个HashMap作为IoC容器
private Map iocContainer = new HashMap();
public ClassPathXmlApplicationContext() {
try {
//得到配置文件的物理地址
String filePath = this.getClass().getResource("/applicationContext.xml").getPath();
//如果包含中文,可能会出错,需要解码重新赋值
filePath = new URLDecoder().decode(filePath, "UTF-8");
//SAXReader对象加载解析XML,创建File对象,得到xml文档对象document
SAXReader reader = new SAXReader();
Document document = reader.read(new File(filePath));
//获取XML文件中的根节点beans的子节点bean
List<Node> beans = document.getRootElement().selectNodes("bean");
for (Node node : beans) {
Element element = (Element) node;
String id = element.attributeValue("id");
String className = element.attributeValue("class");
Class name = Class.forName(className);
//无参构造方法创建实例类
Object obj = name.newInstance();
//将获取到的id和实例对象放入到IoC容器中
iocContainer.put(id, obj);
//获取到XML文件中的property这个节点的属性名name和值value
List<Node> properties = element.selectNodes("property");
for (Node p : properties) {
Element property = (Element) p;
String proName = property.attributeValue("name");
String proValue = property.attributeValue("value");
//截取字符,从索引为0开始,索引1结束,截取一个字符转换为大写;截取从索引为1开始到最后的字符
String setMethodName = "set" + proName.substring(0, 1).toUpperCase() + proName.substring(1);
System.out.println("准备执行" + setMethodName + "方法注入数据");
Method setMethod = name.getMethod(setMethodName, String.class);
setMethod.invoke(obj, proValue);//通过setter方法注入数据
}
iocContainer.put(id, obj);
}
System.out.println(iocContainer);
System.out.println("IOC容器初始化完毕");
} catch (Exception e) {
e.printStackTrace();
}
}
public Object getBean(String beanId) {
return iocContainer.get(beanId);
}
}
8.创建启动类Application
这里导入的类是我们自己创建的类
package com.zy.spring.ioc;
import com.zy.spring.ioc.context.ApplicationContext;
import com.zy.spring.ioc.context.ClassPathXmlApplicationContext;
import com.zy.spring.ioc.entity.Apple;
public class Application {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext();
Apple apple = (Apple)context.getBean("sweetApple");
System.out.println(apple);
}
}
9.运行
至此,一个极简的IoC容器实现。