• Spring4学习回顾之路04—引用其他Bean,集合数据注入,内部Bean


    引用其他Bean

       组件应用程序的Bean经常需要相互协作以完成应用程序的功能,所以要求Bean能够相互访问,就必须在Bean配置文件中指定Bean的引用。在Bean的配置文件中可以用过<ref>元素或者ref属性为Bean的属性或构造器参数指定对Bean的引用。也可以在属性或者构造器里包含Bean的声明,这样的Bean称为内部Bean。具体看代码,在之前的Student类上新增Book类,(一个学生有一本书)。代码如下:

    Book.java

    package com.lql.spring01;
    
    /**
     * @author: lql
     * @date: 2019.10.11
     * Description:
     * Created with IntelliJ IDEA
     */
    public class Book {
    
        private String name;
    
        private double price;
    
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public double getPrice() {
            return price;
        }
    
        public void setPrice(double price) {
            this.price = price;
        }
    }

    Student.java 

    package com.lql.spring01;/**
     * @author: lql
     * @date: 2019.09.24
     * Description:
     */
    public class Student {
    
        private String name;
    
        private Integer age;
    
        private Book book;
    
        public Book getBook() {
            return book;
        }
    
        public void setBook(Book book) {
            this.book = book;
        }
    
        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;
        }
    }

    然后在applicationContext.xml的配置文件中配置Book类的bean;

    <?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:标识  class:类路径   name:属性名,注意是针对set方法的属性名,不是变量的属性名    value:属性值  -->
        <bean id="student" class="com.lql.spring01.Student">
            <property name="name" value="lql"></property>
            <property name="age" value="18"></property>
            <property name="book" ref="book"></property>
            <!--<property name="book">
                <ref bean="book"></ref>
            </property>-->
        </bean>
    
        <bean id="book" class="com.lql.spring01.Book">
            <property name="name" value="三国演义"></property>
            <property name="price" value="79.9"></property>
        </bean>
    </beans>

    代码中就是使用<ref>元素或者ref属性来引用的示例,测试是没问题的:

    public void Hello() {
    
            System.out.println("Hello :" + this.getName() + ",Book:" + this.book.getName());
        }
    
        public static void main(String[] args) {//创建IOC容器
            ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
            //获取bean
            Student student = app.getBean("student", Student.class);
            //调用方法
            student.Hello();
        }

    //输出:Hello :lql,Book:三国演义

    内部Bean

      当Bean的实例仅仅给一个特定的属性使用时,可以将其声明为内部Bean,内部Bean声明直接包含<property>或<constructor-arg>元素里,不需要设置任何的id或name属性,内部Bean不能使用在任何其他地方。

    实际很简单,配置更改如下:

     <bean id="student" class="com.lql.spring01.Student">
            <property name="name" value="lql"></property>
            <property name="age" value="18"></property>
            <!--内部bean-->
            <property name="book">
                <bean class="com.lql.spring01.Book">
                    <property name="price" value="100.0"></property>
                    <property name="name" value="时间简史"></property>
                </bean>
            </property>
    </bean>

    测试也是没问题的,这里省略打印。

    NULL值和级联属性

    可以使用专用的<null/>元素标签为Bean的字符串或其它对象类型的属性注入null值(意义不大,了解知道有这么回事就行了),当然Spring也支持级联属性的配置。

    <?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:标识  class:类路径   name:属性名,注意是针对set方法的属性名,不是变量的属性名    value:属性值  -->
        <bean id="student" class="com.lql.spring01.Student">
            <property name="name" value="lql"></property>
            <property name="age" value="18"></property>
            <property name="book">
                <null/>
            </property>
        </bean>
        <bean id="book" class="com.lql.spring01.Book">
            <property name="name" value="三国演义"></property>
            <property name="price" value="79.9"></property>
        </bean>
    </bean>

    这样一来,book的引用就是null。级联属性的代码如下:

    <?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:标识  class:类路径   name:属性名,注意是针对set方法的属性名,不是变量的属性名    value:属性值  -->
        <bean id="student" class="com.lql.spring01.Student">
            <property name="name" value="lql"></property>
            <property name="age" value="18"></property>
            <property name="book" ref="book"></property>
            <property name="book.price" value="19.9"></property>
            <property name="book.name" value="java从入门到放弃"></property>
        </bean>
        <bean id="book" class="com.lql.spring01.Book">
            <property name="name" value="三国演义"></property>
            <property name="price" value="79.9"></property>
        </bean>
    </bean>

    打印结果为:Hello :lql,Book:java从入门到放弃而非三国演义了。需要注意的是一定要提供setter()。并且我先给book赋值的后调级联属性的,<property name="book" ref="book"></property>,如果没有先引用直接使用级联属性可行不可行呢?答案是否定的,在Struts2里面是支持的,但是Spring是不支持。它会报:Value of nested property 'book' is null。(但是很多情况下也用不到级联属性,知道了解就行了)。

    集合属性

      在Spring中可以通过一组内置的xml标签来配置集合属性(例如:<list>,<set>,<map>等),配置java.util.List类型的属性,需要指定<list>标签,内部可以使用<value>指定简单的常量值,也可以通过<ref>指定对其他Bean的引用,通过<null/>指定空元素,甚至可以内嵌其他集合。当然,数组也可以使用<list>,<array>。代码如下:先建ListDemo类

    package com.lql.spring01;
    
    import java.util.List;
    
    /**
     * @author: lql
     * @date: 2019.10.11
     * Description:
     * Created with IntelliJ IDEA
     */
    public class ListDemo {
    
        private List<String> list;
    
    
        public void setList(List<String> list) {
            this.list = list;
        }
    
        public List<String> getList() {
            return list;
        }
    }

    配置文件如下:需要为ListDemo.java的list属性赋值

    <?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="list" class="com.lql.spring01.ListDemo">
            <property name="list">
                <list value-type="java.lang.String">
                    <value>红色</value>
                    <value>白色</value>
                    <value>黑色</value>
                    <value>还原色</value>
                </list>
            </property>
        </bean>
     </bean>

    测试代码和结果:

     public static void main(String[] args) {
            ApplicationContext app = new ClassPathXmlApplicationContext("applicationcontext.xml");
            ListDemo list = app.getBean("list", ListDemo.class);
            list.getList().forEach(System.out::println);
        }

    //结果:      红色 白色 黑色 还原色

    java.util.Set需要使用<set>标签,定义方式与List一样。这里略,(set不允许重复)

    java.util.map通过<map>标签定义,<map>标签里可以使用多个<entry>作为子标签,每个条目包含一个键和一个值,需要注意几点:

    ①:必须在<key>标签里面定义key.

    ②:因为键和值的类型没有限制,所以可以自由地为它们指定<value>,<ref>,<bean>,<null>元素。

    ③:可以将Map的键和值作为<entry>的属性定义。简单常量使用key和value定义,Bean引用通过key-ref和value-ref属性定义

    ④:使用<props>定义java.util.properties,(properties是hashtable的子类)该标签使用多个<prop>作为子标签,每个<prop>标签必须定义key属性。

    代码如下,简单的形式定义:

    <?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="list" class="com.lql.spring01.ListDemo">
            <property name="list">
                <list value-type="java.lang.String">
                    <value>红色</value>
                    <value>白色</value>
                    <value>黑色</value>
                    <value>还原色</value>
                </list>
            </property>
    
            <property name="set">
                <set value-type="java.lang.Integer">
                    <value>1</value>
                    <value>2</value>
                    <value>3</value>
                    <value>4</value>
                    <value>5</value>
                    <value>3</value>
                </set>
            </property>
    
            <property name="map">
                <map>
                    <entry key="壹">
                        <value>1</value>
                    </entry>
                    <entry key="贰">
                        <value>2</value>
                    </entry>
                </map>
            </property>
        </bean>
    </beans>

    测试结果是可行的:

     public static void main(String[] args) {
            ApplicationContext app = new ClassPathXmlApplicationContext("applicationcontext.xml");
            ListDemo list = app.getBean("list", ListDemo.class);

         //list list.getList().forEach(System.out::println); System.out.println(
    "====================");

         //set list.getSet().forEach(System.out::println); System.out.println(
    "===================="); //map Map<String, Integer> map = list.getMap(); map.forEach((x,y)-> System.out.println(x + "====" + y)); }
    //输出:壹====1,贰====2

    接下来试试properties类:

    先定义一个PropertiesDemo.java

    package com.lql.spring01;
    
    import java.util.Properties;
    
    /**
     * @author: lql
     * @date: 2019.10.11
     * Description:
     * Created with IntelliJ IDEA
     */
    public class PropertiesDemo {
    
        private Properties properties;
    
    
        public void setProperties(Properties properties) {
            this.properties = properties;
        }
    
    
        public Properties getProperties() {
            return properties;
        }
    }

    applicationContext.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="properties" class="com.lql.spring01.PropertiesDemo">
    
            <property name="properties">
                <props>
                    <prop key="壹">1</prop>
                    <prop key="贰">2</prop>
                    <prop key="叁">3</prop>
                </props>
            </property>
        </bean>
     </bean>

    测试代码和结果如下:

     public static void main(String[] args) {
            ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
    
            PropertiesDemo properties = app.getBean("properties", PropertiesDemo.class);
    
            properties.getProperties().forEach((x,y) -> System.out.println(x + "==" + y));
        }

    //结果:叁==3 壹==1 贰==2

    配置单独集合Bean,以供引用

    拿之前的List来说,applicationContext.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:util="http://www.springframework.org/schema/util"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/util  http://www.springframework.org/schema/util/spring-util.xsd">
    
        
        <util:list id="reList">
                <value>红色</value>
                <value>黄色</value>
                <value>黑色</value>
                <value>还原色</value>
        </util:list>
        <bean id="list" class="com.lql.spring01.ListDemo">
            <property name="list" ref="reList"></property>
        </bean>
    </bean>

    需要注意的是引入util头,上图已经加粗显示。测试还是没有问题的:

       public static void main(String[] args) {
            ApplicationContext app = new ClassPathXmlApplicationContext("applicationcontext.xml");
            ListDemo list = app.getBean("list", ListDemo.class);
            list.getList().forEach(System.out::println);
    }
    //结果 红色 黄色 黑色 还原色

    P命名空间

    同样,先引入P的头。加粗

    <?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:util="http://www.springframework.org/schema/util"
           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
            http://www.springframework.org/schema/util  http://www.springframework.org/schema/util/spring-util.xsd">
    
    
        <bean id="stu" class="com.lql.spring01.Student" P:name="张四" P:age="18" P:book-ref="book"></bean>
    </bean>

    测试结果:Hello :张四,Book:java从入门到放弃。

  • 相关阅读:
    TCP/IP协议之ARP寻址
    流畅的python学习笔记:第九章:符合python风格的对象
    【原创】大叔经验分享(12)如何程序化kill提交到spark thrift上的sql
    【原创】大叔问题定位分享(16)spark写数据到hive外部表报错ClassCastException: org.apache.hadoop.hive.hbase.HiveHBaseTableOutputFormat cannot be cast to org.apache.hadoop.hive.ql.io.HiveOutputFormat
    【原创】大数据基础之Spark(3)Spark Thrift实现原理及代码实现
    【原创】大叔问题定位分享(15)spark写parquet数据报错ParquetEncodingException: empty fields are illegal, the field should be ommited completely instead
    【原创】大叔经验分享(11)python引入模块报错ImportError: No module named pandas numpy
    【原创】免费股票行情接口
    【原创】大叔经验分享(10)Could not transfer artifact org.apache.maven:maven. from/to central. Received fatal alert: protocol_version
    【原创】大叔经验分享(16)Context namespace element 'component-scan' and its parser class [org.springframework.context.annotation.ComponentScanBeanDefinitionParser] are only available on JDK 1.5 and higher
  • 原文地址:https://www.cnblogs.com/-qilin/p/11653239.html
Copyright © 2020-2023  润新知