下面来了解一下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. cAdvisor0.24.1+InfluxDB0.13+Grafana4.0.2搭建Docker1.12.3 Swarm集群性能监控平台

    目录 [TOC] 1.基本概念 ​ 既然是对Docker的容器进行监控,我们就不自己单独搭建cAdvisor.InfluxDB.Grarana了,本文中这三个实例,主要以Docker容器方式运行. 本 ...

  2. AspNetPager控件报错误: Syntax error, unrecognized expression: input#ctl00$ContentPlaceHolder1$Aspnetpager1_input问题解决[摘]

    高版本IE,如IE10或者IE11在浏览页面时出现错误: Syntax error, unrecognized expression: input#ctl00$ContentPlaceHolder1$ ...

  3. Entity Framework 连接低版本数据库

    使用EF6连接SQL2012生成的Edmx,分页时生成的查询语句使用了SQL 2012引入的新特性  OFFSET 0 ROWS FETCH NEXT 20 ROWS ONLY,结果在生产环境使用的数 ...

  4. js预解析及特效

    预解析: // 作用域: // 域:空间.范围.区域…… // 作用:读.写 script 全局变量.全局函数 自上而下 函数 由里到外 {} 浏览器: “JS解析器” 1)“找一些东西” :var ...

  5. 转贴:让Windows 2008 R2 64bit支持ASP.NET 1.1应用程序

    随着 Windows Server 2003 的支持期限到期, 最近有很多企业将目前很多的 Windows Server 2003 升级到 Windows 2008 R2. 之前有许多 Web App ...

  6. Disconf

    通常我们会做如下配置:(disconf 2.6.21) <!-- 一次扫描 --> <bean id="disconfMgrBean" class="c ...

  7. 在java下使用log4j2记录日志

    1.定义: log4j2 指log4j 2.X及以上版本 2.安装 log4j-core-xx.jarlog4j-api-xx.jarlog4j-web-xx.jar(web项目的需要引用) 3.配置 ...

  8. Oracle_RAC数据库GI的PSU升级(11.2.0.4.0到11.2.0.4.8)

    Oracle_RAC数据库GI的PSU升级(11.2.0.4.0到11.2.0.4.8) 本次演示为升级oracle rac数据库,用GI的psu升级,从11.2.0.4.0升级到11.2.0.4.8 ...

  9. prim算法查找最小生成树

    我们在图的定义中说过,带有权值的图就是网结构.一个连通图的生成树是一个极小的连通子图,它含有图中全部的顶点,但只有足以构成一棵树的n-1条边.所谓的最小成本,就是n个顶点,用n-1条边把一个连通图连接 ...

  10. html基础 样式

    html样式:本文演示如何在head中添加样式信息使文本格式化 <html> <head> <style type="Text/css"> h1 ...