Spring Ioc
- IoC:Inverse of Control(控制反转)
- 读作“反转控制”,不是什么技术,而是一种设计思想,就是将原本在程序中手动创建对象的控制权,交由Spring框架来管理。
我们举个例子
现实生活中,人们要用到一样东西的时候,第一反应就是去找到这件东西,比如想喝新鲜橙汁,在没有饮品店的日子里,最直观的做法就是:买果汁机、买橙子,然后准备开水。值得注意的是:这些都是你自己“主动”创造的过程,也就是说一杯橙汁需要你自己创造。
然而到了今时今日,由于饮品店的盛行,当我们想喝橙汁时,第一想法就转换成了找到饮品店的联系方式,通过电话等渠道描述你的需要、地址、联系方式等,下订单等待,过一会儿就会有人送来橙汁了。
Spring Ioc
-
Spring IoC容器
Spring容器提供IoC容器(也可以叫Bean容器)来管理和容纳我们所定义开发的各种各样的Bean,并且我们可以从中获取各种发布在Spring Ioc容器的Bean,并且通过描述可以得到它
-
Spring IoC 容器的设计
Spring IoC 容器的设计主要是基于以下两个接口:-
BeanFactory
-
ApplicationContext
-
其中 ApplicationContext 是 BeanFactory 的子接口之一,换句话说:BeanFactory 是 Spring IoC 容器所定义的最底层接口,而 ApplicationContext 是其最高级接口之一,并对 BeanFactory 功能做了许多的扩展,所以在绝大部分的工作场景下,都会使用 ApplicationContext 作为 Spring IoC 容器。
从上图中我们可以几乎看到, BeanFactory 位于设计的最底层,它提供了 Spring IoC 最底层的设计,为此,我们先来看看该类中提供了哪些方法:
-
【getBean】 对应了多个方法来获取配置给 Spring IoC 容器的 Bean。
按照名字和类型拿 bean:(只推荐这种)
bean = (Bean) factory.getBean(“beanName”, Bean.class);
【isSingleton】 用于判断是否单例,如果判断为真,其意思是该 Bean 在容器中是作为一个唯一单例存在的。
【isPrototype】则相反,如果判断为真,意思是当你从容器中获取 Bean,容器就为你生成一个新的实例。 -
下面我们来认识一个 ApplicationContext 的子类—ClassPathXmlApplicationContext。
-
创建ApplicationContext.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 将User接口的实现类的实例交给spring创建 -->
<bean id="user" class="com.tedu.pojo.User">
<property name="id" value="1"></property>
<property name="name" value="熊大"></property>
<property name="age" value="18"></property>
</bean>
</beans>
这里定义了一个 bean ,这样 Spring IoC 容器在初始化的时候就能找到它们,然后使用 ClassPathXmlApplicationContext 容器就可以将其初始化:
package com.tedu.Test;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.tedu.pojo.User;
public class testSpring {
static ClassPathXmlApplicationContext context=null;
static {
context = new ClassPathXmlApplicationContext("applicationContext.xml");
}
@Test
public void testUser() {
User u = (User) context.getBean("user");
System.out.println(u);
}
}
-
BeanFactory 和 ApplicationContext 的区别:
BeanFactory:是Spring中最底层的接口,只提供了最简单的IoC功能,负责配置,创建和管理bean。
在应用中,一般不使用 BeanFactory,而推荐使用ApplicationContext(应用上下文),原因如下。
ApplicationContext:
1.继承了 BeanFactory,拥有了基本的 IoC 功能;
2.除此之外**,ApplicationContext** 还提供了以下功能:
① 支持国际化;
② 支持消息机制;
③ 支持统一的资源加载;
④ 支持AOP功能;
Spring IoC 的容器的初始化和依赖注入
Bean 的定义分为 3 步:
1.Resource 定位
Spring IoC 容器先根据开发者的配置,进行资源的定位,在 Spring 的开发中,通过 XML 或者注解都是十分常见的方式,定位的内容是由开发者提供的。
2.BeanDefinition 的载入
这个时候只是将 Resource 定位到的信息,保存到 Bean 定义(BeanDefinition)中,此时并不会创建 Bean 的实例
3.BeanDefinition 的注册
这个过程就是将 BeanDefinition 的信息发布到 Spring IoC 容器中
注意:此时仍然没有对应的 Bean 的实例。
做完了以上 3 步,Bean 就在 Spring IoC 容器中被定义了,而没有被初始化,更没有完成依赖注入,也就是没有注入其配置的资源给 Bean,那么它还不能完全使用。
对于初始化和依赖注入,Spring Bean 还有一个配置选项——【lazy-init】,其含义就是是否初始化 Spring Bean。在没有任何配置的情况下,它的默认值为 default,实际值为 false,也就是 Spring IoC 默认会自动初始化 Bean。如果将其设置为 true,那么只有当我们使用 Spring IoC 容器的 getBean 方法获取它时,它才会进行 Bean 的初始化,完成依赖注入。