Spring学习总结(三):基于XML装配Bean(1)

一、Bean 的装配

       Bean 的装配可以理解为依赖关系注入,Bean 的装配方式也就是 Bean 的依赖注入方式。Spring容器支持多种形式的 Bean 的装配方式,如基于 XML 的 Bean 装配、基于 Annotation 的 Bean 装配和自动装配等。

       Spring 基于 XML 的装配通常采用两种实现方式,即set注入和构造注入。

1、set注入

       在 Spring 实例化 Bean 的过程中,首先会调用默认的构造方法实例化 Bean 对象,然后通过Java的反射机制调用 setXxx() 方法进行属性的注入。因此,设值注入要求一个 Bean 的对应类必须满足以下两点要求:

  • 必须提供一个默认的无参构造方法。
  • 必须为需要注入的属性提供对应的 setter 方法。

       接下来就用一个简单案例演示一下set注入。步骤如下:

       (1)创建Person类,并提供私有属性name和age以及它们的set方法,覆写toString()。

public class Person {
    private String name;
    private Integer age;

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

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

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

       (2)在bean.xml文件中配置person对象,用set注入方式注入属性值。

    <!--  配置Person  -->
    <bean id="person" class="com.yht.example1.entity.Person">
        <!--  name:类中属性的名称  value:向属性注入的值     -->
        <property name="name" value="张三"></property>
        <property name="age" value="33"></property>
     </bean>

       (3)进行单元测试

    @Test
    public void testPerson(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
        Person person = (Person) applicationContext.getBean("person");
        System.out.println(person);
       
    }

        执行结果如下:

2、构造注入

       使用设值注入时,在 Spring 配置文件中,需要使用 <bean> 元素的子元素 <property> 元素为每个属性注入值。而使用构造注入时,在配置文件中,主要使用 <constructor-arg> 标签定义构造方法的参数,可以使用其 value 属性(或子元素)设置该参数的值。下面通过案例演示基于 XML 方式的 Bean 的装配。

       构造注入有两种方式:第一种通过 <constructor-arg>的子元素name完成;第二种通过 <constructor-arg>的子元素index来完成,这里的index指的是属性在构造方法中的下标,从0开始。来做一个简单测试:

       (1)创建Book类,提供私有属性bName和bAuthor,并提供有参构造(bName和bAuthor)。

public class Book {
    private String bName;
    private String bAuthor;

    public Book(String bName, String bAuthor) {
        this.bName = bName;
        this.bAuthor = bAuthor;
    }

    @Override
    public String toString() {
        return "Book{" +
                "bName='" + bName + '\'' +
                ", bAuthor='" + bAuthor + '\'' +
                '}';
    }
}

       (2)在bean.xml中配置person对象,用构造注入的方式注入属性值。

    <!-- 配置book:用name的方式   -->
    <bean id="book1" class="com.yht.example1.entity.Book">
        <constructor-arg name="bName" value="三国演义"></constructor-arg>
        <constructor-arg name="bAuthor" value="罗贯中"></constructor-arg>
    </bean>
    <!-- 配置book:用index的方式   -->
    <bean id="book2" class="com.yht.example1.entity.Book">
        <constructor-arg name="bName" value="水浒传"></constructor-arg>
        <constructor-arg name="bAuthor" value="施耐庵"></constructor-arg>
    </bean>

       (3)进行单元测试。

    @Test
    public void testBook(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
        //获取用name注入的对象
        Book book1 = (Book) applicationContext.getBean("book1");
        System.out.println(book1);
        //获取用index注入的对象
        Book book2 = (Book) applicationContext.getBean("book2");
        System.out.println(book2);
    }

        执行结果如下:

3、p名称空间注入

从 2.0开始,Spring支持使用名称空间的可扩展配置格式。这些名称空间都是基于一种XML Schema定义。事实上,我们所看到的所有bean的配置格式都是基于一个 XML Schema文档。

p名称空间并不需要定义在一个XSD文件中,它只在Spring内核中存在采用p名称空间就可以在bean元素中使用属性来描述property的值。

写法:

普通属性        p:属性名=”值”

对象属性        p:属性名-ref=”值”

注意事项:

P名称空间注入走的也是set方法,官方目的是简化set注入的property标签的写法,所以并不适用于构造注入。

       我们以注入Person对象的属性值为例,步骤如下:

       (1)在bean.xml中导入p名称空间。

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

        (2)配置person对象,注入属性。

    <!-- p名称空间注入   -->
    <bean id="person2" class="com.yht.example1.entity.Person" p:name="李四" p:age="24" >
    </bean>

       (3)进行单元测试。

    @Test
    public void testPerson(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean1.xml");
        //set注入
        Person person = (Person) applicationContext.getBean("person");
        System.out.println(person);
        //p名称空间注入
        Person person2 = (Person) applicationContext.getBean("person2");
        System.out.println(person2);
    }

        执行结果如下:

二、Bean装配的几点说明

1、bean的子元素name

       bean除了id和class属性,还有一个name属性,Spring 容器可以通过此属性对容器中的 Bean 进行配置和管理,name 属性中可以为 Bean 指定多个名称,每个名称之间用逗号或分号隔开,且可以包含特殊字符。我们用案例来验证一下:

       (1)在bean.xml配置person对象,并给定多个值。

<!--  测试bean的name属性  -->
    <bean class="com.yht.example1.entity.Person" name="p1,p2,p3@">
        <property name="name" value="赵飞"></property>
        <property name="age" value="23"></property>
    </bean>

       (2)进行单元测试。

    @Test
    public void testPersonP(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean1.xml");
        Person p1 = (Person) applicationContext.getBean("p1");
        System.out.println(p1);
        Person p2 = (Person) applicationContext.getBean("p2");
        System.out.println(p2);
        Person p3 = (Person) applicationContext.getBean("p3@");//含有特殊字符
        System.out.println(p3);
    }

       执行结果如下:

       注意点:不管是id还是name,其值都不能重复。即:id之间、name之间、id和name之间都必须唯一。如下:

2、set注入和构造注入是否可以混合使用

       (1)对Person类做一些修改,添加无参构造、含有name的有参构造。

public class Person {
    private String name;
    private Integer age;

    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

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

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

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

       (2)在bean.xml中配置Person对象,注入属性

    <!--set注入和构造注入混合使用-->
    <bean id="per" class="com.yht.example1.entity.Person">
        <constructor-arg name="name" value="tom"></constructor-arg>
        <property name="age" value="41"></property>
    </bean>

       (3)进行单元测试。

    @Test
    public void testPer(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean1.xml");
        Person per = (Person) applicationContext.getBean("per");
        System.out.println(per);
    }

       执行结果如下:

       结论:set注入和构造注入可以同时使用,但不推荐。 

猜你喜欢

转载自blog.csdn.net/weixin_47382783/article/details/112732508