加深spring框架理解,实现简单的Ioc容器
最近学习到了SSM框架,记录一下spring的Ioc容器学习。
什么是Ioc?
Ioc 英文就是 Inversion Of Control,意思是控制反转。
IoC 是指在程序开发中,实例的创建不再由调用者管理,而是由 Spring 容器创建。Spring 容器会负责控制程序之间的关系,而不是由程序代码直接控制,因此,控制权由程序代码转移到了 Spring 容器中,控制权发生了反转,这就是 Spring 的 IoC 思想。
简单一点说,就是以前我们创建对象的时候,要自己敲,new 一个新对象,现在把创建对象的任务交给spring容器处理,由spring容器创建对象,我们直接使用就好。
思想简单理解
我们将需要创建的对象和依赖关系通过bean标签的形式写入配置文件(applicationContext.xml),框架读取配置文件,创建对象并处理依赖关系。
写一个简单的Ioc容器
创建实体对象类,将类信息写入applicationContext.xml文件,初始化容器,读取配置文件,获得类信息,数据信息,利用反射机制获得类对象,创建类,将数据注入类。
实现
1.创建项目
项目名 easyIoc,结构如下
2.实体类:Apple
package com.Ioc.entity;
public class Apple {
private String name;
private String color;
private String taste;
@Override
public String toString() {
return "Apple{" +
"name='" + name + '\'' +
", color='" + color + '\'' +
", taste='" + taste + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getTaste() {
return taste;
}
public void setTaste(String taste) {
this.taste = taste;
}
}
3.配置文件:applicationContext.xml
<?xml version="1.0" encoding="UTF-8" ?>
<beans>
<bean id="redApple" class="com.Ioc.entity.Apple">
<property name="name" value="红苹果"/>
<property name="color" value="红色"/>
<property name="taste" value="甜"/>
</bean>
</beans>
4.接口类:applicationContext
package com.Ioc.context;
public interface ApplicationContext {
public Object getBean(String beanId);
}
5.实现类:ClassPathXmlApplicationContext
package com.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 {
private Map IocContainer = new HashMap();
public ClassPathXmlApplicationContext() {
try {
// 读取xml配置文件
// getResource用于从classpath获取指定文件资源 getPath获取路径
String filePath = this.getClass().getResource("/applicationContext.xml").getPath();
// URL解码,防止出现中文路径丢失问题
filePath = new URLDecoder().decode(filePath, "UTF-8");
// 加载解析xml文件,获得Document对象
SAXReader reader = new SAXReader();
Document document = reader.read(new File(filePath));
// 获取根节点集合
List<Node> beans = document.getRootElement().selectNodes("bean");
for (Node node : beans) {
// 强制转换成Element对象
Element element = (Element) node;
// 提取属性
String id = element.attributeValue("id");
String className = element.attributeValue("class");
// 利用java反射获取类对象
Class c = Class.forName(className);
// 接收类对象
Object obj = c.newInstance();
// 获得属性节点
List<Node> propertys = element.selectNodes("property");
for (Node property : propertys) {
Element ele = (Element) property;
// 获得属性名和属性值
String name = ele.attributeValue("name");
String value = ele.attributeValue("value");
// 动态注入
// 定义方法名,set后第一个字符大写
String setMethodName = "set" + name.substring(0,1).toUpperCase()+name.substring(1);
System.out.println("准备执行" + setMethodName + "方法注入数据");
// 利用反射,通过方法名调用方法
// getMethod(),第一个参数:方法名,第二个参数:方法的参数的类型
Method setMethod = c.getMethod(setMethodName, String.class);
// 调用方法
setMethod.invoke(obj, value);//通过setter方法注入数据
}
// 放入容器
IocContainer.put(id, obj);
}
System.out.println(IocContainer);
System.out.println("初始化完成");
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public Object getBean(String beanId) {
return IocContainer.get(beanId);
}
}
6.导入依赖:dom4j和jaxen (pom.xml)
<dependencies>
<!--dom4j: java的xml解析组件,底层依赖jaxen-->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<!--jaxen:Xpath表达式解释器-->
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.2.0</version>
</dependency>
</dependencies>
7.程序入口:Application
package com.Ioc;
import com.Ioc.context.ApplicationContext;
import com.Ioc.context.ClassPathXmlApplicationContext;
import com.Ioc.entity.Apple;
public class Application {
public static void main(String[] args) {
// 初始化容器
ApplicationContext context = new ClassPathXmlApplicationContext();
System.out.println((Apple)context.getBean("redApple"));
}
}
8.结果
结语
有问题希望大家指出。学无止境,欢迎交流。