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

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>

总结:

使用构造函数进行依赖注入,有个问题那就是不确定性,那个值赋给那个变量:解决方式有两种,即 indextype这两个属性index=0index=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注入


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值