第一什么是IOC
IOC控制反转,把对象的创建,属性设置,初始化,销毁等工作交给Spirng的IOC容器去管理,解放程序员的劳动力。对象被注册到Spring的IOC容器中,使用的时候从容器中获取即可,非常方便。它通过依赖注入,将需要的外部资源注入到组件中,使用IOC使得对象之间的耦合度降低,资源变得容易管理,从而使得代码更加优雅
IOC的原理是什么
当Spring启动时,IOC容器会加载Spring的配置文件,包括XML配置或者注解,然后解析这些Bean并把相关定义信息封装成BeanDefinition对象,通过Bean注册器BeanDefinitionRegistry注册到IOC容器,也就是一个ConcurrentHashMap中,此时会找出所有的单例且非惰性加载的bean,根据其BeanDefinition进行Bean的实例化,它会判断如果bean中有方法覆盖,就使用JDK反射创Bean否则使用CGLIB方式生成代理。然后把实例化好的Bean缓存到一个ConcurrentHashMap中
自定以IOC容器的思路
1: 创建容器 2:处理xml文件 3: 利用反射机制创建对象 4: 将处理好的ben对象放入容器 5:暴露接口供其他人调用
首先创建一个类,构建普通方法
将我们的类信息写入Bean.xml文件中
在pom.xml导入 dom4j和jaxen的依赖包。我这儿用于测试导入了junit的工具包
主要代码如下:
/*定义一个容器 */
static Map<String ,Object> benMap = new ConcurrentHashMap<>();
/* 静态代码块,提前加载*/
static {
/* 使用二进制流处理我们的bean.xml文件*/
InputStream xmlStream = Ioc.class.getClassLoader().getResourceAsStream("bean.xml");
/* 我们导入的依赖包dom4j*/
SAXReader saxReader = new SAXReader();
try {
Document document = saxReader.read(xmlStream); //得到文本对象
// 获取文本的根节点beans
Element rootElement = document.getRootElement();
// 根据根几点找到bean
List<Element> nodeList = rootElement.selectNodes("//bean");// 双斜杠表示匹配所有。
for (int i = 0 ; i <= nodeList.size() ;i++){
Element element = nodeList.get(i);
// 从文本对象里获取对象名id 和 对象路径
String id = element.attributeValue("id");
String aClass = element.attributeValue("class");
// 通过反射机制创建对象。
Class<?> zClass = Class.forName(aClass);
Object bean = zClass.newInstance();
// 添加到容器中
benMap.put(id,bean);
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 暴露接口以便使用
public static Object getBean (String id){
return benMap.get(id);
}