欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring 中 IoC 容器简介

程序员文章站 2022-04-11 15:58:51
IoC 是一种通过描述来生成或者获取对象的技术,可以说 Spring 是一种基于 IoC 容器编程的框架 ......

ioc 是一种通过描述来生成或者获取对象的技术,可以说 spring 是一种基于 ioc 容器编程的框架

在一个系统中可以生成各种对象,并且这些对象都需要进行管理。为了描述这些对象关系,我们需要一个容器。在 spring 中把每一个需要管理的对象称为 spring bean ,而管理这些 bean 的容器就被称为 spring ioc 容器。

ioc 容器需要具备两个基本的功能:

  1. 通过描述管理 bean ,包括发布和获取 bean
  2. 通过描述完成 bean 之间的依赖关系

介绍

spring ioc 容器是一个管理 bean 的容器,在 spring 的定义中,它要求所有的 ioc 容器都需要实现接口 beanfactory,它是一个*容器接口。

如下是部分源码:

import org.springframework.beans.beansexception;
import org.springframework.core.resolvabletype;
import org.springframework.lang.nullable;

public interface beanfactory {
    //前缀
    string factory_bean_prefix = "&";
    // 多个 getbean 方法
    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);
    
    //是否包含 bean
    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;

    //获取bean 类型
    @nullable
    class<?> gettype(string var1) throws nosuchbeandefinitionexception;

    //获取bean别名
    string[] getaliases(string var1);
}

从源码中可以看到多个 getbean 方法,这也是 ioc 容器最重要的方法之一,它的意义就是从 ioc 容器中获取 bean 。而从多个 getbean 方法中可以看出在 spring ioc 容器中,允许我们从多种途径获取 bean,这对后面理解依赖注入(di)十分重要。

issingleton 方法则判断 bean 是否在 spring ioc 中为单例。这里需要记住的是 在 spring ioc 容器中,默认情况下,bean 都是单例存在的,也就是说使用 getbean 方法返回的都是同一个对象。

与 issingleton 方法相反的是 isprototype 方法。如果它返回的是 true,那么当我们使用 getbean 方法获取 bean 的时候, spring ioc 容器就会创建一个新的 bean 返回给调用者。

但是 beanfactory 方法功能还不够强大,因此 spring 在beanfactory 基础上,还设计了一个更高级的接口 applicationcontext 。 在现实中我们使用的大部分 spring ioc 容器都是 applicationcontext 接口的实现类。

Spring 中 IoC 容器简介

在 spring boot 中,我们主要是通过注解来装配 bean 到 spring ioc 容器中,我们主要介绍一个基于注解的 ioc 容器—— annotationconfigapplicationcontext

示例

下面来看一个简单例子。首先定义一个java简单对象 user:

public class user {
    private long id;
    private string username;
    private string note;

    /**setter and getter**/
}

然后再定义一个java配置文件 appconfig.java

import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;

@configuration
public class appconfig {
    @bean(name = "user")
    public user inituser(){
        user user = new user();
        user.setid(1l);
        user.setusername("name");
        user.setnote("note");
        return user;
    }
}

这里需要注意注解 @configuration 和注解 @bean

前者代表这是一个 java 配置文件,spring 容器会根据它来生成 ioc 容器去装配bean。

后者代表将 inituser 方法返回的 pojo 装配到 ioc 容器中,而其 属性 name 定义这个bean 的名称,如果没有配置它,那么则将方法名 inituser 作为bean的名称并保存到 spring ioc 容器中。

做好这些 ,就可以使用 annotationconfigapplicationcontext 来构建自己的 ioc 容器了:

import org.apache.logging.log4j.logmanager;
import org.apache.logging.log4j.logger;
import org.springframework.context.applicationcontext;
import org.springframework.context.annotation.annotationconfigapplicationcontext;

public class ioctest {
    private static logger logger = logmanager.getlogger(logmanager.root_logger_name);
    public static void main(string[] args){
        applicationcontext ctx =
                new annotationconfigapplicationcontext(appconfig.class);
        user user = ctx.getbean(user.class);
        logger.info("user' id is " + user.getnote());
    }
}

代码中将 java 配置文件 appconfig 传递给 annotationconfigapplicationcontext 的构造方法,这样它就能读取配置了。 然后将配置中的 bean 装配到 ioc 容器中,于是就可以使用 getbean 方法获取对应的 pojo ,你可能会看到如下的日志打印:

……
16:15:22.404 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory - creating shared instance of singleton bean 'appconfig'
16:15:22.410 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory - creating shared instance of singleton bean 'user'
16:15:22.453 [main] info  - user' id is note

显然,配置在配置文件中的名称为 user 的 bean 已经被装配到了 ioc 容器中,并且可以通过 getbean 方法获取对应的 bean ,并将 bean 的属性信息输出出来。