Spring复习——day03_Spring 基于XML管理Bean(1)

目录

1.获取bean的三种方式

1.1、根据id获取

1.2、根据类型获取

1.3、根据id和类型获取

1.4、扩展

1.5、结论

2.依赖注入之setter注入

1.1、创建学生类Student

1.2、配置bena时为属性赋值

1.3、测试

3.依赖注入之构造器注入

3.1、在Student类中添加有参构造

3.2、配置bean

3.3、测试

4.特殊值处理

4.1、字面量赋值

4.2、null值

4.3、xml实体

4.4、CDATA节

5.为类类型属性赋值

5.1、创建班级类Clazz

5.2、修改Student类

5.3、方式一:引用外部已声明的bean

5.4、方式二:内部bean

5.5、方式三:级联属性赋值


1.获取bean的三种方式

1.1、根据id获取

由于 id 属性指定了 bean 的唯一标识,所以根据 bean 标签的 id 属性可以精确获取到一个组件对象。这种获取的对象默认是Object类型,需要强转为需要的类型。

    <bean id="studentOne" class="com.itwpf.spring.pojo.Student"></bean>
@Test
    public void testIOC(){
        //获取IOC容器
        ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
        //获取bean
        //根据 id
        Student studentOne = (Student)ioc.getBean("studentOne");
        
        System.out.println(studentOne);
}

1.2、根据类型获取

<bean id="studentTwo" class="com.itwpf.spring.pojo.Student"/>
    @Test
    public void testIOC(){
        //获取IOC容器
        ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
        //获取bean
        
        //根据类型
        Student studentTwo = ioc.getBean(Student.class);
        Student studentThree = ioc.getBean("studentOne", Student.class);
        System.out.println(studentThree);
    }

注意:根据类型获取bean时,要求ioc容器中有且只有一个类型匹配的bean

        若没有任何一个类型匹配的bean,此时抛出异常:NoSuchBeanDefinitionException

        若有多个类型匹配的bean,此时抛出异常:NoUniqueBeanDefinitionException

1.3、根据id和类型获取

<bean id="studentThree" class="com.itwpf.spring.pojo.Student"/>
    @Test
    public void testDI(){
        ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
        Student studentTwo = ioc.getBean("studentTwo", Student.class);

        Student studentThree = ioc.getBean("studentSix", Student.class);
        System.out.println(studentThree);
    }

1.4、扩展

如果组件类实现了接口,可以根据接口类型获取bean,前提是bean唯一

如果一个接口有多个实现类,这些实现类都配置了bean,就不能根据接口获取bean,因为bean不唯一。

1.5、结论

根据类型来获取bean时,在满足bean唯一性的前提下,其实只是看:『对象 instanceof 指定的类 型』的返回结果,只要返回的是true就可以认定为和类型匹配,能够获取到。

(instanceof用法,是Java中的二元运算符,左边是对象,右边是类;当对象是右边类或子类所创建对象时,返回true;否则,返回false。)

2.依赖注入之setter注入

1.1、创建学生类Student

public class Student {

    private Integer id;

    private String name;

    private Integer age;

    private String sex;

    public Student() {
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                '}';
    }
}

1.2、配置bena时为属性赋值

    <bean id="studentTwo" class="com.itwpf.spring.pojo.Student">
        <!--
            property:通过成员变量的set方法进行赋值
            name:指定属性名(是通过setXXX() getXxx()获取的,与成员变量无关
            value:指定属性值
        -->
        <property name="sid" value="1001"></property>
        <property name="sname" value="张三"></property>
        <property name="age" value="23"></property>
        <property name="gender" value="男"></property>
    </bean>

1.3、测试

@Test
public void testDIBySet(){
    ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    Student studentTwo = ac.getBean("studentTwo", Student.class);
    System.out.println(studentTwo);
}

3.依赖注入之构造器注入

3.1、在Student类中添加有参构造

public Student(Integer id, String name, Integer age, String sex) {
    this.id = id;
    this.name = name;
    this.age = age;
    this.sex = sex;
}

3.2、配置bean

    <bean id="studentThree" class="com.itwpf.spring.pojo.Student">
        <constructor-arg value="1002" name="sid"></constructor-arg>
        <constructor-arg value="李四" index="1"/>
        <constructor-arg value="24"/>
        <constructor-arg value="女"/>
    </bean>

注意:constructor-arg标签还有两个属性可以进一步描述构造器参数:

index属性:指定参数所在位置的索引(从0开始)

name属性:指定参数名

3.3、测试

@Test
public void testDIBySet(){
    ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    Student studentTree = ac.getBean("studentTree", Student.class);
    System.out.println(studentTree);
}

4.特殊值处理

4.1、字面量赋值

什么是字面量?

int a = 10; 声明一个变量a,初始化为10,此时a就不代表字母a了,而是作为一个变量的名字。当我们引用a 的时候,我们实际上拿到的值是10。 而如果a是带引号的:'a',那么它现在不是一个变量,它就是代表a这个字母本身,这就是字面量。所以字面量没有引申含义,就是我们看到的这个数据本身。

<!-- 使用value属性给bean的属性赋值时,Spring会把value属性的值看做字面量 -->
<property name="name" value="张三"/>

4.2、null值

<property name="name">
<null />
</property>

注意,下面这种写法,为name所赋的值是字符串

<property name="name" value="null"></property>

4.3、xml实体

<!-- 小于号在XML文档中用来定义标签的开始,不能随便使用 -->
<!-- 解决方案一:使用XML实体来代替 -->
<!-- 
    &: &amp;
    单引号('): &apos;
    大于(>):&gt;
    小于(<):&lt;
    双引号("):&quot;
-->
<property name="expression" value="a &lt; b"/>

4.4、CDATA节

在idea中直接打出大写的CD就可以快速构建

<property name="expression">
    <!-- 解决方案二:使用CDATA节 -->
    <!-- CDATA中的C代表Character,是文本、字符的含义,CDATA就表示纯文本数据 -->
    <!-- XML解析器看到CDATA节就知道这里是纯文本,就不会当作XML标签或属性来解析 -->
    <!-- 所以CDATA节中写什么符号都随意 -->
    <value><![CDATA[a < b]]></value>
</property>

5.为类类型属性赋值

5.1、创建班级类Clazz


public class Clazz {

    private Integer cid;

    private String cname;

    @Override
    public String toString() {
        return "Clazz{" +
                "cid=" + cid +
                ", cname='" + cname + 
                '}';
    }


    public Clazz() {
    }

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

    public Integer getCid() {
        return cid;
    }

    public void setCid(Integer cid) {
        this.cid = cid;
    }

    public String getCname() {
        return cname;
    }

    public void setCname(String cname) {
        this.cname = cname;
    }

}

5.2、修改Student类

在Student类中添加以下代码:

private Clazz clazz;

public Clazz getClazz() {
    return clazz;
}

public void setClazz(Clazz clazz) {
    this.clazz = clazz;
}

5.3、方式一:引用外部已声明的bean

配置Clazz类型的bean

<bean id="clazzOne" class="com.atguigu.spring.bean.Clazz">
    <property name="clazzId" value="1111"></property>
    <property name="clazzName" value="306班"></property>
</bean>

为Student中的clazz赋值

<bean id="studentFour" class="com.atguigu.spring.bean.Student">
    <property name="id" value="1004"></property>
    <property name="name" value="赵六"></property>
    <property name="age" value="26"></property>
    <property name="sex" value="女"></property>
    <!-- ref属性:引用IOC容器中某个bean的id,将所对应的bean为属性赋值 -->
    <property name="clazz" ref="clazzOne"></property>
</bean>

如果错把ref属性写成了value属性,会抛出异常: Caused by: java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'com.atguigu.spring.bean.Clazz' for property 'clazz': no matching editors or conversion strategy found

意思是不能把String类型转换成我们要的Clazz类型,说明我们使用value属性时,Spring只把这个 属性看做一个普通的字符串,不会认为这是一个bean的id,更不会根据它去找到bean来赋值

5.4、方式二:内部bean

<bean id="studentFour" class="com.atguigu.spring.bean.Student">
    <property name="id" value="1004"></property>
    <property name="name" value="赵六"></property>
    <property name="age" value="26"></property>
    <property name="sex" value="女"></property>
    <property name="clazz">
        <!-- 在一个bean中再声明一个bean就是内部bean -->
        <!-- 内部bean只能用于给属性赋值,不能在外部通过IOC容器获取,因此可以省略id属性 -->
        <bean id="clazzInner" class="com.atguigu.spring.bean.Clazz">
            <property name="clazzId" value="2222"></property>
            <property name="clazzName" value="307班"></property>
        </bean>
    </property>
</bean>

5.5、方式三:级联属性赋值

级联赋值,是更新数据,更新所引用的bean所赋的值

<bean id="studentFour" class="com.atguigu.spring.bean.Student">
    <property name="id" value="1004"></property>
    <property name="name" value="赵六"></property>
    <property name="age" value="26"></property>
    <property name="sex" value="女"></property>
    <!-- 一定先引用某个bean为属性赋值,才可以使用级联方式更新属性 -->
    <property name="clazz" ref="clazzOne"></property>
    <property name="clazz.clazzId" value="3333"></property>
    <property name="clazz.clazzName" value="308班"></property>
</bean>

<bean id="clazzOne" class="com.atguigu.spring.bean.Clazz">
    <property name="clazzId" value="1111"></property>
    <property name="clazzName" value="306班"></property>
</bean>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值