IOC控制反转
概念
所谓的控制反转:IOC—Inversion of Control,它更多的是是一种设计思想。在Spring框架中使用了IOC这种设计思想,意味着将设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。将控制权交给IOC容器而不是留在对象内部中,这种控制权的交换便是控制反转。
IOC容器里面存放的是以后会用到的对象,传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对 象的创建
DI依赖注入
概念
IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。
比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了 spring我们就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。在系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。A需要依赖 Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。
那么DI是如何实现的呢? Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。
理解了IoC和DI的概念后,一切都将变得简单明了,剩下的工作只是在spring的框架中堆积木而已。
实现
package com.icss.ioc;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Hashtable;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class ApplicationContext {
//默认情况下是用配置文件做,注解也可以做
/*
* XML方法:SAX或者DOM4J 文档对象模型第三方
*
* 存放要被容器所管理對象的集合類
* 將可能會用到的對象存入容器中
* 将对象放到容器中
* 依赖关系 一个类需要另一个类中的对象时 用的时候直接从容器中依据key值拿出来然后初始化 不用在new
*/
@SuppressWarnings({ "unchecked", "unused", "rawtypes" })
private Hashtable<String,Object> container = new <String,Object>Hashtable();
public void xmlinit(String fileName) throws SAXException, IOException, InstantiationException, IllegalAccessException, ClassNotFoundException
{
//xml初始化
try
{
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
//解析传入的xml文件
Document doc = db.parse(fileName);
//得到根节点
Node root = doc.getDocumentElement();
NodeList childList = root.getChildNodes();
for(int i=0;i<childList.getLength();i++)
{
//的到bean节点
Node childNode = childList.item(i);
NamedNodeMap nodeAttributes = childNode.getAttributes();
if(nodeAttributes!=null&&nodeAttributes.getLength()>0)
{
Node clazz = nodeAttributes.getNamedItem("class");
Node id = nodeAttributes.getNamedItem("id");
if(clazz!=null&&id!=null)
{
String className = clazz.getNodeValue();
String idName = id.getNodeValue();
System.out.println(className);
System.out.println(idName);
//依據配置文件實例化類對象、存入容器
Object ob = Class.forName(className).newInstance();
//存入容器
container.put(idName,ob);
}
}
}
}
catch (ParserConfigurationException e)
{
e.printStackTrace();
}
}
public Object getBean(String id) throws IllegalArgumentException, IllegalAccessException
{
//return this.container.get(id);
//基于注解来实现依赖注入
Object obj = this.container.get(id);
Field[] fields = obj.getClass().getDeclaredFields();
for(Field field:fields)
{
if(field.isAnnotationPresent(AutoWired.class))
{
//给对象obj的属性进行赋值
field.setAccessible(true);
//依赖注入的核心实现 IOC容器得暴力访问
field.set(obj, this.container.get(field.getName()));
}
}
return obj;
}
public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException
{
ApplicationContext applicationContext = new ApplicationContext();
String path = ApplicationContext.class.getResource("/").getPath();
try
{
applicationContext.xmlinit(path+"applicationContext.xml");
}
catch (SAXException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
//從容器中獲取對象:單例模式還是非單例模式
//容器启动的时候自动创建 IOC对象容器,软件运行中需要对象的时候直接拿出来用
@SuppressWarnings("unused")
User user = (User)applicationContext.getBean("user");
//IOC依赖注入
UserController userController = (UserController) applicationContext.getBean("userController");
userController.login("zhagnsan","123456");
}
}
下面是我自己写的一个IOC的简单实现项目上述代码为其中的一部分
https://download.csdn.net/download/qq_23361621/16580519?spm=1001.2014.3001.5501