IOC控制反转、DI依赖注入,Spring框架技术核心(内含项目代码)详解

1 篇文章 0 订阅
1 篇文章 0 订阅

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值