Spring依赖注入原理
接触过spring 的同学应该都知道依赖注入,依赖注入又称控制反转,其内涵就是,将创建某个bean的控制权力,由原来需要引用这个bean的bean转移(反转)到外部的spring IOC容器,由IOC容器统一创建,并且注入到需要引用的bean中去。 那么spring是怎么做到依赖注入的,我们来看看spring是怎么做的吧!
其实,spring的本质是一个工厂(beanFactory)或者说bean容器,它按照我们的要求,生产我们需要的各种各样的bean,提供给我们使用。只是在生产bean的过程中,需要解决bean之间的依赖问题,才引入了依赖注入(DI)这种技术。也就是说依赖注入是beanFactory生产bean时为了解决bean之间的依赖的一种技术而已。但是,我们一般都不直接用BeanFactory,而是用它的实现类ApplicationContext,这个类会自动解析我们配置的applicationContext.xml,然后根据我们配置的bean来new对象,将new好的对象放进一个Map中,键就是我们bean的id,值就是new的对象。
我们来看一下beanFactory的代码:
package org.springframework.beans.factory;
public interface BeanFactory {
String FACTORY_BEAN_PREFIX = "&";
Object getBean(String var1) throws BeansException;
<T> T getBean(String var1, Class<T> var2) throws BeansException;
<T> T getBean(Class<T> var1) throws BeansException;
Object getBean(String var1, Object... var2) throws BeansException;
<T> T getBean(Class<T> var1, Object... var2) throws BeansException;
...
}
beanFactory是一个接口,其中定义了各种getBean()方法,我们可以看到返回的是一个object对象,因此通过上下文对象ApplicationContext对象拿到的对象都必须通过强转能变成指定的类型的对象。
我们再来模拟ClassPathXmlApplicationContext的是怎么拿到bean的:
package com.spring.Context; import java.util.HashMap;
import java.util.List;
import java.util.Map; import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader; public class ClassPathXmlApplicationContext implements BeanFactory {
private Map<String, Object> beanMap = new HashMap<String, Object>(); //map的value是object
public ClassPathXmlApplicationContext(String fileName) throws Exception{
SAXReader reader = new SAXReader();
Document document = reader.read(this.getClass().getClassLoader().getResourceAsStream(fileName)); //SAX解析对应的xml配置文件
List<Element> elements = document.selectNodes("/beans/bean");
for (Element e : elements) {
String id = e.attributeValue("id");
String value = e.attributeValue("class");
Object o = Class.forName(value).newInstance(); //利用反射通过类名拿到的类的一个实例对象
beanMap.put(id, o);
}
} public Object getBean(String id) {
return beanMap.get(id);
} }
我们可以发现,通过spring getBean()拿到的对象实例,都是通过读取applicationContext.xml文件,再通过反射拿到的类的实例对象。
因此,spring注入的对象必须可以实例化,也就是说,接口和抽象类是不能通过spring实现注入的,因为两者都不能实例化。
这就让人很不能理解了,因为在做spring-mybatis整合的时候,我们有一个常见的做法就是在service层通过注解注入dao层接口,在这里不是可以注入接口吗?为什么又说spring不能注入接口呢?
其实,这里注入的接口,并不是真正的接口,我们不妨吧这个注入的“接口”打印出来看看,到底是个什么东西:
the dao is: org.apache.ibatis.binding.MapperProxy@33e4ae3b
the dao class is : class com.sun.proxy.$Proxy21
输出显示,其实注入的并不是接口,而是mybatis中的mapper对象的代理类。
至于这个里面的玄机,还是等下次去探讨吧!
Spring依赖注入原理的更多相关文章
- Spring依赖注入原理分析
在分析原理之前我们先回顾下依赖注入的概念: 我们常提起的依赖注入(Dependency Injection)和控制反转(Inversion of Control)是同一个概念.具体含义是:当某个角色( ...
- Spring学习笔记——Spring依赖注入原理分析
我们知道Spring的依赖注入有四种方式,各自是get/set方法注入.构造器注入.静态工厂方法注入.实例工厂方法注入 以下我们先分析下这几种注入方式 1.get/set方法注入 public cla ...
- Spring 依赖注入原理
所谓依赖注入就是指:在运行期,由外部容器动态地将依赖对象注入到组件中.当spring容器启动后,spring容器初始化,创建并管理bean对象,以及销毁它.所以我们只需从容器直接获取Bean对象就行, ...
- 形象化的spring 依赖注入原理
转. IoC就是Inversion of Control,控制反转.在Java开发中,IoC意味着将你设计好的类交给系统去控制,而不是在你的类内部控制.这称为控制反转. 下面我们以几个例子来说明什 ...
- spring依赖注入原理剖析
PropertyDefinition.java package junit.test; public class PropertyDefinition { private String name; p ...
- Spring、Spring依赖注入与编码剖析Spring依赖注入的原理
Spring依赖注入 新建PersonIDao 和PersonDao底实现Save方法: public interface PersonIDao { public void save(); } pub ...
- Spring 源码分析之 bean 依赖注入原理(注入属性)
最近在研究Spring bean 生命周期相关知识点以及源码,所以打算写一篇 Spring bean生命周期相关的文章,但是整理过程中发现涉及的点太多而且又很复杂,很难在一篇文章中把Spri ...
- (转)编码剖析Spring依赖注入的原理
http://blog.csdn.net/yerenyuan_pku/article/details/52834561 Spring的依赖注入 前面我们就已经讲过所谓依赖注入就是指:在运行期,由外部容 ...
- Spring依赖注入:@Autowired,@Resource和@Inject区别与实现原理
一.spring依赖注入使用方式 @Autowired是spring框架提供的实现依赖注入的注解,主要支持在set方法,field,构造函数中完成bean注入,注入方式为通过类型查找bean,即byT ...
随机推荐
- js 根据身份证号获取性别,年龄,等
$(function(){ $("#corpOwnerIdno").blur(function(){ //获取输入身份证号码 ...
- JavaScript 经典之一 闭包
作为一个前端开发者,闭包是必须要攻克掉的障碍.据说好多面试者挂在闭包面试上.下面我就给大家讲一下我理解中的闭包.不说太多的废话,直接进入主题. 变量作用域 学习编程语言需要明白,变量的作用域.变量作用 ...
- 在C#程序中模拟发送键盘按键消息
using System.Runtime.InteropServices; 引入键盘事件函数 [DllImport("user32.dll")]public static exte ...
- C#编程命名规范推荐
1.用Pascal规则来命名方法和类型. Pascal 大小写形式是指名称中的单词的第一个字母大写public class DataGrid{public void DataBind(){ }} 2. ...
- Error parsing HTTP request header Note: further occurrences of HTTP header parsing errors...java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are
先将异常信息贴出: 该问题是tomcat进行http request解析的时候报的错,网上的解决办法主要是修改Tomcat的server.xml,在<Connector port="8 ...
- 【RabbitMQ+Python入门经典】兔子和兔子窝 笔记
RabbitMQ工业级的消息队列服务器. 兔子和兔子窝 动机来源:从生产环境的电子邮件处理流程当中分支出一个特定的离线分析流程. 解决方案1: 开始使用MySQL处理,将要处理的东西放在表里面,另一个 ...
- SSM框架通过mybatis-generator自动生成代码
一.首先eclipse配置好maven环境,并且创建好一个SSM框架的工程 二.在pom.xml中添加plugin <build> <finalName>ssm_web< ...
- 前端worker之web worker
web worker 背景 众所周知javascript是单线程的,同一时间内只能做一件事情. 这是十分必要的,设想,如果js是多线程的.有个dom元素两个线程同时做了改变,一个display:non ...
- excel vlookup
今天在百度知道的时候,看到旁边有人问excel中条件查找vlookup的问题,有几位高手都知道使用vlookup作答,可惜都是没有经过测试,直接复制别人的答案,让所有的读者都无法实施,一头雾水.今天我 ...
- 大数据查询——HBase读写设计与实践
导语:本文介绍的项目主要解决 check 和 opinion2 张历史数据表(历史数据是指当业务发生过程中的完整中间流程和结果数据)的在线查询.原实现基于 Oracle 提供存储查询服务,随着数据量的 ...