Spring之ioc控制反转(依赖注入)

个人感觉依赖注入比控制反转更好理解,所以下面就只说依赖注入:

spring的整体结构示意图:

一、spring 中的概念

beanFactory容器

1、容器是spring框架的核心,容器使用ioc依赖注入来管理所有组成应用系统的组件。

2、spring中的两种容器: beanFactory  这个容器提供了基础的依赖注入支持,而且是延迟加载的,而 applicationcontext是对beanFactory 这个容器的扩展,

3、beanFactory :beanFactory就是一个Bean工厂,使用了工厂模式,但bean工厂不像一般的工厂,只提供特定类的bean而是一个通用的工厂,可以创建和分发各种类型的bean,beanFactory不仅仅只是创建和分发bean因为我们知道,这个bean工厂知道应用中的很多对象,在创建这些对象的时候,创建出了这些对象之间的关联关系,bean工厂还管理这些对象的生命周期。

4、beanFactory 接口的实现类有很多,我们这里就举一个常用的类:  XMLBeanFactory, XMLBeanFactory构造方法的参数是一个inputStream对象,而传递进来的就是我们定义bean的xml文件

5、实例:BeanFactory  beanfactory = new  XMLBeanFactory(newFileInputStream(bean.xml));  这样beanFactory就获取了配置文件中bean的信息,但是bean是延迟实例化的所以现在只是加载进来了,但还是没有创建实例,只有在使用的时候尽心创建

6、 User user=(User)beanfactory.getBean("user");

当我们调用getBean()时工厂会实例化并且会依赖注入设置相关属性值。

ApplicationContext 容器

1、applicationcontext和beanFactory看来都是一样的,都是加载bean的信息,配置bean和分发bean,但是application
context作为beanFactory的扩展有一些额外的功能:(1)文本信息解析工具,包括对国际化的支持(2)应用上下文提供了载入文件资源的通用方法(3)应用上下文可以向注册为监听器的bean发送事件,因为application
context的额外功能所以在应用中大都使用application context而beanFactory在资源较少的移动设备上使用

2、ApplicationContext的实现:ClassPathXmlApplicationContext()类路劲中的xml文件中载入上下文信息,FileSystemXmlApplicationContext()文件系统xml获取上下文信息

XmlWebApplicationContext()从网络获取上下文信息。

3、我们知道 ApplicationContext是对beanFactory的扩展所以我们同样可以使用
.getBean("User")来获取对象,但是这里有点不同,那就是在beanFactory中使用的就是懒加载,在调用getBean()的时候才会创建实例而ApplicationContext
() 在上下文预加载的时候就创建了实例,在使用的时候不用等待创建而是直接使用。

Spring中bean的周期

1、容器寻找bean的定义信息,并且实例化bean

2、使用依赖注入,spring按照bean定义信息配置bean的所有属性

3、如果bean实现了BeanNameAware接口则工厂调用bean的setBeanName() 方法传递bean的Id

4、如果bean实现了beanFacgtoryAware 接口则工厂调用 setBeanFactory()方法传入工厂本身。

5、如果有BeanPostProcess和bean关联那么他们的PostProcessBeforeInitialzation()方法将被调用

6、如果bean指定了init-method 方法则将被调用

7、如果有BeanPostProcess和bean关联那么他们的PostProcessAfterInitialzation()方法将被调用

到这里bean就可以在系统中被使用了,并将一直保存在BeanFactory 中直到他不在使用。

8、删除: spring  中有两种方式:(1)、如果bean实现了Disposable接口则destory方法将会被调用(2)、自己定义定义了销毁方法则执行他  destroy-method

依赖注入

1、所谓依赖注入,即组件之间的依赖关系由容器在运行期决定,形象地说,即由容器动态地将某种依赖关系注入到组件之中。

装配

在spring容器内拼凑bean叫做装配,装配bean的时候你是在告诉容器需要哪些bean,以及容器如何使用依赖注入将他们配合在一起。

实例化

1、在使用spring容器进行bean类的管理的时候,我们获取bean类有两种类型,一种就是在spring中使用了单例模式,获取的都是第一次加载的时候创建的那个bean实例,第二种就是在spring中没有定义单例模式,每获取一次就会产生一个新的bean实例。

区别这两种的配置:

<beanid="user" class="com.inspur.User" singleton=off>

</bean>

// singleton(单一的 唯一的) 这里关闭了单例模式,所以每次获取的bean对象都是新的,而在spring中singleton默认是开着的,因为像数据库连接池,网络资源等创建新对象很浪费资源,所以还是使用单例模式比较好,如果没有特别需求还是使用单例模式比较好!

二、注入实例

1、setter 注入

一般属性注入

<beanid="user" class="com.inspur.User">

<propertyname="name">

<value>"Name"</value>

</property>

<propertyname="age">

<value>12</value>

</property>

</bean>

<beanid="user" class="com.inspur.User">

<property name="name"  value="name"/>

<property name="age"  value=12 />

</bean>

//这种方式就是set注入,所谓的注入也就是给spring中的bean的属性赋值

属性的值为其他的类

<beanid="user" class="com.inspur.User">

<propertyname="name">

<value>"Name"</value>

</property>

<propertyname="address">

<ref bean="otherBeanId"/>  // 属性的值为某一实例,所以进行了引用

</property>

</bean>

如果某个属性的值为其他的类,则可以按如下操作完成

<beanid="user" class="com.inspur.User">

<propertyname="name"  value="name">

<propertyname="address"  ref="otherBeanId">// 属性的值为某一实例,所以进行了引用

</bean>

属性的类型为集合:list

<property name="list">

<list>

<value>1</value>   // 这里的value可以是任何类型

<value>2</value>

</list>

</property>

属性的类型为集合:set

属性的类型为集合:map,前提还是类型为map

Props/prop属性值的设置:

这个没见过但是他的使用方式和map一样,但是他的值只是
string类型所以就不用value了:

特殊的值:将某个属性的值设置为null:

2、构造函数注入

构造函数只有一个参数

<beanid="user" class="com.inspur.User">

<constructor-arg>

<value>Name</value>

</constructor-arg>

</bean>

构造函数注入,有两个不同类型的参数

<beanid="user" class="com.inspur.User">

<constructor-arg type="java.lang.String"> // 标明参数的类型

<value>"6"</value>

<constructor-arg>

<constructor-arg type="int">  // 标明参数的类型

<value>8</value>

<constructor-arg>

</bean>

构造函数注入,有两个相同类型的参数

<beanid="user" class="com.inspur.User">

<constructor-arg index=0>   // 是从0开始的

<value>6</value>

</constructor-arg>

<constructor-arg index=1>

<value>8</value>

</constructor-arg>

</bean>

总结:

使用构造函数进行依赖注入,有个问题那就是不确定性,那个值赋给那个变量:解决方式有两种,即
index和type这两个属性index=“0”index=“1”这个就是来确定构造函数中第一个第二个参数的。

而type=“int”或type="java.lang.String"这个就是一个构造函数中有不同类型的参数的时候我们使用type来确定。

总的来说构造函数注入的方式还是有不确定性,因为有的时候如果有过个构造函数等情况就没办法处理了。

上面的那种注入方式都是手动注入,下面我们看看spring中的自动注入:

自动注入--byName(按照名称来注入)

例:

springtest中有个属性就是Student student;

<bean  id="springtest" class="com.inspur.imp.SpringTest"   autowire="byName"/>

// 这里是按照名称来自动注入的 也就是SpringTest 这个类中有个Student   student 属性 而使用byName方式来注入的时候就会将id=student 的这个bean注入到 SpringTest的Student  student这个属性上。

<bean  id="student" class="com.inspur.imp.Student">

<propertyname="age">

<value>12</value>

</property>

<propertyname="name">

<value>"stuname"</value>

</property>

</bean>

自动注入--byType(按照类型来注入)

<bean  id="springtest" class="com.inspur.imp.SpringTest"   autowire="byType"/>

自动注入--constructor(按照构造函数来注入):

<bean  id="springtest" class="com.inspur.imp.SpringTest"   autowire="constructor"/>

自动注入---使用何种注入方式,可以让容器自己选择:

<bean  id="springtest" class="com.inspur.imp.SpringTest"   autowire="autodetect"/>

自动注入减少了配置,但是这样会带来很多麻烦因为有可能找不到,就会报异常,而且平时使用最多的也就是比较方便的set注入

时间: 2024-12-05 21:25:50

Spring之ioc控制反转(依赖注入)的相关文章

玩转Spring MVC (一)---控制反转(依赖注入)

Spring的核心是控制反转,什么是控制反转呢?小编浅述一下自己的拙见,有不当之处还希望大家指出. 控制反转(IOC),也可以叫做依赖注入(DI),这两个词其实是一个概念. 控制反转,那是什么控制被反转了呢?Martin Fowler总结出是"依赖对象的获得"被反转了. 什么是"依赖对象"呢?大多数情况下,java中的都需要通过多个类的合作实现某种业务逻辑,每个对象都需要与他合作的对象的引用,这个与他合作的对象就是它的"依赖对象". 如果我们要引

Spring框架使用(控制反转,依赖注入,面向切面AOP)

参见:http://blog.csdn.net/fei641327936/article/details/52015121 Mybatis: 实现IOC的轻量级的一个Bean的容器 Inversion of control 控制反转:由容器控制程序之间的关系,不是程序代码操作 Depend Inject 依赖注入 Aspect oriented programming 面向切面编程 Spring能帮助我们根据配置文件创建及组装对象之间的依赖关系: Spring面向切面编程能帮助我们无耦合的实现日

Spring IOC - 控制反转(依赖注入) - 创建对象的方式

a.通过类的无参构造方法创建对象 在入门案例中就是这种方式.当用最普通的方式配饰一个<bean>时,默认就是采用类的 无参构造创建对象.在Spring容器初始化时,通过<bean>上配置的class属性反射的到字 节码对象,通过newInstance()创建对象. Class c = Class .forName("类的全路径名称") Object obj = c.newInstance() 这种方式下Spring创建对象,必须有无参的构造,否则无法通过反射创建

Spring IOC - 控制反转(依赖注入) - 配置初始化和销毁的方法

在Spring中如果某个bean在初始化之后,或销毁之前要做一些额外操作可以为该bean配置初始化和销毁的我方法,在这些方法中完成需要的功能. 实验: 通过断点调试模式,测试初始化方法和销毁方法的执行 package cn.tedu.beans; public class ProdDao { public ProdDao() { System.out.println("ProdDao 被创建..."); } public void init() { System.out.println

Spring 学习 2- IOC原理 控制反转/依赖注入

控制反转/依赖注入 最近,买了本spring入门书:spring In Action .大致浏览了下感觉还不错.就是入门了点.Manning的书还是不错的,我虽然不像哪些只看Manning书的人那样专注于Manning,但怀着崇敬的心情和激情通览了一遍.又一次接受了IOC .DI.AOP等Spring核心概念. 先就IOC和DI谈一点我的看法. IOC(DI):其实这个Spring架构核心的概念没有这么复杂,更不像有些书上描述的那样晦涩.Java程序员都知道:java程序中的每个业务逻辑至少需要

spring IOC控制反转 DI注入

<!-- 初始化 init-method="init" 销毁destroy-method="destory" --> <!--懒加载 lazy-init="true" --> <bean id="IUDao" class="dao.IUDao" scope="singleton" init-method="init" destroy-me

控制反转&amp;依赖注入

控制反转 如果要在A里面使用C,你会怎么做呢?当然是直接去创建C的对象,也就是说,是在A类中主动去获取所需要的外部资源C,这种情况被称为正向的.那么什么是反向呢?就是A类不再主动去获取C,而是被动等待,等待IoC/DI的容器获取一个C的实例,然后反向的注入到A 类中. 依赖注入 依赖注入和控制反转是对同一件事情的不同描述,从某个方面讲,就是它们描述的角度不同.依赖注入是从应用程序的角度在描述,可以把依赖注入描述完整点:应用程序依赖容器创建并注入它所需要的外部资源:而控制反转是从容器的角度在描述,

大话依赖倒置?控制反转?依赖注入?面向接口编程

那些年,空气中仿佛还能闻到汉唐盛世的余韵,因此你决不允许自己的脸上有油光,时刻保持活力.然而,你一定曾为这些“高深术语”感到过困扰——依赖倒置•控制反转•依赖注入•面向接口编程.也许时至今日,你仍对它们一知半解.不过就在今天,这一切都将彻底改变!我将带领你以一种全新的高清视角进入奇妙的编程世界,领略涵泳在这些“高深术语”中的活泼泼的地气,以及翩跹于青萍之末的云水禅心. ·内聚 内聚,通俗的来讲,就是自己的东西自己保管,自己的事情自己做. 经典理论告诉我们,程序的两大要素:一个是数据(data),

依赖倒置,控制反转,依赖注入

好的文章,总是担心消失,自己保存一遍,这里是原文 向依赖关系宣战 依赖倒置.控制反转和依赖注入辨析在<道法自然——面向对象实践指南>一书中,我们采用了一个对立统一的辩证关系来说明“模板方法”模式—— “正向依赖 vs. 依赖倒置”(参见:<道法自然>第15章[王咏武, 王咏刚 2004]).这种把“好莱坞”原则和 “依赖倒置”原则等量齐观的看法其实来自于轻量级容器PicoContainer主页上的一段话: “控制反转(Inversion of Control)的一个著名的同义原则是