下面来了解一下Spring到底是怎么运行的。

public static void main(String[] args) {
ApplicationContext context = new FileSystemXmlApplicationContext(
"applicationContext.xml");
Animal animal = (Animal) context.getBean("animal");
animal.say();
}

这段代码你一定很熟悉吧,不过还是让我们分析一下它吧,首先是applicationContext.xml

他有一个类phz.springframework.test.Cat

public class Cat implements Animal {
private String name;
public void say() {
System.out.println("I am " + name + "!");
}
public void setName(String name) {
this.name = name;
}
}

实现了phz.springframework.test.Animal接口

public interface Animal {
public void say();
}

   

很明显上面的代码输出I am kitty!

那么到底Spring是如何做到的呢? 
接下来就让我们自己写个Spring 来看看Spring 到底是怎么运行的吧!

首先,我们定义一个Bean类,这个类用来存放一个Bean拥有的属性

/* Bean Id */
private String id;
/* Bean Class */
private String type;
/* Bean Property */
private Map<String, Object> properties = new HashMap<String, Object>();

  

 

一个Bean包括id,type,和Properties。

接下来Spring 就开始加载我们的配置文件了,将我们配置的信息保存在一个HashMap中,HashMap的key就是Bean 的 Id ,HasMap 的value是这个Bean,只有这样我们才能通过context.getBean("animal")这个方法获得Animal这个类。我们都知道Spirng可以注入基本类型,而且可以注入像List,Map这样的类型,接下来就让我们以Map为例看看Spring是怎么保存的吧

Map配置可以像下面的

<bean id="test" class="Test">
<property name="testMap">
<map>
<entry key="a">
<value>1</value>
</entry>
<entry key="b">
<value>2</value>
</entry>
</map>
</property>
</bean>

  

 

Spring是怎样保存上面的配置呢?,代码如下:

if (beanProperty.element("map") != null) {
Map<String, Object> propertiesMap = new HashMap<String, Object>();
Element propertiesListMap = (Element) beanProperty
.elements().get(0);
Iterator<?> propertiesIterator = propertiesListMap
.elements().iterator();
while (propertiesIterator.hasNext()) {
Element vet = (Element) propertiesIterator.next();
if (vet.getName().equals("entry")) {
String key = vet.attributeValue("key");
Iterator<?> valuesIterator = vet.elements()
.iterator();
while (valuesIterator.hasNext()) {
Element value = (Element) valuesIterator.next();
if (value.getName().equals("value")) {
propertiesMap.put(key, value.getText());
}
if (value.getName().equals("ref")) {
propertiesMap.put(key, new String[] { value
.attributeValue("bean") });
}
}
}
}
bean.getProperties().put(name, propertiesMap);
}

  

接下来就进入最核心部分了,让我们看看Spring 到底是怎么依赖注入的吧,其实依赖注入的思想也很简单,它是通过反射机制实现的,在实例化一个类时,它通过反射调用类中set方法将事先保存在HashMap中的类属性注入到类中。让我们看看具体它是怎么做的吧。 
首先实例化一个类,像这样

public static Object newInstance(String className) {
Class<?> cls = null;
Object obj = null;
try {
cls = Class.forName(className);
obj = cls.newInstance();
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
return obj;
}

  

接着它将这个类的依赖注入进去,像这样

public static void setProperty(Object obj, String name, String value) {
Class<? extends Object> clazz = obj.getClass();
try {
String methodName = returnSetMthodName(name);
Method[] ms = clazz.getMethods();
for (Method m : ms) {
if (m.getName().equals(methodName)) {
if (m.getParameterTypes().length == 1) {
Class<?> clazzParameterType = m.getParameterTypes()[0];
setFieldValue(clazzParameterType.getName(), value, m,
obj);
break;
}
}
}
} catch (SecurityException e) {
throw new RuntimeException(e);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}

  

最后它将这个类的实例返回给我们,我们就可以用了。我们还是以Map为例看看它是怎么做的,我写的代码里面是创建一个HashMap并把该HashMap注入到需要注入的类中,像这样,

if (value instanceof Map) {
Iterator<?> entryIterator = ((Map<?, ?>) value).entrySet()
.iterator();
Map<String, Object> map = new HashMap<String, Object>();
while (entryIterator.hasNext()) {
Entry<?, ?> entryMap = (Entry<?, ?>) entryIterator.next();
if (entryMap.getValue() instanceof String[]) {
map.put((String) entryMap.getKey(),
getBean(((String[]) entryMap.getValue())[0]));
}
}
BeanProcesser.setProperty(obj, property, map);
}

  

好了,这样我们就可以用Spring 给我们创建的类了,是不是也不是很难啊?当然Spring能做到的远不止这些,这个示例程序仅仅提供了Spring最核心的依赖注入功能中的一部分。

转载:http://blog.csdn.net/it_man/article/details/4402245

spring IOC核心原理的更多相关文章

  1. spring ioc aop 原理

    spring ioc aop 原理 spring ioc aop 的原理 spring的IoC容器是spring的核心,spring AOP是spring框架的重要组成部分. 在传统的程序设计中,当调 ...

  2. Spring IOC设计原理解析:本文乃学习整理参考而来

    Spring IOC设计原理解析:本文乃学习整理参考而来 一. 什么是Ioc/DI? 二. Spring IOC体系结构 (1) BeanFactory (2) BeanDefinition 三. I ...

  3. Spring Boot核心原理

    Spring Boot核心原理 spring-boot-starter-xxx  方便开发和配置 1.没有depoy setup tomcat 2.xml文件里面的没有没有了 @SpringBootA ...

  4. Spring框架系列(6) - Spring IOC实现原理详解之IOC体系结构设计

    在对IoC有了初步的认知后,我们开始对IOC的实现原理进行深入理解.本文将帮助你站在设计者的角度去看IOC最顶层的结构设计.@pdai Spring框架系列(6) - Spring IOC实现原理详解 ...

  5. Spring框架系列(7) - Spring IOC实现原理详解之IOC初始化流程

    上文,我们看了IOC设计要点和设计结构:紧接着这篇,我们可以看下源码的实现了:Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的. ...

  6. Spring框架系列(8) - Spring IOC实现原理详解之Bean实例化(生命周期,循环依赖等)

    上文,我们看了IOC设计要点和设计结构:以及Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的:容器中存放的是Bean的定义即Be ...

  7. Spring IoC底层原理

    -------------------siwuxie095                                 Spring IoC 底层原理         1.IoC 即 Invers ...

  8. Spring源码剖析2:初探Spring IOC核心流程

    本文转载自互联网,侵删 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutor ...

  9. Spring IOC Container原理解析

    Spring Framework 之 IOC IOC.DI基础概念 关于IOC和DI大家都不陌生,我们直接上martin fowler的原文,里面已经有DI的例子和spring的使用示例 <In ...

随机推荐

  1. oracle 职业学习指引

    风哥 它是阿里巴巴造出的概念.其本意是,在阿里巴巴的IT架构中,去掉IBM的小型机.Oracle数据库.EMC存储设备,代之以自己在开源软件基础上开发的系统. 思科.IBM.谷歌.高通.英特尔.苹果. ...

  2. 【转】无法将notepad++添加到打开方式列表中的解决办法

    问题:想要设置notepad++为默认打开方式,却发现在点击browse找到notepad++.exe点击打开后没有在打开方式列表中找到notepad++. 原因:更新程序版本后程序的路径发生了变动. ...

  3. webpack的几个使用方法

    1.gulp.task -> webpack -> webpack.config.js -> bundle.js -> html 2.cmd -> npm run -&g ...

  4. angular 实现tab切换(循环输出tab标题及tab下属内容,非direct,非include)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script sr ...

  5. ruby : nil?, empty? and blank?的选择

    article = nil article.nil? # => true empty? checks if an element - like a string or an array f.e. ...

  6. pickle序列化

    通过pickle来序列化: # -*- coding: utf-8 -*- import pickle #-------------------序列化--------------------- zoo ...

  7. 图片Exif 信息中Orientation的理解和对此的处理

    这个问题是在用七牛上传图片后获取宽高时发现的,一张图片,用图片浏览器打开始终是竖图,但是查看属性或者用七牛获取宽高,却发现宽大于高,也就是在属性中这是个横图.这样导致客户端用该宽高来展示图片会出现问题 ...

  8. c#操作Excel

    Excel是微软公司办公自动化套件中的一个软件,他主要是用来处理电子表格.Excel以其功能强大,界面友好等受到了许多用户的欢迎.在设计应用系统时,对于不同的用户,他们对于打印的需求是不一样的,如果要 ...

  9. jsgen 搭建

    1,mongodb 2,redis  http://www.cnblogs.com/lxx/archive/2013/06/04/3116985.html http://blog.csdn.net/w ...

  10. 缓存AsimpleCache -- 解决Android中Sharedpreferences无法存储List数据/ASimpleCache

    Sharedpreferences想必大家在项目中都经常会用到,但是如果需要在本地需要存储比较多的数据,存储一个集合的时,发现Sharedpreferences并不 是那么好使了. 分析 如果需要在本 ...