DI依赖注入


DI(依赖注入)

概念

依赖注入(Dependency Injection,DI)。

依赖 : 指Bean对象的创建依赖于容器 . Bean对象的依赖资源 .

注入 : 指Bean对象所依赖的资源 , 由容器来设置和装配 .


构造器注入

创建对象时已经讲过,这里列举最常用的一种方式。

<!-- 第二种根据参数名字设置 -->
<bean id="userT" class="com.kuang.pojo.UserT">
   <!-- name指参数名 -->
   <constructor-arg name="name" value="kuangshen2"/>
</bean>

set注入(重点)

环境搭建

1.复杂类型 Address

public class Address {
    private String address;

    public Address(String address) {
        this.address = address;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Address{" +
                "address='" + address + '\'' +
                '}';
    }
}

2.真实测试对象 Student

public class Student {

    private String name;
    private Address address;
    private String[] books;
    private List<String> hobbies;
    private Map<String,String> card;
    private Set<String> games;
    private String wife;
    private Properties info;

    //get set toString方法
}

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

    <bean id="student" class="com.allen.pojo.Student">
        <!--  第一种,普通值注入,value-->
        <property name="name" value="allen"/>

    </bean>
</beans>

4.测试

@Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

        Student student = (Student) context.getBean("student");
        System.out.println(student.getName());
    }

全部注入

<?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="address" class="com.allen.pojo.Address">
        <!--  构造器注入-->
        <constructor-arg name="address" value="CHINA"/>
        <!--  对同一属性赋值时,property 优先级高于 constructor-arg-->
        <property name="address" value="china"/>
    </bean>

    <bean id="student" class="com.allen.pojo.Student">
        <!--  普通值注入,value-->
        <property name="name" value="allen"/>

        <!--  bean注入,ref-->
        <property name="address" ref="address"/>

        <!--  Array  -->
        <property name="books">
            <array>
                <value>西游记</value>
                <value>红楼梦</value>
                <value>水浒传</value>
            </array>
        </property>

        <!--  List-->
        <property name="hobbies">
            <list>
                <value>听歌</value>
                <value>看电影</value>
                <value>游戏</value>
            </list>
        </property>

        <!--  Map-->
        <property name="card">
            <map>
                <entry key="身份证" value="111111222222223333"/>
                <entry key="校园卡" value="0000000000"/>
            </map>
        </property>

        <!--  Set-->
        <property name="games">
            <set>
                <value>LOL</value>
                <value>COC</value>
            </set>
        </property>

        <!--  null-->
        <property name="wife">
            <null/>
        </property>

        <!--  properties-->
        <property name="info">
            <props>
                <prop key="学号">20211126</prop>
                <prop key="性别"></prop>
                <prop key="username">111111</prop>
                <prop key="pwd">222222</prop>
            </props>
        </property>

    </bean>
</beans>

输出结果

Student{name='allen', address=Address{address='china'}, books=[西游记, 红楼梦, 水浒传], hobbies=[听歌, 看电影, 游戏], card={身份证=111111222222223333, 校园卡=0000000000}, games=[LOL, COC], wife='null', info={学号=20211126, pwd=222222, username=111111, 性别=男}}

其中,address值为小写的 china, 说明对同一属性赋值时,property 优先级高于 constructor-arg.


扩展方式

环境搭建

新建实体类 User

public class User {

    private String name;
    private int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

新建 userBeans.xml.

p命名空间依赖注入(properties)

编写 userBeans.xml,注意导入

xmlns:p="http://www.springframework.org/schema/p"

然后使用 p:age 和 p:name 进行赋值。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean name="user" class="com.allen.pojo.User" p:age="18" p:name="allen"/>
</beans>

测试

@Test
public void test2(){
    ApplicationContext context = new ClassPathXmlApplicationContext("userBeans.xml");
    User user = (User) context.getBean("user");
    System.out.println(user.toString());
}

输出

User{name='allen', age=18}

c命名空间依赖注入(constructor-arg)

编写 userBeans.xml,注意导入

xmlxmlns:c="http://www.springframework.org/schema/c"

然后使用 c:age 和 c:name 进行赋值。

注意:此时需要对 User 类加入有参和无参构造器。有参构造器为了c依赖注入,无参构造器为了p依赖注入。默认是无参构造,但加上有参构造将会覆盖无参构造,因此需要重载无参构造

User 类

public class User {

    private String name;
    private int age;

    //无参
    public User() {
    }

    //有参
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

userBeans.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"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<!--    <bean name="user" class="com.allen.pojo.User" p:age="18" p:name="allen"/>-->
    <bean name="user2" class="com.allen.pojo.User" c:age="20" c:name="china"/>
</beans>

测试

@Test
public void test3(){
    ApplicationContext context = new ClassPathXmlApplicationContext("userBeans.xml");
    User user = (User) context.getBean("user2");
    System.out.println(user.toString());
}

输出

User{name='china', age=20}

注意点:p 命名空间和 c 命名空间不能直接使用,需要导入 xml 约束

xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"

文章作者: Hailong Gao
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Hailong Gao !
评论
  目录