IoC(控制反转)是Spring框架的核心,通过DI(依赖注入)实现对象创建和依赖管理的自动化。Spring本质上就是一个Bean容器,负责完成对象的创建和依赖的注入
所谓控制反转,就是把原先我们代码里面需要实现的对象(bean)创建、依赖的代码,反转给ioc容器来帮忙实现,也就是 ioc 容器帮我们做了原本应该我门自己实现的对象创建和依赖的内容。
我们有一个业务逻辑模块 UserService 和一个实体类 User 还有一个持久层模块 UserDAO 和它的实现 UserDAOImpl。
他们之间 UserService 调用(依赖)UserDAO 来操作数据库。我们在test 中运行的时候呢,要创建 UserService 和 UserDAO 并将 UserDAO set 到 UserService 中,这是我门正常的逻辑。
好了、现在我们要用自己编写的简单的ioc 来处理这些关系。
一、项目结构
1 | |
1 | |
package com.study.spring;
/**
- @author Howe Hsiang
*/
public interface BeanFactory {
Object getBean(String name);
}
1 | |
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
@author Howe Hsiang
1
*/public class ClassPathXmlApplicationContext implements BeanFactory {
private Map<String, Object> beans = new HashMap<String, Object>();public ClassPathXmlApplicationContext() throws Exception {
//解析xml 利用反射生成 bean
SAXBuilder sb = new SAXBuilder();
Document doc = sb.build(“src/main/resources/bean.xml”); //构造文档对象
Element root = doc.getRootElement(); //获取根元素
List list = root.getChildren(“bean”);//取名字为disk的所有元素
for (int i = 0; i < list.size(); i++) {
Element element = (Element) list.get(i);
String id = element.getAttributeValue(“id”);
String className = element.getAttributeValue(“class”);//取disk子元素capacity的内容
System.out.println(“id : “ + id + “ className : “ + className);
Object o = Class.forName(className).newInstance();
beans.put(id, o);
//依赖注入,自动装配 xml 的第二层
for (Element propertyElement : (List
String name = propertyElement.getAttributeValue(“name”); //userDAO
String bean = propertyElement.getAttributeValue(“bean”); //u
Object beanObj = beans.get(bean);//UserDAOImpl instance
//拼出setUserDAO方法名字
String methodName = “set” + name.substring(0, 1).toUpperCase() + name.substring(1);
System.out.println(“methodName : “ + methodName);
// methodName 为方法名 beanObj.getClass().getInterfaces()[0] 为方法的参数 反射取出方法
// beanObj.getClass().getInterfaces()[0] 为 beanObj 实现的第一个接口 也就是 UserDao 为方法的参数
// beanObj 为 UserDAOImpl.class 因为xml 中 bean u 配置的 class 为 UserDAOImpl
Method m = o.getClass().getMethod(methodName, beanObj.getClass().getInterfaces()[0]);
// 进行注入
// 代理执行 m 方法, 也就是用 o 这个对象 调用 m 方法 参数 为 beanObj
// o.m(beanObj) 等价于 userService.setUserDao(userDao)
m.invoke(o, beanObj);
1 | |
public Object getBean(String name) {
return beans.get(name);
1 | |
*/
1 | |
}
1 | |
*/
}
1 | |
本文标题: SpringIOC实战篇
本文作者: 狂欢马克思
发布时间: 2019年03月03日 00:00
最后更新: 2026年09月16日 05:40
原始链接: https://haoxiang.eu.org/ce756b0e/
版权声明: 本文著作权归作者所有,均采用CC BY-NC-SA 4.0许可协议,转载请注明出处!

