前一段时候我把Spring技术内幕的关于IOC原理一章看完,感觉代码太多,不好掌握,我特意又各方搜集了一些关于IOC原理的资料,特加深一下印象,以便真正掌握IOC的原理。

IOC的思想是:Spring容器来实现这些相互依赖对象的创建、协调工作。对象仅仅须要关系业务逻辑本身就能够了。

SpringIOC容器的执行步骤是:

1、资源定位,即首先要找到applicationContext.xml文件

2、BeanDefinition的加载,把XML文件里的数据统一加载到BeanDefinition中,方便以后的处理

3、向IOC容器中注入BeanDefinition数据

4、将BeanDefinition中的数据进行依赖注入

IoC的一个重点是在系统执行中,动态的向某个对象提供它所须要的其它对象。这一点是通过DI(Dependency Injection。依赖注入)来实现的。比方对象A须要操作数据库。曾经我们总是要在A中自己编写代码来获得一个Connection对象。有了 spring我们就仅仅须要告诉spring。A中须要一个Connection,至于这个Connection怎么构造。何时构造,A不须要知道。在系统执行时,spring会在适当的时候制造一个Connection,然后像打针一样。注射到A其中。这样就完毕了对各个对象之间关系的控制。A须要依赖 Connection才干正常执行,而这个Connection是由spring注入到A中的。依赖注入的名字就这么来的。

那么DI是怎样实现的呢? Java 1.3之后一个重要特征是反射(reflection)。它同意程序在执行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。

举个现实生活中样例。如今有非常多中介公司,比如我爱我家。我爱我家会有各种各样的房源资料,当我们找房子时我们仅仅需把须要的房子告诉我爱我家,我爱我家会依据我们的需求给我们提供适合的房子。这样我们就不用自己去网上、小区广告等各个地方去搜集寻求适合自己的房子,整个过程由我爱我家中介来控制即可了,如今想想有个这个中介是不是使整个过程变得简单愉快了。当然,在实际生活中面对中介我们是须要交中介费的,好比SpringIOC我们也须要维护ApplicationContext这个配置文件,都是成本,面对Spring我们能够忽略成本,哈哈。

以下让我看看SpringIOC的执行过程:

1、首先加载ApplicationContext.xml,资源定位

首先资源定位终于是在Springframe下的AbstractBeanDefinitionReader类中的LoaderBeanDefinitions(String location,Set<Resource> actualResources) line 98,以下举例说明:

public static void main(String[] args) {
ApplicationContext context = new FileSystemXmlApplicationContext(
"applicationContext.xml");
User user= (User) context.getBean("user");
user.write();
}
 <bean id="user" class="com.jader.spring.Model.User">
<property name="name" value="jader" />
</bean>
 public class User{
private String name;
public void write() {
System.out.println("my name is:"+name);
}
public void setName(String name) {
this.name = name;
}
}

执行程序会输出:my name is jader,非常明显,SpringIOC已经把property里的value注入到User的name属性其中。

以下我们来分析Spring是怎么实现的

2、BeanDefinition的加载

加载和解析终于是在Springframework下的AbstractApplicationContext类的refresh()方法实现的,这种方法非常关键,里面包括了资源加载和解析,包括对lazy-init的额外处理等,line 445。以下举例说明:

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

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

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


<bean id="beanMap" class="BeanMap">
<property name="myBeanMap">
<map>
<entry key="name">
<value>jader</value>
</entry>
<entry key="age">
<value>26</value>
</entry>
</map>
</property>
</bean>

3、向IOC容器中注冊BeanDefinition

注冊终于是在Spring frame的DefaultListableBeanFactory类下的registerBeanDefinition(String beanName,BeanDefinition beanDefinition)方法中实现,line 664;以下举例说明:

            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);
}

4、依赖注入

SpringIOC的终于依赖注入是是通过AbstractAutowireCapableBeanFactory的doCreateBean(finale String beanName,final RootBeanDefinition mbd,final Object[] args)方法(line 480)的,这种方法里的关键方法有populateBean()和createBeanInstance()。正在实现注入是通过BeanWrapperImpl extends AbstractPropertyAccessor类的setPropertyValue()方法实现 line 911

原理是:通过反射机制实现的,在实例化一个类时。它通过反射调用类中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技术内幕的第一章介绍SpringIOC原理,难用理解,借助于这边文章能够帮我们理解一下。

书读百遍。其义自现,当你读一遍不明确的时候能够重复阅读,这篇文章我都是从网上多方搜集的资料。在这里我表示感谢,希望我们共同进步。

Spring技术内幕:SpringIOC原理学习总结的更多相关文章

  1. Spring技术内幕:设计理念和整体架构概述(转)

    程序员都很崇拜技术大神,很大一部分是因为他们发现和解决问题的能力,特别是线上出现紧急问题时,总是能够快速定位和解决. 一方面,他们有深厚的技术基础,对应用的技术知其所以然,另一方面,在采坑的过程中不断 ...

  2. 《spring技术内幕》读书笔记(1)——什么是POJO模式

    今天在看<spring技术内幕>,第一章中多次提到了使用POJO来完成开发,就百度了一下,在此保留 1.     什么是POJO POJO的名称有多种,pure old java obje ...

  3. 《Spring技术内幕》笔记-第二章 IoC容器的实现

    简单介绍 1,在Spring中,SpringIoC提供了一个主要的JavaBean容器.通过IoC模式管理依赖关系.并通过依赖注入和AOP切面增强了为JavaBean这样子的POJO提供事务管理,生命 ...

  4. Spring技术内幕:Spring AOP的实现原理(二)

    **二.AOP的设计与实现 1.JVM的动态代理特性** 在Spring AOP实现中, 使用的核心技术时动态代理.而这样的动态代理实际上是JDK的一个特性.通过JDK的动态代理特性,能够为随意Jav ...

  5. Spring技术内幕——深入解析Spring架构与设计原理(一)IOC实现原理

    IOC的基础 下面我们从IOC/AOP开始,它们是Spring平台实现的核心部分:虽然,我们一开始大多只是在这个层面上,做一些配置和外部特性的使用工作,但对这两个核心模块工作原理和运作机制的理解,对深 ...

  6. 《Spring技术内幕》学习笔记17——Spring HTTP调用器实现远程调用

    1.Spring中,HTTPInvoker(HTTP调用器)是通过基于HTTP协议的分布式远程调用解决方案,和java RMI一样,HTTP调用器也需要使用java的对象序列化机制完成客户端和服务器端 ...

  7. Spring技术内幕:Spring AOP的实现原理(一)

    一.SpringAOP的概述 1.AOP概念 AOP是Aspect-Oriented Programming(面向切面编程)的简称.维基百科的解释例如以下: Aspect是一种新的模块化机制,用来描写 ...

  8. Spring技术内幕:Spring AOP的实现原理(三)

    生成SingleTon代理对象在getSingleTonInstance方法中完毕,这种方法时ProxyFactoryBean生成AopProxy对象的入口.代理对象会封装对target目标对象的调用 ...

  9. Spring技术内幕:Spring AOP的实现原理(五)

    7.Advice通知的实现 AopProxy代理对象生成时,其拦截器也一并生成.以下我们来分析下Aop是怎样对目标对象进行增强的.在为AopProxy配置拦截器的实现中,有一个取得拦截器配置过程,这个 ...

随机推荐

  1. 函数中的this的四种绑定形式

    目录 this的默认绑定 this的隐式绑定 隐式绑定下,作为对象属性的函数,对于对象来说是独立的 在一串对象属性链中,this绑定的是最内层的对象 this的显式绑定:(call和bind方法) n ...

  2. [Apple开发者帐户帮助]五、管理标识符(2)启用应用服务

    您可以在证书,标识符和配置文件中查看和启用App ID的服务.包含已修改的App ID的供应配置文件将变为无效.您需要重新生成使用该App ID的配置文件. 注意:要为应用程序完全配置服务,请在Xco ...

  3. CentOS7 搭建Kafka(三)工具篇

    CentOS7 搭建Kafka(三)工具篇 做为一名懒人,自然不喜欢敲那些命令,一个是容易出错,另外一个是懒得记,能有个工具就最好了,一查还挺多,我们用个最主流的Kafka Manager Kafka ...

  4. Laravel5.1学习笔记8 Blade模板

    简介 模板继承 定义一个页面布局模板 扩展一个页面布局模板 展示数据 控制语法的结构 Service Injection 扩展 Blade   简介 Blade 是 Laravel 提供的一个既简单又 ...

  5. 项目平台统一(前后端IDE、代码风格)

    项目平台统一(前后端IDE.代码风格) 记录人:娄雨禛 前端:Webstorm(HTML+CSS+JavaScript) 后端:IntelliJ IDEA(Java) 代码风格:Java风格代码 代码 ...

  6. 复习java基础第六天(IO)

    一:File 类 • 输入:读取外部数据(磁盘.光盘等存储设备的数据)到程序(内存)中.  • 输出:将程序(内存)数据输出到磁盘.光盘等存储设备中 • Java 的 IO 流主要包括输入.输出两种 ...

  7. SAP computer之RAM

    RAM The RAM is a 16 X 8 static TTL RAM. We can program the RAM by means of the address and data swit ...

  8. Metric Learning度量学习:**矩阵学习和图学习

    DML学习原文链接:http://blog.csdn.net/lzt1983/article/details/7884553 一篇metric learning(DML)的综述文章,对DML的意义.方 ...

  9. java输入输入流图解

  10. 【ng-zorro-antd】加入in-memory-web-api插件后icon不显示

    在ng-zorro-antd框架下,根据angular的技术文档demo,加入in-memory-web-api后icon不显示 解决方案: 在app.module.ts中的imports:[]加入 ...