Spring依赖注入之为类类型注入的三种方式

90 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情

1 为类类型属性赋值

Clazz类

public class Clazz {

    private Integer cid;
    private String cname;

    public Clazz() {
    }

    public Clazz(Integer cid, String cname) {
        this.cid = cid;
        this.cname = cname;
    }

    //get和set方法
    //toString方法
}

Student类

public class Student {

    private Integer sid;

    private String sname;

    private Integer age;

    private String gender;

    private Double score;

    private Clazz clazz;

    public Student() {
    }

    public Student(Integer sid, String sname, String gender,Integer age) {
        this.sid = sid;
        this.sname = sname;
        this.age = age;
        this.gender = gender;
    }

    public Student(Integer sid, String sname, String gender,Double score) {
        this.sid = sid;
        this.sname = sname;
        this.score = score;
        this.gender = gender;
    }
	//get和set方法
    //toString方法
}

1.1 引用外部bean

场景引入:Student类里面有一个类属性Clazz,如果我们要为这个属性注入值的话是不能使用property标签的value属性的,因为value属性的值会被spring当成字面量(你看到的是什么,它就是什么)。

解决办法:

1.Spring的IOC容器就是用来管理bean的,我们可以让IOC容器来管理Clazz类型的bean

2.在生成Student类型的bean的时候,引入Clazz类型的bean,具体做法如下:

​ (1)在spring的配置文件中声明生成Clazz类型的bean的标签,并为这个bean注入值,这个bean有id

​ (2)在spring的配置文件中声明生成Student类型的bean的标签,只是在为这个bean注入Clazz类型属性名的值的时候,要用property标签的属性ref 来为Clazz类型注入值。ref的值是你要引入的bean的id

<bean id="studentFive" class="com.atguigu.spring.pojo.Student">
    <property name="sid" value="1004"></property>
    <property name="sname" value="赵六"></property>
    <property name="age" value="26"></property>
    <property name="gender" value="男"></property>
    <!--ref:引用IOC容器中的某个bean的id-->
    <property name="clazz" ref="clazzOne"></property>
</bean>

<!--生成Clazz类型的bean-->
<bean id="clazzOne" class="com.atguigu.spring.pojo.Clazz">
    <property name="cid" value="1111"></property>
    <property name="cname" value="最强王者班"></property>
</bean>

测试

@Test
public void testDI() {
    //获取IOC容器
    ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc.xml");
    //获取bean
    Student student = ioc.getBean("studentFive", Student.class);
    System.out.println(student);
}

image-20221130143112133.png

1.2 级联

级联:说白了就是通过对象.属性名的方式为属性名赋值。这种方式在mybatis中的一对多映射关系中比较好用,我个人认为这种级联方式在spring中不是很方便。原因很简单:你想要通过对象.属性名的方式来为属性名赋值,那么你首先就应该拥有对象,意味着你还是得在IOC容器里生成对应的bean。

<bean id="studentFive" class="com.atguigu.spring.pojo.Student">
    <property name="sid" value="1004"></property>
    <property name="sname" value="赵六"></property>
    <property name="age" value="26"></property>
    <property name="gender" value="男"></property>
    <!--ref:引用IOC容器中的某个bean的id-->
    <property name="clazz" ref="clazzOne"></property>
    <!--级联的方式,要保证提前为clazz属性赋值或者实例化-->
    <property name="clazz.cid" value="2222"></property>
    <property name="clazz.cname" value="远大前程班"></property>
</bean>

<!--生成Clazz类型的bean-->
<bean id="clazzOne" class="com.atguigu.spring.pojo.Clazz">
    <property name="cid" value="1111"></property>
    <property name="cname" value="最强王者班"></property>
</bean>

测试,运行上面的测试代码得到如下结果:

image-20221130212425089.png

1.3 内部bean

内部bean说白了就是在一个bean里面直接生成另一个bean。应用的场景是某一个bean的属性名是类类型,而你又不想引用外部bean或者使用级联的方式来为这个bean的类属性注入值。

注意:内部bean虽然也有id,但是无法通过spring的容器获取

<bean id="studentFive" class="com.atguigu.spring.pojo.Student">
    <property name="sid" value="1004"></property>
    <property name="sname" value="赵六"></property>
    <property name="age" value="26"></property>
    <property name="gender" value="男"></property>
    <property name="clazz">
        <!--内部bean,只能在当前bean的内部使用,不能直接通过IOC容器获取-->
        <bean id="clazzInner" class="com.atguigu.spring.pojo.Clazz">
            <property name="cid" value="2222"></property>
            <property name="cname" value="远大前程班"></property>
        </bean>
    </property>
</bean>

运行代码,实验结果如下

image-20221130213931979.png

如果你想获取内部bean的话,又会怎样呢?

@Test
public void testDI() {
    //获取IOC容器
    ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc.xml");
    //获取bean
    /*Student student = ioc.getBean("studentFive", Student.class);
    System.out.println(student);*/
    Clazz clazz = ioc.getBean("clazzInner", Clazz.class);
    System.out.println(clazz);
}

image-20221130214222099.png