文档章节

浅谈Spring IOC

戴的天
 戴的天
发布于 2014/11/12 10:42
字数 924
阅读 23
收藏 0

Spring的核心是IOC和AOP,今天只谈IOC,这部分内容主要集中在spring-beans包下。

容器的实现

IOC(Inversion of Control)即控制反转,也叫做依赖注入(DI),主要是实现一个容器,而该容器的功能就是进行装配、生产的工厂。同时,Spring的一个核心概念就是将所有配置信息当做bean来处理。

从而得到一个叫做BeanFactory的接口类。

package com.ddt.summer.bean.factory;

/**
 * 
 * @author daidetian@gmail.com
 */
public interface BeanFactory {
	
	/**
	 * 放入bean对象
	 * @param name
	 * @param object
	 */
	void putBean(String name, Object object);
	
	/**
	 * 根据bean名称获取bean实例
	 * @param name
	 * @return
	 */
	Object getBean(String name);

	/**
	 * 是否含有名称为name的bean
	 * @param name
	 * @return
	 */
	boolean containsBean(String name);

}

这个容器需要能进行配置的bean的读取,所以需要有一个集合类来存储这些bean,下面列出一个beanFactory的实现类

package com.ddt.summer.bean.factory;

import java.util.ArrayList;
import java.util.List;

import com.ddt.summer.bean.entity.Bean;

public class XmlBeanFactory implements BeanFactory {
	
	private List<Bean> beans = new ArrayList<Bean>();
	
	private static XmlBeanFactory factory;
	
	private XmlBeanFactory(){
	}
	
	public static XmlBeanFactory getInstance(){
		if(factory==null){
			factory = new XmlBeanFactory();
		}
		return factory;
	}
	
	@Override
	public void putBean(String name, Object object){
		Bean bean = new Bean();
		bean.setId(name);
		bean.setObject(object);
		beans.add(bean);
	}

	@Override
	public Object getBean(String name) {
		for(Bean bean:beans){
			if(bean.getId().equals(name)){
				return bean.getObject();
			}
		}
		return null;
	}

	@Override
	public boolean containsBean(String name) {
		for(Bean bean:beans){
			if(bean.getId().equals(name)){
				return true;
			}
		}
		return false;
	}
}

注意到上面的XmlBeanFactory使用了单例模式,是为了保证我们每次获取到的容器是同一个容器。

配置信息注入

有了容器后,我们就需要将配置好的信息,通过反射注入到我们实现好了的容器中。

下面举一个简单的例子,我们实现几个类。

首先实现一个大的接口类

package test;

public interface Animal {
	
	void say();

}

再来一个老鼠类

package test;

public class Mouse implements Animal{
	
	private String name;
	
	public void setName(String name){
		this.name=name;
	}
	
	public String getName(){
		return this.name;
	}
	@Override
	public void say(){
		System.out.println("mouse is "+name);
	}

}

有了老鼠,就自然会有猫类:

package test;

public class Cat implements Animal {
	
	private String name;
	private Mouse mouse;

	@Override
	public void say() {
		System.out.println("i am "+name+" !");
		System.out.println("catched:");
			mouse.say();
	}
	
	public String getName(){
		return this.name;
	}
	
	public Mouse getMouse(){
		return mouse;
	}
	
	public void setName(String name){
		this.name = name;
	}
	
	public void setMouse(Mouse mouse){
		this.mouse = mouse;
	}

}

有了这几个类,我们就可以开始我们的配置了,配置如下

<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="animal2" class="test.Mouse">
	<property name="name" value="jerry" />
</bean>
<bean id="animal" class="test.Cat">
	<property name="name" value="tom" />
	<property name="mouse" ref="animal2" />
</bean>
</beans>

最后,我们剩下的工作就是将这些配置信息注入到工厂容器里了

package simple;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.List;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;

import com.ddt.summer.bean.factory.BeanFactory;
import com.ddt.summer.bean.factory.XmlBeanFactory;

public class XmlReader {
	
	public static void read(){
		URL base = ClassLoader.getSystemResource("");
		File file = new File(base.getFile(),"applicationContext.xml");
		SAXBuilder builder = new SAXBuilder();
		try {
			Document doc = builder.build(file);
			Element beans = doc.getRootElement();
			paking(beans);
		} catch (JDOMException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private static void paking(Element beans){
		List<Element> list = beans.getChildren();
		for(Element beanEle:list){
			String id = beanEle.getAttributeValue("id");
			String className = beanEle.getAttributeValue("class");
			try {
				Class<?> clazz = Class.forName(className);
				Object obj = clazz.newInstance();
				BeanFactory factory = XmlBeanFactory.getInstance();
				factory.putBean(id, obj);
				List<Element> properties = beanEle.getChildren();
				for(Element property:properties){
					if("property".equals(property.getName())){
						String name = property.getAttributeValue("name");
						String value = property.getAttributeValue("value");
						if(value!=null){
							Field field = clazz.getDeclaredField(name);
							PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
							Method setterMethod = pd.getWriteMethod();
							setterMethod.invoke(obj,value);
						}
					}
				}
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			} catch (NoSuchFieldException e) {
				e.printStackTrace();
			} catch (IntrospectionException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static Object getBean(String id){
		read();
		BeanFactory factory = XmlBeanFactory.getInstance();
		return factory.getBean(id);
	}

}

这里我用Jdom来实现了对xml的读取。这样就愉快的将这些配置好的信息注入到了我们的工厂容器里了。

再来一个简单的测试

public static void main(String[] args){
		Animal a1 = (Animal) XmlReader.getBean("animal");
		a1.say();
	}

输出结果如下:

i am tom !
catched:
mouse is jerry

显然,我的如下代码基本实现了IOC的功能,由XmlBeanFactory和XmlReader来实现对具体bean的组装、生成和管理。

具体代码可以在github上找到,https://github.com/daidetian/summer

© 著作权归作者所有

共有 人打赏支持
上一篇: jdk5-7特性
戴的天
粉丝 16
博文 63
码字总数 83564
作品 0
杭州
技术主管
私信 提问
初识 Spring(01)---(浅谈 Spring 框架)

浅谈 Spring 框架 Spring框架是分模块存在,除了最核心的Spring Core Container(即Spring容器)是必要模块之外,其他模块都是可选,视需要而定。大约有20多个模块。简单来说,Spring是一个分层...

姜白告
08/07
0
0
浅谈Spring设计分析_201800814

spring学习的思考与发现 1:spring中核心的几个部分 1:core : 工具类角色 2:beans : 各种实例化,被管理的对象与类 3:为整个spring容器提供维护,最基础的环境 2:IOC和AOP应该是在beans模块实现...

noteman
08/14
0
0
浅谈当前流行的开发架构

随着软件开发规模和复杂性,社会对软件开发速度和数量要求不断提高,Web应用系统特别是企业级Web系统的开发通常都要求有一个良好的、可维护的、可扩展、高稳定性的开发架构,便于敏捷、协作开...

李晓
2010/06/24
1K
6
Spring IoC 浅谈

谈谈对Spring IOC的理解 学习过Spring框架的人一定都会听过Spring的IoC(控制反转) 、DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC 、DI这两个概念是模糊不清的,是很难理解的...

The_flying_pig
2017/11/03
0
0
【死磕 Spring】—– IOC 之 IOC 初始化总结

原文出自:http://cmsblogs.com 前面 13 篇博文从源码层次分析了 IOC 整个初始化过程,这篇就这些内容做一个总结将其连贯起来。 在前文提过,IOC 容器的初始化过程分为三步骤:Resource 定位...

chenssy
10/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

jquery通过id显示隐藏

var $div3 = $('#div3'); 显示 $div3.show(); 隐藏 $div3.hide();

yan_liu
50分钟前
1
0
《乱世佳人》读书笔记及相关感悟3900字

《乱世佳人》读书笔记及相关感悟3900字: 之前一直听「荔枝」,后来不知怎的转向了「喜马拉雅」,一听就是三年。上班的时候听房产,买房了以后听装修,兴之所至时听旅行,分手后听亲密关系,...

原创小博客
53分钟前
1
0
大数据教程(9.6)map端join实现

上一篇文章讲了mapreduce配合实现join,本节博主将讲述在map端的join实现; 一、需求 实现两个“表”的join操作,其中一个表数据量小,一个表很大,这种场景在实际中非常常见,比如“订单日志...

em_aaron
今天
1
0
cookie与session详解

session与cookie是什么? session与cookie属于一种会话控制技术.常用在身份识别,登录验证,数据传输等.举个例子,就像我们去超市买东西结账的时候,我们要拿出我们的会员卡才会获取优惠.这时...

士兵7
今天
1
0
十万个为什么之为什么大家都说dubbo

Dubbo是什么? 使用背景 dubbo为什么这么流行, 为什么大家都这么喜欢用dubbo; 通过了解分布式开发了解到, 为适应访问量暴增,业务拆分后, 子应用部署在多台服务器上,而多台服务器通过可以通过d...

尾生
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部