Spring 的核心功能就是提供一个 IoC 容器,用于管理应用程序中的 bean,在容器中配置元数据来管理 Bean 之间的依赖关系,Java 程序中的类都可以交由 Spring 容器管理。

一、Bean 管理

1. 元数据

配置 Spring 元数据的方式有三种:

  • 基于 XML 方式配置
  • 基于注解方式配置
  • 基于 Java 方式配置

Spring 最早的时候提供BeanFactory接口实现 Bean 容器,而后面新增的许多功能都是基于其子接口ApplicationContext来实现的,前面说的三种配置方式,可以使用下面三个实现类来实例化容器。

|interface BeanFactory (org.springframework.beans.factory)
|---interface ApplicationContext (org.springframework.context)
|---|---class FileSystemXmlApplicationContext (org.springframework.context.support)
|---|---class ClassPathXmlApplicationContext (org.springframework.context.support)
|---|---class AnnotationConfigApplicationContext (org.springframework.context.annotation)

例如使用 ClassPathXmlApplicationContext 来通过 classpath 目录下的配置文件实例化容器:

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");

2. Bean 实例化

在 Spring 容器中配置好的 Bean 都会被 Spring 自动实例化,以供在开发过程中注入直接可以使用,而不需要手动去 new 对象。

2.1 构造器实例化

Spring 容器默认使用类的无参构造器来实例化 Bean,也可以指定其他带参数的构造器来实例化。

<!--默认使用无参构造器-->
<bean id="beanProvider" class="cn.codeartist.spring.bean.xml.BeanProvider"/>

<!--使用其他构造器-->
<bean id="beanExample" class="cn.codeartist.spring.bean.xml.BeanExample">
    <constructor-arg index="0" value="码匠公众号"/>
    <constructor-arg index="1" value="2021"/>
    <constructor-arg index="2" ref="beanProvider"/>
</bean>

2.2 静态工厂方式实例化

Spring 容器支持使用静态工厂方法来实例化 Bean,在类中定义一个 static 方法来创建对象实例。

public class BeanExample {
    
    private static BeanExample beanExample = new BeanExample();

    public static BeanExample getInstance() {
        return beanExample;
    }
}

在 Bean 配置中使用 factory-method 属性来指定工厂方法。

<bean id="beanExample" class="...xml.BeanExample" factory-method="getInstance"/>

2.3 实例工厂方式实例化

和静态工厂方法一样,不同的是工厂方法是实例化后的 Bean 的方法而不是静态方法。

public class BeanExampleFactory {
    
    private static BeanExample beanExample = new BeanExample();

    public BeanExample getInstance() {
        return beanExample;
    }
}

在 Bean 配置中使用 factory-bean 属性指定工厂类的 Bean,使用 factory-method 属性来指定工厂方法。

<bean id="beanExample" class="...xml.BeanExample" factory-bean="beanExampleFactory" factory-method="getInstance"/>
<bean id="beanExampleFactory" class="cn.codeartist.spring.bean.xml.BeanExampleFactory"/>

3. Bean 作用域

通过 scope 属性配置 bean 的作用域,来指定 bean 的实例化作用范围。

<bean id="beanExample" class="...xml.BeanExample" scope="prototype"/>

常用的几种 Bean 作用域如下:

作用域 描述
singleton (默认)单例作用域,在 Spring 容器内部只创建一个实例
prototype 原型作用域,在容器中创建多个实例,每使用一次创建一个实例
request 请求作用域,在 Web 框架下单次请求创建一个实例
session 会话作用域,在 Web 框架下单次会话内创建一个实例
application 应用作用域,在 ServletContext 生命周期内创建一个实例

二、依赖注入

Spring 容器创建好了 Bean 实例后,会根据实例间的依赖关系来进行注入。

1. 依赖注入

1.1 构造器注入

通过类的构造器来注入依赖的值或 Bean。

<bean id="beanExample" class="...xml.BeanExample">
    <constructor-arg index="0" value="码匠公众号"/>
    <constructor-arg index="1" value="2021"/>
    <constructor-arg index="2" ref="beanProvider"/>
</bean>

1.2 Setter 方法注入

通过类的 Setter 方法注入依赖的值或 Bean。

<bean id="beanExample" class="...xml.BeanExample">
    <property name="name" value="码匠公众号"/>
    <property name="year" value="2021"/>
    <property name="beanProvider" ref="beanProvider"/>
</bean>

在两种注入方式中,配置值的方式:

  • value:注入值
  • ref:注入引用(注入 Bean 实例)

2. 依赖关系

一般情况下,Bean 之间的依赖关系并不明确,但在一些情况下,比如初始化一个静态类,使用 depends-on 属性指定在初始化该 bean 之前,强制初始化依赖的一个或多个 bean。

<bean id="beanExample" class="...xml.BeanExample" depends-on="beanProvider" />

3. 懒加载

一般情况下,Spring 会在容器启动的时候把所有 Bean 实例化完成,如果想在第一次使用的 Bean 的时候才初始化,可能配置 lazy-init 来实现。

<bean id="beanExample" class="...xml.BeanExample" lazy-init="true"/>

4. 自动注入

Spring 容器支持自动注入,而不需要手动通过 ref 来指定依赖的 bean 实例。

<bean id="beanExample" class="...xml.BeanExample" autowire="byName"/>

容器支持的注入方式:

注入方式 描述
no (默认)不使用自动注入
byName 通过 bean 名称注入
byType 通过 bean 类型注入
constructor 通过构造器参数类型注入

三、附录

1. 配置属性表

属性 默认值 描述
id 指定 bean 的名称
class 指定 bean 的类
scope singleton 指定作用域
depends-on 指定依赖关系
lazy-init false 配置懒加载
autowire no 配置自动注入
factory-bean 指定提供工厂方法的 bean
factory-method 指定创建 bean 的工厂方法

2. 示例代码

Gitee 仓库:https://gitee.com/code_artist/spring

代码目录:src/main/java/cn/codeartist/spring/bean/xml

原文地址:http://www.cnblogs.com/code-artist/p/spring-2.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性