依赖注入

Last updated: ... / Reads: 36 Edit

set方法注入

依赖注入的一种常见方式是使用setter方法注入,通过在目标类中提供setter方法,Spring容器在实例化Bean的同时通过调用这些setter方法来注入所需的依赖。以下是一个简单的示例:

假设有一个Person类和一个Address类,我们希望在Person类中注入Address

public class Person {
    private Address address;

    // Setter方法用于注入Address
    public void setAddress(Address address) {
        this.address = address;
    }

    public void displayAddress() {
        System.out.println("Address: " + address.getAddressLine());
    }
}

public class Address {
    private String addressLine;

    public void setAddressLine(String addressLine) {
        this.addressLine = addressLine;
    }

    public String getAddressLine() {
        return addressLine;
    }
}

在Spring的XML配置文件中,我们可以进行如下的配置:

<!-- applicationContext.xml -->

<bean id="person" class="com.example.Person">
    <!-- 使用property标签配置setter方法注入 -->
    <property name="address">
        <bean class="com.example.Address">
            <property name="addressLine" value="123 Main St" />
        </bean>
    </property>
</bean>

上述配置中,Person类的address属性通过setAddress方法注入了一个Address类型的Bean。

然后,通过ApplicationContext获取Person实例:

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = (Person) context.getBean("person");
person.displayAddress();

这样,Person实例就被创建并且Address实例通过setter方法注入到Person中了。这是一种基于XML配置的setter方法注入方式,你也可以使用基于注解的方式进行setter注入。

构造方法注入

构造方法注入是另一种常见的依赖注入方式,它通过在目标类的构造方法中接收依赖参数来实现。以下是一个简单的示例:

假设有一个Person类和一个Address类,我们希望在Person类的构造方法中注入Address

public class Person {
    private Address address;

    // 构造方法接收Address参数,用于注入
    public Person(Address address) {
        this.address = address;
    }

    public void displayAddress() {
        System.out.println("Address: " + address.getAddressLine());
    }
}

public class Address {
    private String addressLine;

    public void setAddressLine(String addressLine) {
        this.addressLine = addressLine;
    }

    public String getAddressLine() {
        return addressLine;
    }
}

在Spring的XML配置文件中,我们可以进行如下的配置:

<!-- applicationContext.xml -->

<bean id="address" class="com.example.Address">
    <property name="addressLine" value="123 Main St" />
</bean>

<bean id="person" class="com.example.Person">
    <!-- 使用constructor-arg标签配置构造方法注入 -->
    <constructor-arg ref="address" />
</bean>

上述配置中,Person类的构造方法接收一个Address类型的参数,通过constructor-arg标签将address Bean注入到Person的构造方法中。

然后,通过ApplicationContext获取Person实例:

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = (Person) context.getBean("person");
person.displayAddress();

这样,Person实例就被创建并且Address实例通过构造方法注入到Person中了。构造方法注入是一种直观且常见的依赖注入方式,特别适用于那些在实例化时就需要传入依赖的情况。

引用另一个Bean

在Spring的XML配置文件中,ref属性用于引用另一个Bean的ID,以便将其注入到当前Bean的属性或构造函数参数中。ref属性通常用于解决依赖关系,将一个Bean与另一个Bean关联起来。

以下是一个简单的例子,演示了如何使用ref属性:

<!-- applicationContext.xml -->

<bean id="address" class="com.example.Address">
    <property name="addressLine" value="123 Main St" />
</bean>

<bean id="person" class="com.example.Person">
    <!-- 使用ref属性将address注入到person的address属性中 -->
    <property name="address" ref="address" />
</bean>

在这个例子中,<property>标签的ref属性用于引用ID为address的Bean,即com.example.Address。这样,Spring容器会自动将address Bean 注入到person Bean 的address属性中。

ref属性可以用于不同的元素,例如<property><constructor-arg>等,具体取决于你是在属性上进行依赖注入还是在构造函数中进行注入。

另外,需要确保被引用的Bean已经在配置文件中定义,并且其ID与ref属性中指定的ID一致。这样,Spring容器才能正确地识别并注入相应的Bean。

内部bean不可以通过ioc容器获取

在Spring中,内部Bean的可见性通常被限制在包含它的外部Bean内部。这意味着在ApplicationContext中直接获取内部Bean可能会受到限制,因为内部Bean没有全局的可见性。

如果确实需要在ApplicationContext中获取内部Bean,可以考虑使用getBeansOfType方法,通过类型来获取所有匹配的Bean。以下是一个示例:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Map;
import com.example.InnerBean;

public class MainApp {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        // 获取所有类型为InnerBean的Bean
        Map<String, InnerBean> innerBeans = context.getBeansOfType(InnerBean.class);

        // 遍历所有匹配的Bean
        for (Map.Entry<String, InnerBean> entry : innerBeans.entrySet()) {
            String beanName = entry.getKey();
            InnerBean innerBean = entry.getValue();
            
            // 使用内部Bean
            String innerPropertyValue = innerBean.getInnerProperty();
            System.out.println("Inner Bean Property Value (" + beanName + "): " + innerPropertyValue);
        }
    }
}

请注意,这样的方式可能不太常见,因为通常内部Bean是作为外部Bean的一部分,而不是在ApplicationContext中单独存在。在实际应用中,通常通过外部Bean的方法或属性来访问内部Bean。

级联属性赋值

在Spring配置文件中,使用property元素时,name属性用于指定要设置的属性的名称。通过name属性,你可以将值赋给指定的Bean属性。下面是一个简单的例子:

<!-- applicationContext.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.xsd">

    <!-- 定义一个简单的 Bean -->
    <bean id="myBean" class="com.example.MyBean">
        <!-- 使用 property 元素设置属性值 -->
        <property name="propertyName" value="Property Value"/>
    </bean>
</beans>

在这个示例中,MyBean 类中的 propertyName 属性通过 property 元素的 name 属性赋值。

如果你有一个嵌套的Bean结构,你可以使用点操作符在name属性中表示深层次的属性。例如:

<!-- applicationContext.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.xsd">

    <!-- 定义 OuterBean,包含 InnerBean -->
    <bean id="outerBean" class="com.example.OuterBean">
        <!-- 使用 property 元素设置嵌套属性值 -->
        <property name="innerBean.innerProperty" value="Inner Property Value"/>
    </bean>
</beans>

在这个示例中,OuterBeaninnerBean 属性的 innerProperty 被通过 property 元素的 name 属性设置。

通过使用property元素和name属性,你可以在Spring配置文件中灵活地设置Bean的属性值。这对于将配置与代码分离以及实现松耦合非常有用。

为Bean的数组属性赋值

在Spring中,你可以使用property元素为Bean的数组属性赋值。以下是一个简单的示例,演示如何配置一个Bean,其中包含一个String数组属性:

<!-- applicationContext.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.xsd">

    <!-- 定义包含数组属性的 Bean -->
    <bean id="myArrayBean" class="com.example.MyArrayBean">
        <!-- 使用 property 元素设置数组属性值 -->
        <property name="stringArray">
            <array>
                <value>Value 1</value>
                <value>Value 2</value>
                <value>Value 3</value>
            </array>
        </property>
    </bean>
</beans>

在这个示例中,MyArrayBean 类有一个名为 stringArray 的String数组属性。通过property元素的name属性,我们为这个数组属性设置了值。

在JavaConfig中,你可以使用@Value注解或者在@Bean方法中直接赋值数组:

@Configuration
public class AppConfig {

    @Bean
    public MyArrayBean myArrayBean() {
        MyArrayBean myArrayBean = new MyArrayBean();
        myArrayBean.setStringArray(new String[]{"Value 1", "Value 2", "Value 3"});
        return myArrayBean;
    }
}

这个JavaConfig示例中,MyArrayBean 类的 stringArray 属性通过在@Bean方法中直接设置数组值来进行赋值。

无论是XML配置还是JavaConfig,都允许你灵活地为Bean的数组属性赋值,以满足不同的需求。

util引用集合类型的bean

在Spring中,除了使用<bean>元素定义和引用Bean外,还可以使用<util:list><util:set><util:map>来定义集合类型的Bean,并且可以在其中引用其他Bean。以下是如何使用<util:list><util:set><util:map>来引用其他Bean的示例:

1. 使用 <util:list> 引用其他Bean:

<!-- applicationContext.xml -->

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:util="http://www.springframework.org/schema/util"
    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.xsd
    http://www.springframework.org/schema/util
    http://www.springframework.org/schema/util/spring-util.xsd">

    <!-- 定义两个值 Bean -->
    <bean id="valueBean1" class="com.example.ValueBean">
        <property name="value" value="Value 1"/>
    </bean>

    <bean id="valueBean2" class="com.example.ValueBean">
        <property name="value" value="Value 2"/>
    </bean>

    <!-- 使用 util:list 定义 List 类型的 Bean,并引用其他 Bean -->
    <util:list id="myList">
        <ref bean="valueBean1"/>
        <ref bean="valueBean2"/>
    </util:list>
</beans>

2. 使用 <util:set> 引用其他Bean:

<!-- applicationContext.xml -->

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:util="http://www.springframework.org/schema/util"
    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.xsd
    http://www.springframework.org/schema/util
    http://www.springframework.org/schema/util/spring-util.xsd">

    <!-- 定义两个值 Bean -->
    <bean id="valueBeanA" class="com.example.ValueBean">
        <property name="value" value="Value A"/>
    </bean>

    <bean id="valueBeanB" class="com.example.ValueBean">
        <property name="value" value="Value B"/>
    </bean>

    <!-- 使用 util:set 定义 Set 类型的 Bean,并引用其他 Bean -->
    <util:set id="mySet">
        <ref bean="valueBeanA"/>
        <ref bean="valueBeanB"/>
    </util:set>
</beans>

3. 使用 <util:map> 引用其他Bean:

<!-- applicationContext.xml -->

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:util="http://www.springframework.org/schema/util"
    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.xsd
    http://www.springframework.org/schema/util
    http://www.springframework.org/schema/util/spring-util.xsd">

    <!-- 定义两个值 Bean -->
    <bean id="valueBeanKey1" class="com.example.ValueBean">
        <property name="value" value="Value for Key 1"/>
    </bean>

    <bean id="valueBeanKey2" class="com.example.ValueBean">
        <property name="value" value="Value for Key 2"/>
    </bean>

    <!-- 使用 util:map 定义 Map 类型的 Bean,并引用其他 Bean -->
    <util:map id="myMap">
        <entry key="Key1" value-ref="valueBeanKey1"/>
        <entry key="Key2" value-ref="valueBeanKey2"/>
    </util:map>
</beans>

通过这种方式,你可以利用<util:list><util:set><util:map>元素来定义集合类型的Bean,并在其中引用其他已定义的Bean,从而简化配置文件的管理和维护。


Comments

Make a comment