文档章节

浅谈Spring IOC

戴的天
 戴的天
发布于 2014/11/12 10:42
字数 924
阅读 22
收藏 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

© 著作权归作者所有

共有 人打赏支持
戴的天
粉丝 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
那些年,我们一起追的Spring

学无止境,但仍需及时总结。 自去年开始写作以来,写了一些关于Spring的文章,今天将它们汇总起来,一方面方便大家阅读,另一方面,也是一次小的复盘总结。 IOC 首先是Spring的IOC,也就是控...

SexyCode
08/14
0
0
在spring中如何配置和使用一个Bean

在Spring中,那些组成你应用程序的主体(backbone)及由Spring IoC容器所管理的对象,被称之为bean。 简单地讲,bean就是由Spring容器初始化、装配及管理的对象,除此之外,bean就与应用程序中...

冰雷卡尔
2012/07/24
0
0
【Spring学习笔记】--IOC学习

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/YYZZHC999/article/details/82824751 spring ioc原理 Ioc—Inversion of Control,即“控制反转”,不是什么技...

Hepburn_Yang
昨天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

计算卷积神经网络浮点数运算量

前言 本文主要是介绍了,给定一个卷积神经网络的配置之后,如何大概估算它的浮点数运算量。 相关代码:CalFlops,基于MXNet框架的 Scala 接口实现的一个计算MXNet网络模型运算量的demo。 正文...

Ldpe2G
今天
1
0
Sql语言与MySql数据库

1. 数据库简介 1. 数据库,就是存储数据的仓库,只能通过sql语言来访问,数据库也是一个文件系统。通常,MySQL、Oracle等数据库,也被称为关系型数据库,其保存的不仅仅只是数据,还包括数据...

江左煤郎
今天
1
0
IDEA 取消自动import .*

打开设置 > Editor > Code Style > Java > Scheme Default > Imports ① 将 Class count to use import with "*" 改为 99 (导入同一个包的类超过这个数值自动变为 * ) ② 将 Names count ......

乔老哥
今天
3
0
PostGIS学习笔记(开篇)

PostGIS事实上算是笔者开始写博客的第一篇内容。而事实上那篇博文的内容并不丰富,笔者对PostGIS的了解仍然不多,然而17年在OSGeo课程学习时对PostGIS又有了进一步了解,并逐步发现它的强大。...

胖胖雕
今天
3
0
【Centos】在nginx服务器中配置php和mysql

接上一章《【Centos】利用Vultr服务器和namesilo布网》(https://my.oschina.net/u/3776619/blog/2051986),在Centos中配置好nginx,并在iptables中开启了80端口,和为了远程mysql操作方便开...

yongh701
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部