下面来了解一下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. Linux 随机生成随机数

    #!/bin/bash echo $(($RANDOM % 39)) 表示生成0-39的随机数 并且不为0和39

  2. [2016.08.09]文本替换专家 v5.2

    软件名称:文本替换专家最新版本:v5.2软件授权:共享软件发布日期:2016.01.18文件大小:650KB操作系统:XP/2003/Win7/Win2008开发人员:胡洪祥版权所有:胡洪祥

  3. MyBatis入门学习教程-使用MyBatis对表执行CRUD操作

    上一篇MyBatis学习总结(一)--MyBatis快速入门中我们讲了如何使用Mybatis查询users表中的数据,算是对MyBatis有一个初步的入门了,今天讲解一下如何使用MyBatis对use ...

  4. <<面向模式的软件架构2-并发和联网对象模式>>读书笔记

    服务访问和配置模式 Wrapper Facade可以将有非对象API提供的函数和数据封装到面向对象的类接口中 就是把底层API再封装一次,让外部不用关心是调用哪个平台的API,不如锁,在不同的平台上可 ...

  5. C++的隐式类型转换与转换操作符

    C++标准允许隐式类型转换,即对特定的类,在特定条件下,某些参数或变量将隐形转换成类对象(创建临时对象).如果这种转换代价很大(调用类的构造函数),隐式转换将影响性能.隐式转换的发生条件:函数调用中, ...

  6. TensorFlow中max pooling层各参数的意义

    官方教程中没有解释pooling层各参数的意义,找了很久终于找到,在tensorflow/python/ops/gen_nn_ops.py中有写: def _max_pool(input, ksize ...

  7. Spring自定义缓存管理及配置Ehcache缓存

    spring自带缓存.自建缓存管理器等都可解决项目部分性能问题.结合Ehcache后性能更优,使用也比较简单. 在进行Ehcache学习之前,最好对Spring自带的缓存管理有一个总体的认识. 这篇文 ...

  8. 同时使用Junit4的@Parameterized参数化测试和Spring容器

    转载:http://www.jianshu.com/p/d191fe54915f 整合Spring容器 @SpringApplicationConfiguration(classes = Applic ...

  9. MVC部分视图含义

    Partail Views 类似于ASPX视图引擎中的用户控件,使用部分视图可以创建放置于不同页面的通用部分.

  10. Request.ServerVariables

    APPL_MD_PATH-->APPL_PHYSICAL_PATH-->C:\Users\TomZhang\Desktop\GAP\后台修改\UMS\UMSSite\AUTH_TYPE-- ...