Spring之依赖注入的方式

2024-01-08 03:11:52

1.setter注入

(1)setter注入简单数据类型
首先在bean中定义简单类型属性并提供可访问的set方法,然后再配置文件中使用<property>标签的name和value属性注入简单数据类型(注:name属性的值和bean中定义的简单数据类型属性名相对应)

package domain;

public class People {
    private String name;
    private int age;

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="people" class="domain.People">
        <property name="name" value="张三"/>
        <!--value的值会自动转换为对应的基本数据类型-->
        <property name="age" value="18"/>
    </bean>
</beans>

(2)setter注入引用数据类型
首先在bean中定义引用类型属性并提供可访问的set方法,然后在配置中使用<property>标签的name和ref属性注入引用类型对象(注:name属性的值和bean中定义的引用数据类型属性名相对应,ref与IoC容器中Bean的id值相对应)

package domain;

public class People {
  private Animal animal;

    public void setAnimal(Animal animal) {
        this.animal = animal;
    }
}
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="animal" class="domain.Animal">
        <property name="name" value="小狗"/>
        <property name="age" value="1"/>
    </bean>
    <bean id="people" class="domain.People">
       <property name="animal" ref="animal"/>
    </bean>
</beans>

(3)setter注入集合

package domain;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class People {
    private int[] array;
    private List<String> list;
    private Set<String> set;
    private Map<String, String> map;
    private Properties properties;

    public void setArray(int[] array) {
        this.array = array;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public void setSet(Set<String> set) {
        this.set = set;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }
}

<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="animal" class="domain.Animal">
        <property name="name" value="小花"/>
        <property name="age" value="1"/>
    </bean>
    <bean id="people" class="domain.People">
        <property name="array">
            <array>
                <value>100</value>
                <value>200</value>
                <value>300</value>
            </array>
        </property>
        <property name="list">
            <list>
                <value>aaa</value>
                <value>ccc</value>
                <value>sss</value>
            </list>
        </property>
        <property name="set">
            <set>
                <value>aaa</value>
                <value>ccc</value>
                <value>sss</value>
            </set>
        </property>
        <property name="map">
            <map>
                <entry key="name" value="小花"/>
                <entry key="age" value="1"/>
            </map>
        </property>
        <property name="properties">
            <props>
                <prop key="country">中国</prop>
                <prop key="city">北京</prop>
            </props>
        </property>
    </bean>
</beans>

2.构造器注入

(1)构造器注入简单数据类型
首先在bean中定义简单类型属性并提供带参数的构造方法,然后在配置文件中使用 <constructor-arg>标签的name(或type或index)和value属性注入简单数据类型(注:name属性的值和bean中定义的构造方法的形参名相对应)

package domain;

public class People {
    private String name;
    private int age;

    public People(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="people" class="domain.People">
        <constructor-arg name="name" value="张三"/>
        <constructor-arg name="age" value="22"/>
    </bean>
</beans>

(2)构造器注入引用数据类型
首先在bean中定义引用数据类型属性并提供带参数的构造方法,然后在配置文件中使用 <constructor-arg>标签的name(或type或index)和value属性注入引用数据类型(注:name属性的值和bean中定义的构造方法的形参名相对应,ref与IoC容器中Bean的id值相对应)

package domain;

public class People {
    private Animal animal;

    public People(Animal animal) {
        this.animal = animal;
    }
}
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="animal" class="domain.Animal">
        <property name="name" value="小花"/>
        <property name="age" value="1"/>
    </bean>
    <bean id="people" class="domain.People">
        <constructor-arg name="animal" ref="animal"/>
    </bean>
</beans>

(3)name、type、index三个属性的对比

构造器注入xml文件中使用name缺点:代码和配置文件耦合度很高
构造器注入xml中文件使用type缺点:如果构造方法形参中有两个相同的数据类型无法解决(type属性的值和bean中定义的构造方法的形参数据类型相对应)
构造器注入xml文件中使用index属性:从0开始(index属性的值和bean中定义的构造方法的形参位置索引相对应)

3.setter注入和构造器注入两种方式的选择

(1)强制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现
(2)可选依赖使用setter注入进行,灵活性强
(3)Spring框架倡导使用构造器,第三方框架内部大多采用构造器注入的形式进行数据初始化,相对严谨
(4)如果有必要可以两者同时使用,使用构造器注入完成强制依赖的注入,使用setter注入完成可选依赖的注入
(5)自己开发的模块推荐使用setter注入

4.自动装配

(1)自动装配概念
IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配 (利用autowire属性),本质上是setter注入
(2)按类型自动装配
按照bean中定义的属性的数据类型和<bean>标签的class属性的值匹配,自动查找要注入的bean(注:若是有多个<bean>标签的class属性的值相同则产生NoUniqueBeanDefinitionException异常)

package domain;

public class People {
    private Animal animal;

    public void setAnimal(Animal animal) {
        this.animal = animal;
    }
}
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="animal" class="domain.Animal">
        <property name="name" value="小花"/>
        <property name="age" value="1"/>
    </bean>
    <bean id="people" class="domain.People" autowire="byType"/>
</beans>

(3)按名称自动装配
按照bean中定义的属性名(set方法命名标准的情况下)和<bean>标签的id属性的值匹配,自动查找要注入的bean

<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="animal" class="domain.Animal">
        <property name="name" value="小花"/>
        <property name="age" value="1"/>
    </bean>
    <bean id="people" class="domain.People" autowire="byName"/>
</beans>

(4)使用自动装配的注意事项

  • 自动装配用于引用类型的依赖注入,不能对简单类型进行操作
  • 使用按类型装配时必须保证容器中相同类型的bean唯一
  • 使用按名称装配时必须保证容器中有指定名称的bean,因为变量名与配置耦合,因此不推荐使用
  • 自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效

文章来源:https://blog.csdn.net/Lyhdreamer/article/details/135379383
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。