Bean的注入

在Spring Framework中,Bean的注入方式主要有以下两种形式:

  • 构造器注入
  • SET注入

1. 构造器注入

依赖信息见Spring Beans初始化相关章节的依赖信息

首先编写一个Service,如下:

public class ConstructorClientService {
    private String name;
    private ClientService clientService;

    public ConstructorClientService(String name, ClientService clientService) {
        this.name = name;
        this.clientService = clientService;
    }

    public String getName() {
        return name;
    }

    public ClientService getClientService() {
        return clientService;
    }
}

public class ClientService {}

以XML为例,初始化该对象及其依赖关系,META-INF/applicationContext.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
       https://www.springframework.org/schema/beans/spring-beans.xsd">

  <bean id="service" class="com.vielat.springframework.bean.service.ConstructorClientService">
      <constructor-arg name="name" value="Michael" />
      <constructor-arg name="clientService">
        <null/>
      </constructor-arg>
  </bean>
</beans>

上述配置中,ConstructorClientService构造器中有两个参数,一个是普通字符串,一个是对象类型,通过设置constructor-arg参数,然后可以进行注入,上述对象类型直接设置为
测试类如下:

    @Test
    public void testConstructorInitializing() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("META-INF/applicationContext.xml");
        ConstructorClientService clientService = ac.getBean("service", ConstructorClientService.class);
        System.out.println(clientService);
        System.out.println(clientService.getName() +" -->" + clientService.getClientService());
    }

若想为对象类型赋值,需要使用如下形式:

    <bean id="service" class="com.vielat.springframework.bean.service.ConstructorClientService">
        <constructor-arg name="name" value="Michael" />
        <constructor-arg name="clientService" ref="clientService">
            <!--<null/>-->
        </constructor-arg>
    </bean>

    <bean id="clientService" class="com.vielat.springframework.bean.service.ClientService" />

也可以使用下标的方式指定需要注入的值,如下:

<bean id="service" class="com.vielat.springframework.bean.service.ConstructorClientService">
        <!--<constructor-arg name="name" value="Michael" />
        <constructor-arg name="clientService" ref="clientService">
            &lt;!&ndash;<null/>&ndash;&gt;
        </constructor-arg>-->

        <constructor-arg index="0" value="Michael" />
        <constructor-arg index="1" ref="clientService" />
    </bean>

使用类型指定需要注入的值,如下:

<bean id="service" class="com.vielat.springframework.bean.service.ConstructorClientService">
        <!--<constructor-arg name="name" value="Michael" />
        <constructor-arg name="clientService" ref="clientService">
            &lt;!&ndash;<null/>&ndash;&gt;
        </constructor-arg>-->

       <!-- <constructor-arg index="0" value="Michael" />
        <constructor-arg index="1" ref="clientService" />-->

        <constructor-arg type="String" value="Michael" />
        <constructor-arg type="com.vielat.springframework.bean.service.ClientService" ref="clientService" />
    </bean>

若存在多个相同类型时无法注入

c命名空间的简化写法此处略,详细信息见Spring Beans初始化相关章节。

2. SET注入

在Spring Framework中,除了构造器注入外,还有一种使用SET方式的注入。
为简化代码,在此引入lombok相关插件,插件安装成功后,新增依赖信息如下:

    <properties>
        ...
        <lombok.version>1.18.22</lombok.version>
    </properties>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>${lombok.version}</version>
    </dependency>

新增Service类,如下:

@Data
public class AdvancedClientService {
    private String name;
    private Integer age;
    private Properties props;
    private List<String> hobbies;
    private Map<String,Object> map;
    private Set<String> emails;
    private ClientService clientService;
}

在该对象中,定义了多种不同类型的属性值,包括普通字符、int、Properties、集合、Map及对象等,若要为相应属性值赋值,XML需要使用如下配置的方式:

<bean id="advancedClientService" class="com.vielat.springframework.bean.service.AdvancedClientService">
        <property name="name" value="Michael"/>
        <property name="age" value="18"/>
        <property name="props">
            <props>
                <prop key="username">root</prop>
                <prop key="password">root</prop>
            </props>
        </property>
        <property name="hobbies">
            <list>
                <value>Reading</value>
                <value>Writing</value>
            </list>
        </property>
        <property name="map">
            <map>
                <entry key="name" value="Michael"/>
                <entry key="age" value="18" />
            </map>
        </property>
        <property name="emails">
            <set>
                <value>aaa@163.com</value>
                <value>bbb@qq.com</value>
            </set>
        </property>
        <property name="clientService">
            <ref bean="clientService" />
        </property>
    </bean>

    <bean id="clientService" class="com.vielat.springframework.bean.service.ClientService" />

测试类如下:

    @Test
    public void testInjection() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("META-INF/applicationContext.xml");
        System.out.println(ac.getBean("advancedClientService"));
    }

执行结果如下:

AdvancedClientService(name=Michael, age=18, props={password=root, username=root}, hobbies=[Reading, Writing], map={name=Michael, age=18}, emails=[aaa@163.com, bbb@qq.com], clientService=com.vielat.springframework.bean.service.ClientService@1cab0bfb)

Process finished with exit code 0

从上述执行结果可以看出,对于普通属性,如字符或Integer等,Spring Framework会根据具体对象类型非常完美的进行类型转换,这块属于类型转换的范畴,后续章节会进行相应的介绍,此处略。
针对Properties属性的设值,除上述标签外,也可以使用如下方式:

    <property name="props">
    <!--<props>
            <prop key="username">root</prop>
            <prop key="password">root</prop>
        </props>-->
        <value>
            username=root
            password=root
        </value>
    </property>

上述配置在value属性中的信息,会使用JavaBeansPropertyEditor机制,将字符串转换为相应的Properties实例。
对象应用的赋值可以简化为如下方式:

    <!--<property name="clientService">
            <ref bean="clientService" />
        </property>-->
        <property name="clientService" ref="clientService" />

同样,上述property属性也可以使用p命名空间进行简写,如下:

<bean id="advancedClientService" class="com.vielat.springframework.bean.service.AdvancedClientService" p:name="Michael">
        <!--<property name="name" value="Michael"/>-->
        <property name="age" value="18"/>
  ...
</bean>
posted @ 2021-12-06 23:33  生活咖啡  阅读(247)  评论(0编辑  收藏  举报