Spring中基于XML的注入

2023/05/13

1. 概述

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

2. 依赖注入

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

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

public class IndexApp {

    private Service service;

    // standard constructors/getters/setters ...
}

Service是一个接口:

public interface Service {
    String serve();
}

该接口可能有多个实现:

public class IndexService implements Service {

    @Override
    public String serve() {
        return "Hello World";
    }
}

在这里,IndexApp是一个高级组件,它依赖于名为Service的低级组件。

从本质上讲,我们将IndexApp与Service的特定实现分离,Service实现可以根据各种因素而变化。

3. 实践

3.1 使用Setter注入

让我们看看如何使用基于XML的配置注入依赖:


<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-3.0.xsd">

    <bean id="indexService" class="cn.tuyucheng.taketoday.di.spring.IndexService"/>

    <bean id="indexApp" class="cn.tuyucheng.taketoday.di.spring.IndexApp">
        <property name="service" ref="indexService"/>
    </bean>
</beans>

可以看出,我们创建一个IndexService实例并为其分配一个id。 默认情况下,bean是单例的。此外,我们还创建一个IndexApp实例。在这个bean中,我们使用setter方法注入另一个bean。

3.2 使用构造注入

我们可以使用构造函数注入依赖:


<bean id="indexApp" class="cn.tuyucheng.taketoday.di.spring.IndexApp">
    <constructor-arg ref="indexService"/>
</bean>    

3.3 使用静态工厂方法

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

public class StaticServiceFactory {

    public static Service getService(int number) {
        return switch (number) {
            case 1 -> new MessageService("Foo");
            case 0 -> new IndexService();
            default -> throw new IllegalArgumentException("Unknown parameter " + number);
        };
    }
}

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


<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-3.0.xsd">

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

    <bean id="indexApp" class="cn.tuyucheng.taketoday.di.spring.IndexApp">
        <property name="service" ref="messageService"/>
    </bean>
</beans>

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

3.4 使用实例工厂方法

实例工厂方法根据提供的数字返回一个Service实例:

public class InstanceServiceFactory {

    public Service getService(int number) {
        return switch (number) {
            case 1 -> new MessageService("Foo");
            case 0 -> new IndexService();
            default -> throw new IllegalArgumentException("Unknown parameter " + number);
        };
    }
}

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


<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-3.0.xsd">

    <bean id="indexServiceFactory" class="cn.tuyucheng.taketoday.di.spring.InstanceServiceFactory"/>

    <bean id="messageServiceFromInstanceFactory" class="cn.tuyucheng.taketoday.di.spring.InstanceServiceFactory"
          factory-method="getService" factory-bean="indexServiceFactory">
        <constructor-arg value="1"/>
    </bean>

    <bean id="indexApp" class="cn.tuyucheng.taketoday.di.spring.IndexApp">
        <property name="service" ref="messageServiceFromInstanceFactory"/>
    </bean>
</beans>

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

4. 测试

class BeanInjectionIntegrationTest {

    private ApplicationContext applicationContext;

    @BeforeEach
    void setUp() {
        applicationContext = new ClassPathXmlApplicationContext("cn.tuyucheng.taketoday.di.spring.xml");
    }

    @Test
    void getBean_returnsInstance() {
        final IndexApp indexApp = applicationContext.getBean("indexApp", IndexApp.class);
        assertNotNull(indexApp);
    }
}

5. 总结

在这个教程中,我们举例说明了如何使用Spring通过基于XML的配置来注入依赖bean。 与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章