文章目录
1、IOC是什么?
IOC(Inversion of Control)称为控制反转,也被称为依赖项注入(DI),是一种编程思维,而不是技术实现。IOC指的就是 控制权的反转,用原来手动创建对象,转成java程序创建对象。
- 传统的开发方式:类 A 中手动通过 new 关键字来 new 一个 B 的对象出来
- 使用IOC思维的开发方式:不通过 new 关键字来创建对象,而是通过IOC 容器(Spring 框架) 来帮助我们实例化对象。我们需要哪个对象,直接从IOC 容器里面获取即可。
从两种不同的开发方式对比来说:对象是由Spring创建,管理,装配了,而不是程序!
我们分别解析一下控制反转的意思:
- 控制:指的是对象创建(实例化、管理)的权力发生改变。这个权利从程序本身变为了 Sping IOC 容器。
- 反转·:指的是控制权。程序本身不创建对象,而变成被动的接收 Spring IOC 容器创建的对象。
2、IOC容器
IOC容器是Spring实现IOC的载体, IOC 容器实际上就是个 Map(key,value),Map 中存放的是各种对象。
Spring 中提供了 BeanFactory
接口,它提供了一种高级配置机制,能够管理任何类型的对象。它有一个子接口 ApplicationContext
,这个接口代表 IOC 容器,并负责实例化,配置和组装 Bean。
ApplicationContext
接口的实现类有很多,但是比较常用的是 ClassPathXmlApplicationContext
类和FileSystemXmlApplicationContext
类。
3、通过 XML 的方式配置 Bean
什么是Bean ?是指在 Spring 中,IOC 容器管理的对象称为 Bean。 Bean 是由 IOC 容器实例化,组装和以其他方式管理的对象,简单来说 Bean 就是对象。
想要使用IOC容器,首先要配置Bean,然后实例化容器。最主要的就是配置Bean,下面我们将具体讲解Bean的配置。
在 Spring 中有三种方式配置Bean:XML、Java注解和 Java 代码。下面主要是通过 XML 的方式配置 ,具体步骤如下:
-
创建应用程序上下文:因为 Bean 是存放在XML文件中的,所以第一步就是创建一个 XML。在资源文件夹中创建一个XML文件,文件命名可以自定义,并且需要将此XML文件设置为应用程序上下文,设置方式如下:
-
配置Bean:通过
<bean>
标签配置Bean,如下所示
在配置过程中需要给<bean>
标签添加一些属性:id
属性:bean的唯一标识符,也就是相当于我们学的对象名class
属性:bean 对象所对应的全限定名:包名+类型name
属性:别名,而且同时name可以同时取多个别名,用逗号 ( ,)、分号 ( ; ) 或空格分隔lazy-init
属性:是将 bean 定义标记为延迟初始化来防止单例 bean 的预实例化,它有三个值——ture(确定延迟)、false(预先实例化)和default(默认)。scope
属性:详解见下Bean的作用域。init-method
属性:指定类中的初始化方法名称,在bean被实例化之后里面执行。destroy-method
属性:指定类中的销毁方法名称,在bean被销毁之后里面执行。
3.1、配置别名(name)
在上述属性中,有一个 name
属性,这个属性主要用于定于别名。但是,在XML中除了使用<Bean>
标签上的 name
属性取别名,可以使用<alias>
标签,具体使用方法如下:
上述图片中,我们使用name
属性和<alias>
标签对 Bean 取别名,在使用过程中我们可以使用user、user1、user2和user3四种名称。
3.2、作用域(sorce)
Bean的作用域(sorce)有singleton、prototype、request、session和application五种取值。其代表含义为:
singleton
:在spring IOC容器仅存在一个Bean实例,Bean以单例方式存在。是bean作用域范围的默认值,这个仅存的Bean实例创建时机为 XML 被加载的时候。prototype
:每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,既创建时机为调用getBean
方法实例化时。request
:每次HTTP请求都会创建一个新的Bean,该作用域仅适用于web的Spring WebApplicationContext环境。session
:同一个HTTP Session共享一个Bean,不同Session使用不同的Bean。该作用域仅适用于web的Spring WebApplicationContext环境。application
:限定一个Bean的作用域为ServletContext的生命周期。该作用域仅适用于web的Spring WebApplicationContext环境。
3.3、懒加载(lazy-init)
在 ICO 容器被初始化的时候,会创建和配置所有 Bean。可以通过lazy-init
属性延迟初始化的 Bean,这样设置之后,Bean 的初始化就是在首次请求时而不是在启动时。
<!-- true 表示进行懒加载 -->
<bean id="..." class="..." lazy-init="true"/>
还可以在通过default-lazy-init
属性设置整个 IOC 容器的控制延迟初始化:
<!-- default-lazy-init 使用在 beans 标签上,而不是 bean -->
<beans default-lazy-init="true">
</beans>
4、对 Bean 进行依赖注入
依赖注入(DI)是一个过程。对象中封装了对象的属性和行为,而在实例化的时候,我们通过要对这些属性赋值。
依赖注入有两种方式:基于构造函数的依赖注入和基于 Setter 的依赖注入。
4.1、基于构造函数
<constructor-arg>
标签:使用这种标签是通过有参构造的方式完成注入,既在类中通过有参构造完成属性赋值。使用方法如下:
<bean id="..." class="...">
<!--引用赋值,引用容器中其他 Bean -->
<constructor-arg ref="..."/>
<!--下标赋值 -->
<constructor-arg index="0" value="张三"/>
<!--类型赋值(不建议使用) -->
<constructor-arg type="java.lang.String" value="张三"/>
<!--通过参数名来赋值 -->
<constructor-arg name="name" value="张三"/>
</bean>
使用 type
属性的时候存在歧义,因为一个对象中可能存在多个同类型的属性,而index
和name
可以消除歧义。
4.2、基于 Setter
<property>
标签:使用这种标签是用 Setter
方法完成注入,既在类中通过 set
方法完成属性赋值,使用方法如下:
<bean id="..." class="...">
<!--第一种,普通的value注入 String类型-->
<property name="name" value="张三"/>
<!--第二种,引用类型注入Bean-->
<property name="address" ref="address"/>
<!--第三种,数组注入-->
<property name="books">
<array>
<value>Spring</value>
</array>
</property>
<!--第四种,list注入 List类型-->
<property name="hobbys">
<list>
<value>java</value>
<value>vue</value>
</list>
</property>
<!--第五种,Map注入 Map类型-->
<property name="card">
<map>
<entry key="id" value="0001"/>
</map>
</property>
<!--第六种,set注入 Set类型-->
<property name="games">
<set>
<value>springboot</value>
</set>
</property>
<!--第七种,空值注入 String类型-->
<property name="wife">
<null/>
</property>
<!--第八种,properties注入-->
<property name="info">
<props>
<prop key="name">王五</prop>
</props>
</property>
<bean/>
4.3、简化标签
可以在 XML 中简化上面两种依赖注入方式:既通过p命名空间和c命名空间完成。这两种命名空间只是简化了上面提到了两种标签。
p标签注入和c标签注入需要在约束条件中加入一条约束代码,分别是xmlns:p=“http://www.springframework.org/schema/p” 和xmlns:c=“http://www.springframework.org/schema/c”。
使用方法如下:
<!--源代码-->
<bean id="..." class="...">
<property name="name" value="张三"/>
</bean>
<!--通过p命名注入,可以直接注入属性的值:properties-->
<bean id="..." class="..." p:name="张三" p:age="18"/>
<!--通过c命名注入,通过构造器注入:construct-args-->
<bean id="..." class="..." c:name="盾山" c:age="19"/>
5、其他标签
在团队开发中,可能有多个人负责不同的开发,不同的类注册需要在不同的bean中,而在项目整合时需要进行整合。而在Spring中提供了一种整合Bean的方法,使用 <import>
标签进行整合,使用方法如下:
6、IOC容器的使用
在配置完Bean之后,我们就要进行使用,其实使用方法很简单,只需要实例化IOC容器就行。而org.springframework.context.ApplicationContext
接口代表了IOC容器。而实例化通常使用ClassPathXmlApplicationContext
进行。实例化完成之后,使用getBean("名称")
方法就行获取具体的Bean。具体代码如下
//获取带IOC容器,"services.xml", "daos.xml"为参数表示xml文件的地址,可以设置多个
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
//我们的对象现在都在Spring中管理了,我们要使用,直接去里面取出来即可,hello为需要创建的对象所在的类名,
Hello hello = (Hello) context.getBean("hello");
//或者使用
Hello hello = context.getBean("hello",Hello.Class);
如有错误请及时私信作者!