zoukankan      html  css  js  c++  java
  • (II)第四节:为 Bean 的各种属性赋值

    一、通过 setter 方法为属性赋值

      通过 bean 的 setXxx() 方法赋值,在配置文件中注册一个bean,并使用 property 标签来给属性赋值:

        <!--注册一个Person对象,Spring会自动创建这个Person对象-->
        <bean id="person01" class="com.njf.spring.bean.Person">
            <!--
                使用property标签为Person对象的属性赋值
                name="lastName": 指定属性名
                value="子龙": 指定属性值
             -->
            <property name="lastName" value="子龙"></property>
            <property name="age" value="18"></property>
            <property name="email" value="zilong@achang.com"></property>
            <property name="gender" value="男"></property>
        </bean>

      同时也在 Person 类的 setLastName() 方法中添加打印输出:

        public void setLastName(String lastName) {
            System.out.println("调用了Person的setLastName方法");
            this.lastName = lastName;
        }

      测试:

        /**
         * 通过 setter 方法为 bean 的属性赋值
         */
        @Test
        public void testSetBeanProp1() {
            ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
    
            Person person01 = (Person) ioc.getBean("person01");
            System.out.println("person01 = " + person01);
        }

      运行结果:

       可以看到使用 property 标签来给属性赋值,其实就是调用的其 setter 方法。

      javaBean的属性名是由什么决定的?

      由getter/setter方法后面的名决定,首字母小写所有的getter/setter都自动生成!!!千万别乱改

      

       注意:使用property标签这种方式是调用的 setter 方法,而不是直接对声明的属性进行操作的。

    二、通过构造器为属性赋值

      1、使用构造器为属性赋值(推荐使用)

        配置文件中进行配置 bean 信息:

        <bean id="person02" class="com.njf.spring.bean.Person">
            <!--
                调用有参构造器进行对象并赋值
                public Person(String lastName, Integer age, String gender, String email)
            -->
            <constructor-arg name="lastName" value="小明"></constructor-arg>
            <constructor-arg name="email" value="xiaoming@126.com"></constructor-arg>
            <constructor-arg name="gender" value="男"></constructor-arg>
            <constructor-arg name="age" value="18"></constructor-arg>
        </bean>

        测试代码:

        @Test
        public void testSetBeanProp2() {
            ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
    
            Person person02 = (Person) ioc.getBean("person02");
            System.out.println("person02 = " + person02);
        }

        

         可以使用 constructor-arg 标签来调用构造器方法给 bean 赋值,而且还可以打乱顺序,Spring 自动匹配合适的构造器。

      2、省略 name 的构造器赋值

        除此之外,还可以只使用 value 属性给赋值:

        <!--可以省略 name 属性,严格按照构造器参数的位置-->
        <bean id="person03" class="com.njf.spring.bean.Person">
            <constructor-arg value="小明"></constructor-arg>
            <constructor-arg value="18"></constructor-arg>
            <constructor-arg value="男"></constructor-arg>
            <constructor-arg value="xiaoming@126.com"></constructor-arg>
        </bean>

        但是这种情况,必须严格按照构造器参数的位置先后依次声明各个属性。

      3、添加 index 属性的赋值(通过索引值指定参数位置)

        对于上面的情况,如果把 email 放在了 sex 的前面会怎么样呢?

        <bean id="person04" class="com.njf.spring.bean.Person">
            <constructor-arg value="小明"></constructor-arg>
            <constructor-arg value="18"></constructor-arg>
            <constructor-arg value="xiaoming@126.com"></constructor-arg>
            <constructor-arg value="男"></constructor-arg>
        </bean>

        测试运行:

        这是就会赋值混乱,就可以使用 index 来指定参数的索引,从 0 开始。

        修改配置文件:

        <!--使用 index 为参数指定索引,从0开始-->
        <bean id="person04" class="com.njf.spring.bean.Person">
            <constructor-arg value="小明"></constructor-arg>
            <constructor-arg value="18"></constructor-arg>
            <constructor-arg value="xiaoming@126.com" index="3"></constructor-arg>
            <constructor-arg value="男" index="2"></constructor-arg>
        </bean>

        再次运行测试:

         正常赋值了。

      4、添加 type 属性的赋值(通过类型区分重载的构造器)

        为 Person 类添加三个参数的构造器:

        public Person(String lastName, Integer age, String gender) {
            System.out.println("调用了三个参数的构造器");
            this.lastName = lastName;
            this.age = age;
            this.gender = gender;
        }
    
        public Person(String lastName, String email, String gender) {
            System.out.println("调用了三个参数的构造器");
            this.lastName = lastName;
            this.email = email;
            this.gender = gender;
        }

        配置 bean 信息:

        <bean id="person05" class="com.njf.spring.bean.Person">
            <constructor-arg value="小明"></constructor-arg>
            <constructor-arg value="18"></constructor-arg>
            <constructor-arg value="男"></constructor-arg>
        </bean>

        测试运行:

        

         发现并没有成功赋值,对于重载的构造器,Spring 仅凭 value 不能判断调用哪一个构造器。

        修改配置文件:

        <!-- 重载的情况type可以指定参数的类型-->
        <bean id="person05" class="com.njf.spring.bean.Person">
            <constructor-arg value="小明"></constructor-arg>
            <constructor-arg value="18" index="1" type="java.lang.Integer"></constructor-arg>
            <constructor-arg value="男"></constructor-arg>
        </bean>

        重新测试:

         可以正确赋值了,当遇到重载的构造器时,可以用 index 指定参数的索引位置,用 type 指定参数的类型。

    三、通过p名称空间为 bean 赋值

      为了简化XML文件的配置,越来越多的XML文件采用属性而非子元素配置信息。Spring  从2.5版本开始引入了一个新的p命名空间,可以通过<bean>元素属性的方式配置Bean 的属性。

      添加名称空间:

      

       使用 p 命名空间后,基于 XML 的配置方式将进一步简化

        <bean id="person06" class="com.njf.spring.bean.Person" p:lastName="小刘" p:age="18" p:gender="男" p:email="liu@126.com"></bean>

      

    四、可以使用的值

      1、字面量

       (1)可以使用字符串表示的值,可以通过 value 属性或 value 子节点的方式指定;
            (2)基本数据类型及其封装类、String 等类型都可以采取字面值注入的方式;
            (3)若字面值中包含特殊字符,可以使用 <![CDATA[]]> 把字面值包裹起来;

      2、null 值

        null 值可以直接使用。

       对于有初始值的 Person 类

        

         如果在容器中就想给它赋值为 null,可以直接使用 null 标签来赋值。

        <!-- 测试使用 null 值,默认引用类型就是 null,基本类型就是默认值 -->
        <bean id="person07" class="com.njf.spring.bean.Person">
            <property name="lastName">
                <null/>
            </property>
        </bean>

         下面的写法是错误的:

        <bean id="person07" class="com.njf.spring.bean.Person">
            <property name="lastName" value="null"></property>
        </bean>

    五、为引用类型赋值

      修改完的 Person 类中有一个 Car 属性,如何给该引用类型的赋值呢

      1、外部已声明的 bean、引用其他的 bean

        当 bean 实例里面有引用其他的 bean 时,可以使用 ref (reference)来引用其他的 bean 的实例。

        配置文件:

        <bean id="car01" class="com.njf.spring.bean.Car">
            <property name="carName" value="宝马"></property>
            <property name="color" value="绿色"></property>
            <property name="price" value="30000"></property>
        </bean>
    
        <!--引用其他 bean-->
        <bean id="person08" class="com.njf.spring.bean.Person">
            <!--ref:引用外面的一个值-->
            <property name="car" ref="car01"></property>
        </bean>

        测试:

        @Test
        public void testSetBeanProp8() {
            ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
    
            Person person08 = (Person) ioc.getBean("person08");
            System.out.println("person08 = " + person08);
            Car car = ioc.getBean(Car.class);
            System.out.println(car == person08.getCar()); //true
    
            car.setPrice(4000);
            System.out.println(person08.getCar().getPrice()); //4000
            System.out.println(car == person08.getCar()); //true
    
        }

        在这里引用的是都是容器中同一个 Car,当修改了 Car 的属性时,Persong08 中的 Car 属性也会跟着变化。(同一个对象)

      2、引用内部 bean

      当 bean 实例仅仅给一个特定的属性使用时,可以将其声明为 内部 bean,内部 bean 声明直接包含在 <property> 或 <constructor-arg> 元素里,不需要设置任何 id 或 name 属性(设置也无妨)
      
      配置文件:
        <bean id="person09" class="com.njf.spring.bean.Person">
            <!--创建内部 bean-->
            <property name="car">
                <bean id="car02" class="com.njf.spring.bean.Car">
                    <property name="carName" value="宝马"></property>
                    <property name="color" value="红色"></property>
                    <property name="price" value="5000"></property>
                </bean>
            </property>
        </bean>
      测试运行:
        @Test
        public void testSetBeanProp9() {
            ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
    
            Person person09 = (Person) ioc.getBean("person09");
            System.out.println("person09 = " + person09);
            System.out.println(person09.getCar());
    
            /**
             * org.springframework.beans.factory.NoSuchBeanDefinitionException:
             * No bean named 'car02' is defined
             */
            Car car02 = (Car) ioc.getBean("car02");
            System.out.println("car02 = " + car02);
        }
        注意:内部 bean 只能使用在当前 bean 中,不能使用到任何其他地方,而且也无法从直接从容器中获取。

      

    六、为集合类型赋值

      1、为数组属性赋值

        配置数组类型的属性,需要指定 <array> 或 <list> 标签,在标签里包含一些元素。
        这些标签可以通过 <value> 指定简单的常量值,通过<ref> 指定对其他 Bean 的引用,通过 <bean> 指定内置 bean 定义,通过<null/> 指定空元素,甚至可以内嵌其他集合。
        配置文件:
        <bean id="person10" class="com.njf.spring.bean.Person">
            <!--  给数组类型赋值  -->
            <property name="names">
                <array>                    <!-- 使用 array 标签-->
                    <value>老张</value>
                    <value>老李</value>
                </array>
            </property>
        </bean>
    
        <bean id="person11" class="com.njf.spring.bean.Person">
            <!--  给数组类型赋值  -->
            <property name="names">
                <list>                    <!-- 使用 list标签-->
                    <value>小张</value>
                    <value>小李</value>
                </list>
            </property>
        </bean>
        测试:
        @Test
        public void testSetBeanProp10() {
            ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
    
            Person person10 = (Person) ioc.getBean("person10");
            System.out.println("person10 = " + person10);
            System.out.println(Arrays.toString(person10.getNames()));
    
            Person person11 = (Person) ioc.getBean("person11");
            System.out.println("person11 = " + person11);
            System.out.println(Arrays.toString(person11.getNames()));
        }
     

      2、为List属性赋值

        使用 <list> 标签,设置同数组

        配置文件:

        <bean id="person12" class="com.njf.spring.bean.Person">
            <!--  给List类型赋值  -->
            <property name="books">          <!-- 使用 array 标签-->
                <array>
                    <bean class="com.njf.spring.bean.Book">
                        <property name="bookName" value="水浒传"></property>
                    </bean>
                </array>
            </property>
        </bean>
    
        <bean id="person13" class="com.njf.spring.bean.Person">
            <!--  给List类型赋值  -->
            <property name="books">
                <list>                        <!-- 使用 list标签-->
                    <bean class="com.njf.spring.bean.Book">
                        <property name="bookName" value="西游记"></property>
                    </bean>
                    <ref bean="book01"></ref>
                </list>
            </property>
        </bean>
    
        <bean id="book01" class="com.njf.spring.bean.Book">
            <property name="bookName" value="红楼梦"></property>
        </bean>

        测试运行:

        @Test
        public void testSetBeanProp11() {
            ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
    
            Person person12 = (Person) ioc.getBean("person12");
            System.out.println("person12 = " + person12);
            System.out.println(person12.getBooks());
    
            Person person13 = (Person) ioc.getBean("person13");
            System.out.println("person13 = " + person13);
            System.out.println(person13.getBooks());
        }

      3、为Set属性赋值

        使用 <set> 标签,其他同数组

        配置文件:

        <bean id="person14" class="com.njf.spring.bean.Person">
            <!--  给 Set 类型赋值  -->
            <property name="hobby">
                <set>
                    <value>骑行</value>
                    <value>爬山</value>
                    <value>打球</value>
                </set>
            </property>
        </bean>

        测试代码:

        @Test
        public void testSetBeanProp14() {
            ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
    
            Person person14 = (Person) ioc.getBean("person14");
            System.out.println("person14 = " + person14);
            System.out.println(person14.getHobby());
        }

      4、为 Map 属性赋值

      java.util.Map 通过 <map> 标签定义,<map> 标签里可以使用多个 <entry> 作为子标签,每个条目包含一个键和一个值。必须在 <key> 标签里定义键。
      因为键和值的类型没有限制,所以可以自由地为它们指定 <value>、<ref>、<bean>或<null/> 元素。
      可以将 Map 的键和值作为 <entry> 的属性定义:简单常量使用 key 和 value 来定义;bean 引用 通过 key-ref 或 value -ref 属性定义。
      配置文件:
        <bean id="person15" class="com.njf.spring.bean.Person">
            <!--  给 Map 类型赋值  -->
            <property name="map">
                <map>
                    <!--一个 entry 代码一个键值对-->
                    <entry key="key01" value="张三"></entry>
                    <entry key="key02" value="18"></entry>
                    <entry key="key03" value-ref="book01"></entry>
                    <entry key="key04">
                        <bean class="com.njf.spring.bean.Car">
                            <property name="carName" value="宝马"></property>
                        </bean>
                    </entry>
                    <entry key="key05">
                        <map></map>
                    </entry>
                    <entry>
                        <key>
                            <value>key06</value>
                        </key>
                        <value>张老师</value>
                    </entry>
                </map>
            </property>
        </bean>
      测试代码:
        @Test
        public void testSetBeanProp15() {
            ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
    
            Person person15 = (Person) ioc.getBean("person15");
            System.out.println("person15 = " + person15);
            System.out.println(person15.getMap());
        }
     

      5、为 Properties 属性赋值

        配置文件:

        <bean id="person16" class="com.njf.spring.bean.Person">
            <property name="properties">
                <!-- properties = new Properties() 所有的 k=v 都是String-->
                <props>
                    <prop key="username">root</prop>
                    <prop key="password">123456</prop>
                </props>
            </property>
        </bean>

        测试代码:

        @Test
        public void testSetBeanProp16() {
            ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
    
            Person person16 = (Person) ioc.getBean("person16");
            System.out.println("person16 = " + person16);
            System.out.println(person16.getProperties());
        }

      6、utils 名称空间创建一个可以外部引用的集合bean

        如果只能将集合对象配置在某个 bean 内部,则这个集合的配置将不能重用。如果可以,希望把集合 bean 的配置拿到外面,供其他 bean 也可以使用。
        注意:配置集合类型的 bean 需要引入 util 名称空间
        

         配置文件:

        <util:list id="bookList">
            <ref bean="book01"/>
            <bean class="com.njf.spring.bean.Book">
                <property name="bookName" value="西游记"></property>
            </bean>
        </util:list>
    
        <util:set id="hobby">
            <value>打球</value>
            <value>爬山</value>
            <value>游泳</value>
        </util:set>
    
        <util:map id="map">
            <entry>
                <key>
                    <value>20200316</value>
                </key>
                <value>小黑老师</value>
            </entry>
    
            <entry>
                <key>
                    <value>20200317</value>
                </key>
                <value>小白老师</value>
            </entry>
        </util:map>
    
        <bean id="person17" class="com.njf.spring.bean.Person">
            <property name="books" ref="bookList"></property>
            <property name="hobby" ref="hobby"></property>
            <property name="map" ref="map"></property>
        </bean>

        测试代码:

        @Test
        public void testSetBeanProp17() {
            ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
    
            Person person17 = (Person) ioc.getBean("person17");
            System.out.println("person17 = " + person17);
            System.out.println(person17.getBooks());
            System.out.println(person17.getHobby());
            System.out.println(person17.getMap());
        }
     

        当使用了util名称空间创建的集合对象,可以直接从容器中获取到集合 bean对象。

      7、级联属性赋值

        给 bean 的级联属性赋值,当一个 bean 中又引用了另外一个 bean,可以为引用的 bean的属性进行赋值。

        配置文件:

        <bean id="person18" class="com.njf.spring.bean.Person">
            <property name="lastName" value="张三"></property>
            <property name="car" ref="car01"></property>
            <!-- 设置级联属性 -->
            <property name="car.carName" value="红旗"></property>
        </bean>

        测试代码:

        /**
         * 级联属性可以修改属性的属性,注意:原来的 bean 的值可能会被修改
         */
        @Test
        public void testSetBeanProp18() {
            ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
    
            Person person18 = (Person) ioc.getBean("person18");
            System.out.println("person18 = " + person18);
            System.out.println(person18.getCar().getCarName());
    
            Car car01 = (Car) ioc.getBean("car01");
            System.out.println(car01.getCarName());
        }
  • 相关阅读:
    栈:删除最外层的括号 (Leetcode 1021 / 155 / 1172 / 剑指31 / 面试 03.03)
    JDBC: Druid连接池
    JDBC: C3P0
    JDBC: C3P0
    JDBC: C3P0连接池
    JDBC: DBCP连接池
    JDBC: 数据库连接池
    JDBC: JDBC 控制事务
    JDBC: 预处理对象
    wpf 键盘快捷键响应
  • 原文地址:https://www.cnblogs.com/niujifei/p/15412983.html
Copyright © 2011-2022 走看看