zoukankan      html  css  js  c++  java
  • Spring-IOC:复杂值注入、各种类型赋值、bean的复用

    复杂值注入准备工作

    从这里开始我们要进行复杂值的注入

    创建 Car

    public class Car {
        // 写入有参无参setget...
        private String carName;
        private Integer price;
        private String color;
    }
    

    创建Book

    public class Book {
        // 写入有参无参setget...
        private String bookName;
        private Integer price;
    }
    

    Person类

    public class Person {
        // 写入有参无参setget ToString...
        private String lastName;
        private String gender;
        private Integer age;
        private String email;
    
        private Car car;
        private List<Book> books;
        private Map<String,Object> maps;
        private Properties properties;
    }    
    

    测试空值null

    1.当注入bean不赋值

    <bean id="person01" class="com.jiang.bean.Person">
    
    </bean>
    

    此时我们仅仅只是注册了 这个bean,但我们是没有进行任何赋值操作的

    我们进行打印输出会得到

    Person{lastName='null', gender='null', age=null, email='null', car=null, books=null, maps=null, properties=null}
    

    会将他们的默认值输出,即为null

    2.设置初始值

    但此时我将Person 中的lastName设置初始值 "小姜"

    public class Person {
        private String lastName = "小姜";
        ......
    

    再次进行输出

    Person{lastName='小姜', gender='null', age=null, email='null', car=null, books=null, maps=null, properties=null}
    

    那么打印出来的话,则是 lastname="小姜"....
    但如果我此时 我希望默认值小姜变成null 怎么做

    <bean id="person01" class="com.jiang.bean.Person">
    	可以在这里使用porperty进行赋值
        <property name="lastName" value="null"></property>
    </bean>
    

    此时打印

    Person{lastName='null', gender='null', age=null, email='null', car=null, books=null, maps=null, properties=null}
    

    好像是变成了lastname=null

    但是当我们进行判断

    Person person01 = app.getBean("person01", Person.class);
    System.out.println(person01.getLastName() == null);
    

    输出false 即不是真正的null 只是一个字符串null而已

    3.解决方法

    <bean id="person01" class="com.jiang.bean.Person">
    	可以在这里使用porperty进行赋值
        <!-- <property name="lastName" value="null"></property> -->
        通过null 标签进行设置空值
    	<property name="lastName">
    		<null/>
        </property>
    </bean>
    

    复杂类型的赋值 在标签体里进行赋值

    System.out.println(person01.getLastName() == null);
    

    此时判断则为true

    ref引入外部bean

    ref :引用外面的值

    <beans>	
    	<bean id="person01" class="com.jiang.bean.Person">
       	 	<property name="car" ref="car01"></property>
    	</bean>
    
        <!--2.ref引用的car-->
        <bean id="car01" class="com.jiang.bean.Car">
            <property name="carName" value="milk"></property>
            <property name="color" value="white"></property>
            <property name="price" value="2000"></property>
        </bean>
    </beans>
    

    那么我们在person对象里 有private Car car 也就是在Person类中有Car对象

    我们之前通过property赋值 ,都是赋给某个属性的值 :比如 name、age..... 那么我们此时如何赋给对象值呢

    我们可以先将我们的car对象注册为一个bean 然后通过ref 引用我们这个bean

    注意点:

    ​ 1.我们在这里的ref 就是引用的下面car01的值

    ​ 2.这个car 虽然是person01中的car,但其实他是引用的ioc容器中的car01

    ​ 3.所以car == car01 当car01进行修改时,car的值也会随着改变


    引入内部bean

    其实就是在我们person01下 new了一个新的car对象

    <beans >
        <bean id="person01" class="com.jiang.bean.Person">
            <!--3.bean标签在内部创建
                直接就是在这个person01下面新new了一个car对象
                  -->
            <property name="car">
                <bean id="carbean" class="com.jiang.bean.Car">
                    <property name="price" value="200"></property>
                    <property name="color" value="black"></property>
                    <property name="carName" value="mmm~"></property>
                </bean>
            </property>
        </bean>
    </beans>
    

    很简单 我们的car是个对象 不是个属性

    那么我们就在property里注册一个新的bean


    List类型赋值

    1.在list标签中添加元素

        <bean id="person02" class="com.jiang.bean.Person">
            <property name="books">
               
                <list>
                    <!--list标签中添加一个元素-->
                    <bean class="com.jiang.bean.Book">
                        <property name="price" value="50"></property>
                        <property name="bookName" value="Spring5核心原理"></property>
                    </bean>
                </list>
            </property>
        </bean>
    

    <list></list> 其实就是books = new ArrayList<Book>()

    为books赋值 就说向list集合books中添加元素

    第一种方法就是直接通过bean标签 添加属性值 比较简单

    2.ref引用

    <bean id="book" class="com.jiang.bean.Book">
        <property name="bookName" value="高性能Netty"></property>
        <property name="price" value="55"></property>
    </bean>
    
    <bean id="person02" class="com.jiang.bean.Person">
        <property name="books">
            <!--books = new ArrayList<Book>()-->
            <list>
                <!--list标签中添加一个元素-->
                <bean class="com.jiang.bean.Book">
                    <property name="price" value="50"></property>
                    <property name="bookName" value="Spring5核心原理"></property>
                </bean>
                <!--ref引用-->
                <ref bean="book"></ref>
            </list>
        </property>
    </bean>
    

    首先在外面注册一个book的bean 赋于对应的值

    然后在list内部 通过ref引用外面注册的这个bean 即ref引用的book

    记得写法是 ref bean="book"

    PS: 内部写的bean是不需要name的
    你在beans下,也就是外面的bean是全局的 大家都可以用 你写name可以输出打印
    但是你在property下的bean是内部的,不可以被随便打印,所以不需要name


    Map类型赋值

    <property name="maps">
        <!--map = new LinkedHashMap()-->
        <map>
            <!--一个entry 就代表一个键值对-->
            <entry key="key01" value="张三"></entry>
            <entry key="key02" value="18"></entry>
            <entry key="key03" value-ref="book"></entry>
            <entry key="key04">
                <bean class="com.jiang.bean.Book">
                    <property name="bookName" value="SpringBoot实战开发"></property>
                </bean>
            </entry>
            <entry key="key05">
                <map></map>
            </entry>
        </map>
    </property>
    

    当你在property下,写一个map标签时,其实在底层就是给你new 了一个LinkedHaskMap()

    每个entry 都代表一个键值对

    • 第一种方式就是 <entry key="键名" value="值">
    • 第二种方式是 key键名不变,值通过value-ref引入外面的值
    • 第三种方式是 在entry标签内部,键名不变,值是通过bean标签重新注入
    • 第四种方式是在map里集成map.....用的不多 省略

    Properties

    <property name="properties">
        <!--props = new Properties() -->
        <props>
            <!--所有的key=value 都是String类型 所以值都写在标签体中-->
            <prop key="username" >root</prop>
            <prop key="password">123456</prop>
        </props>
    </property>
    

    当你在property下,写一个props标签时,其实在底层就是给你new 了一个Properties()

    所有的key=value 都是String类型 所以值都写在标签体中


    util方式的map引用

    1.引入util命名空间

    <?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-4.1.xsd
            http://www.springframework.org/schema/util
            http://www.springframework.org/schema/util/spring-util-4.1.xsd">
    

    2.在bean标签外创建util标签

        <util:map id="utilmap">
            <!--一个entry 就代表一个键值对-->
            <entry key="key01" value="王五"></entry>
            <entry key="key02" value="18"></entry>
            <entry key="key03" value-ref="book"></entry>
            <entry key="key04">
                <bean class="com.jiang.bean.Book">
                    <property name="bookName" value="SpringBoot实战开发"></property>
                </bean>
            </entry>
            <entry key="key05">
                <map></map>
            </entry>
    
        </util:map>
    

    Ps:我们这个util:map 是可以在全局进行访问的

    3.map通过ref引入

    <property name="maps" ref="utilmap"></property>
    

    级联属性赋值

    级联属性:属性的属性 比如Car.price

    <bean id="person03" class="com.jiang.bean.Person">
        <!-- 为car赋值的时候 我要改变price -->
        <property name="car" ref="carbean"></property>
        <!--我们可以通过car.price 进行单独的修改 -->
        <property name="car.price" value="150"></property>
        <!--但是此时就出现了问题,我们发现无论是ioc中的car还是person03中的car的price都进行了改变
            这是因为我们获取car的方式是引用,所以我们进行修改的时候,其实是修改的引用地址的那个price
            所以级联属性可以对属性的属性进行修改,但可能会改变原来的值
            -->
    </bean>
    
    • 我们可以通过car.price 进行单独的修改
    • 但是此时就出现了问题,我们发现无论是ioc中的car还是person03中的car的price都进行了改变
    • 这是因为我们获取car的方式是引用,所以我们进行修改的时候,其实是修改的引用地址的那个price
    • 所以级联属性可以对属性的属性进行修改,但可能会改变原来的值

    继承实现bean的复用

    <bean id="person01" class="com.jiang.bean.Person" abstract="true">
        <property name="lastName" value="马云"></property>
        <property name="age" value="50"></property>
        <property name="email" value="123456@alibaba.com"></property>
        <property name="gender" value="男"></property>
        
    </bean>
    

    此刻 我们希望有一个person02 他的属性值和person01相同

    <!--parent:指定当前bean的配置信息继承于那个-->
    <bean id="person02" class="com.jiang.bean.Person" parent="person01"></bean>
    

    我们就可以使用parent属性

    parent:指定当前bean的配置信息继承于那个

    如果我们只希望person01只允许被继承,不允许被获取实例怎么办?

    我们可以通过 abstrac=true来实现这个效果

    <bean id="person01" class="com.jiang.bean.Person" abstract="true">
        <property name="lastName" value="马云"></property>
        <property name="age" value="50"></property>
        <property name="email" value="123456@alibaba.com"></property>
        <property name="gender" value="男"></property>
    </bean>
    
  • 相关阅读:
    Spring MVC注解中@PathVariable和@RequestParam的区别
    Spring MVC请求流程
    eclipse-web项目目录结构
    数论基础------质数板
    线性DP基础--acwing---动态规划
    背包基础
    ----------动态规划分界线----------
    2020牛客暑期多校训练营(第三场)
    区间选点-贪心-acwing
    2020牛客暑期多校训练营(第二场)
  • 原文地址:https://www.cnblogs.com/pengcode/p/12501000.html
Copyright © 2011-2022 走看看