首先我们需要了解一下是什么是Ioc。

Ioc是Spring的核心技术之一,全称是Inversion of Control(控制反转)。最原始的创建对象的方法就是通过new来实现(手动的编写代码实现):

new Hollow();

而Spring提供了Ioc容器用于对象的创建以及配置、管理、销毁等。

控制:容器进行组件代码的控制和管理

反转:组件代码的控制权由外部代码转移到了内部容器 (程序员到容器)

当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象,这样做降低了类之间的耦合程度。不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。


那么到底什么是容器?

从程序的角度,容器实际上就是某些特定接口的实现类的实例

Spring提供了两种不同的类型的容器:

    Spring BeanFactory容器: 最简单的容器,给依赖注入提供了基本的支持

    ApplicationContext容器: ApplicationContext 容器继承自BeanFactory,它包括 BeanFactory 容器的所有功能,并对其功能进行了扩展。

Spring BeanFactory 容器

org.springframework.beans.factory.BeanFactor 接口

BeanFacotry是spring中比较原始的Factory。如XMLBeanFactory就是一种典型的BeanFactory。原始的BeanFactory无法支持spring的许多插件,如AOP功能、Web应用等。 
ApplicationContext接口,它由BeanFactory接口派生而来,ApplicationContext包含BeanFactory的所有功能,通常建议比BeanFactory优先。

image.png

代码:

public interface BeanFactory {
    String FACTORY_BEAN_PREFIX = "&";

    Object getBean(String var1) throws BeansException;

    <T> T getBean(String var1, Class<T> var2) throws BeansException;

    Object getBean(String var1, Object... var2) throws BeansException;

    <T> T getBean(Class<T> var1) throws BeansException;

    <T> T getBean(Class<T> var1, Object... var2) throws BeansException;

    <T> ObjectProvider<T> getBeanProvider(Class<T> var1);

    <T> ObjectProvider<T> getBeanProvider(ResolvableType var1);

    boolean containsBean(String var1);

    boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;

    boolean isPrototype(String var1) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String var1, ResolvableType var2) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException;

    @Nullable
    Class<?> getType(String var1) throws NoSuchBeanDefinitionException;

    String[] getAliases(String var1);
}

getBean方法:从容器中获取Bean对象

is方法:单例,原型,bean类型的判断

get方法:获取Bean类型和别名


ApplicationContext 的主要实现类

    • ClassPathXmlApplicationContext:从 类路径下加载配置文件

    • FileSystemXmlApplicationContext: 从文件系统中加载配置文件

    • ConfigurableApplicationContext: 扩展于 ApplicationContext,新增加两个主要方法:refresh() 和 close(), 让 ApplicationContext 具有启动、刷新和关闭上下文的能力

    • ApplicationContext :在初始化上下文时就实例化所有单例的 Bean。

    • WebApplicationContext: 是专门为 WEB 应用而准备的,它允许从相对于 WEB 根目录的路径中完成初始化工作


Bean注册到Ioc容器过程

1、Bean配置信息(xml配置文件、配置类、注解)定义了Bean的实现及依赖关系,即Bean的配置信息

2、Spring容器根据各种形式的Bean配置信息在容器内部建立Bean定义注册表

3、容器根据注册表加载、实例化Bean,并建立Bean和Bean的依赖关系,最后将这些准备就绪的Bean放到Bean缓存池中,以供外层的应用程序进行调用

timg?image&quality=80&size=b9999_10000&sec=1555844218218&di=ae63c548a2a2f8f3c3f3d6f8dd4c9f25&imgtype=0&src=http%3A%2F%2Faliyunzixunbucket.oss-cn-beijing.aliyuncs.com%2Fjpg%2Fb5219aea95d58ee517d6b4bbfea8cb7d.jpg%3Fx-oss-process%3Dimage%2Fresize%2Cp_100%2Fauto-orient%2C1%2Fquality%2Cq_90%2Fformat%2Cjpg%2Fwatermark%2Cimage_eXVuY2VzaGk%3D%2Ct_100



Bean注册方式

一、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">

    <bean id="hollow" class="com.example.bean_configuration.Hollow"></bean>

</beans>

配置文件位置、名称不固定,建议命名为applicationContext.xml

    id:创建的对象名称

    class:需要进行注册的Bean全路径

使用静态工厂创建和使用实例工厂创建与使用类的无参构造函数相似,不再介绍

测试方法

public void classBeanConfiguration() {
    ApplicationContext applicationContext=new ClassPathXmlApplicationContext("config/applicationContext.xml");
    System.out.println("从容器获取Bean"+applicationContext.getBean("hollow"));
}

二、java配置类

配置类

@Configuration
public class SpringConfiguration {
    @Bean
    public HollowController hollowController(){
        return new HollowController();
    }
}

测试类

@Test
public void xmlBeanConfiguration1() {
    ApplicationContext applicationContext=new AnnotationConfigApplicationContext(SpringConfiguration.class);
    System.out.println("从容器获取Bean: "+applicationContext.getBean("hollowController"));
}


三、注解

添加注解

@Controller
public class AnnotationController {

    public AnnotationController() {
        System.out.println("annotationController创建了");
    }
}

开启扫描

@ComponentScan(value="com.example.bean_configuration.configuration.controller")
@Configuration
public class SpringConfiguration {

}

或者

<context:component-scan base-package="com.example.bean_configuration.configuration.controller" ></context:component-scan>

测试方法

@Test
public void xmlBeanConfiguration1() {
    ApplicationContext applicationContext=new AnnotationConfigApplicationContext(SpringConfiguration.class);
    System.out.println("从容器获取Bean: "+applicationContext.getBean("annotationController"));
}

注意:@Controller注解仅仅其标记作用,开启注解扫描@ComponentScan后才会注册Bean