Contents

Spring 使用基于 XML 的配置注入依赖项

1.简介

在这个基础教程中,我们将学习如何使用 Spring Framework 进行简单的基于 XML 的 bean 配置。

2. 概述

让我们首先在pom.xml中添加 Spring 的库依赖项:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.4.RELEASE</version>
</dependency>

可以在此处 找到最新版本的 Spring 依赖项。

3. 依赖注入——概述

依赖注入 是一种技术,其中对象的依赖关系由外部容器提供。

假设我们有一个依赖于实际处理业务逻辑的服务的应用程序类:

public class IndexApp {
    private IService service;
    // standard constructors/getters/setters
}

现在假设IService是一个接口:

public interface IService {
    public String serve();
}

这个接口可以有多种实现。 让我们快速看一下一种可能的实现:

public class IndexService implements IService {
    @Override
    public String serve() {
        return "Hello World";
    }
}

在这里,IndexApp是一个高级组件,它依赖于名为IService的低级组件。 从本质上讲,我们将IndexAppIService的特定实现分离,该实现可能会因各种因素而异。

4. 依赖注入——在行动

让我们看看如何注入依赖项。

4.1. 使用属性

让我们看看如何使用基于 XML 的配置将依赖项连接在一起:

<bean 
  id="indexService" 
  class="com.blogdemo.di.spring.IndexService" />

<bean 
  id="indexApp" 
  class="com.blogdemo.di.spring.IndexApp" >
    <property name="service" ref="indexService" />
</bean>

可以看出,我们正在创建一个IndexService实例并为其分配一个 id。默认情况下,bean 是单例的。此外,我们正在创建一个IndexApp实例。

在这个 bean 中,我们使用 setter 方法注入另一个 bean。

4.2. 使用构造函数

我们可以使用构造函数注入依赖项,而不是通过 setter 方法注入 bean:

<bean 
  id="indexApp" 
  class="com.blogdemo.di.spring.IndexApp">
    <constructor-arg ref="indexService" />
</bean>

4.3. 使用静态工厂

我们还可以注入工厂返回的 bean。让我们创建一个简单的工厂,它根据提供的数字返回IService的实例:

public class StaticServiceFactory {
    public static IService getNumber(int number) {
        // ...
    }
}

现在让我们看看如何使用上面的实现通过基于 XML 的配置将 bean 注入IndexApp

<bean id="messageService"
  class="com.blogdemo.di.spring.StaticServiceFactory"
  factory-method="getService">
    <constructor-arg value="1" />
</bean>

<bean id="indexApp" class="com.blogdemo.di.spring.IndexApp">
    <property name="service" ref="messageService" />
</bean>

在上面的示例中,我们使用工厂方法调用静态getService方法来创建一个id为messageService的 bean ,我们将其注入IndexApp

4.4. 使用工厂方法

让我们考虑一个实例工厂,它根据提供的数字返回一个IService实例。这一次,方法不是静态的:

public class InstanceServiceFactory {
    public IService getNumber(int number) {
        // ...
    }
}

现在让我们看看如何使用上述实现通过 XML 配置将 bean 注入IndexApp

<bean id="indexServiceFactory" 
  class="com.blogdemo.di.spring.InstanceServiceFactory" />
<bean id="messageService"
  class="com.blogdemo.di.spring.InstanceServiceFactory"
  factory-method="getService" factory-bean="indexServiceFactory">
    <constructor-arg value="1" />
</bean>
<bean id="indexApp" class="com.blogdemo.di.spring.IndexApp">
    <property name="service" ref="messageService" />
</bean>

在上面的示例中,我们使用工厂方法InstanceServiceFactory实例上调用getService方法,以创建一个 id 为messageService的 bean ,我们将其注入IndexApp

5. 测试

这就是我们可以访问配置的 bean 的方式:

@Test
public void whenGetBeans_returnsBean() {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("...");
    IndexApp indexApp = applicationContext.getBean("indexApp", IndexApp.class);
    assertNotNull(indexApp);
}