• 【spring框架 02】


    一、集合属性

    场景:对象的属性是集合类型的,那么就需要注入一个集合

    实现方式:在Spring中可以通过一组内置的XML标签来配置几个属性,例如:<list>,<set>或<map>

    1、list集合、set集合、数组属性赋值

    案例:

    1)创建一个PersonList类,有name和list<Car> 两个私有属性

    2)IOC容器给属性赋值

    <!--list集合、set集合、数组-->
        <bean id="personlist" class="com.wufq.spring.PersonList">
            <property name="name" value="韦小宝"></property>
            <property name="car">
                <!--构造集合-->
                <list>
                    <!--两中方式赋值:内部bean、ref-->
                    <ref bean="car"></ref>
                    <ref bean="car1"></ref>
                    <ref bean="car2"></ref>
                    
                    <!--数组对象有自己特有的标签,但是可以直接用list(建议用)-->
                    <!--<array></array>-->
                    <!--set集合可以直接用set标签-->
                    <!--<set></set>-->
    
                </list>
            </property>
        </bean>

    3)调用测试

      @Test
        public void testList(){
            PersonList list = context.getBean("personlist", PersonList.class);
            System.out.println(list);
    
        }
    =====执行结果====
    PersonList{name='韦小宝', car=[Car{brand='奔驰', crop='一汽', price='400000.0',speed='500'}, Car{brand='奥迪', crop='一汽', price='450000.0',speed='null'}, Car{brand='宝马', crop='华晨', price='0.0',speed='200'}]}

     2、map集合属性赋值

        <!--map集合-->
        <bean id="personMap" class="com.wufq.spring.PersonMap">
            <property name="name" value="小昭"></property>
            <property name="map">
                <!--构造map-->
                <map>
                    <entry key="AA" value-ref="car"></entry>
                    <entry key="BB" value-ref="car1"></entry>
                    <entry key="CC" value-ref="car2"></entry>
                </map>
            </property>
        </bean>

    注意点:给map集合属性的值赋值,用到<map></map>标签,map集合是无法直接取值的,所以需要转换成set集合,这时候就用到了entry,同样在map集合属性赋值也用到<entry>

    以及通过entry内部的key和value进行赋值

    3、集合类型的bean (主要解决没有可引用的bean)

    就是把集合设置成共有的,供其他所有的bean使用。

    -->前提:配置集合类型的bean需要引入util名称空间

    1)idea需要引入spring的命名空间(无法像eclipse一样勾选Namespaces),需要手动添加util的空间名称

    #在xml文件的首部添加
    xmlns:context="http://www.springframework.org/schema/context"
    然后我们打出:xmlns:util= 然后就会有相应的以提示,完整的内容如下: xmlns:util="http://www.springframework.org/schema/util"

    注意:xmlns:util  或者xmlns:p必须在xmlns:context="”这一行的下面打,否则也不会提示

    2)在xsi:schemaLocation=内补充

    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/util
    http://www.springframework.org/schema/util/spring-util-4.0.xsd

    注意:http://.../spring-context.xsd必须要写并且放在http://.../scontext下面,否则会报“无法找到元素context:component-scan”错

         http://.../spring-util-4.0.xsd必须要写并且放在http://.../util下面,否则会报“无法找到元素 'util:map' 的声明”错

    -->配置集合类型的bean

    <!--集合bean-->
        <util:map id="mapBean">
            <entry key="AA" value-ref="car"></entry>
            <entry key="BB" value-ref="car1"></entry>
            <entry key="CC" value-ref="car2"></entry>
        </util:map>
    
        <util:list id="listBean">
            <ref bean="car"></ref>
            <ref bean="car1"></ref>
            <ref bean="car2"></ref>
        </util:list>
    
    ========其他bean引用集合bean=========
    <bean id="personMap" class="com.wufq.spring.PersonMap">
            <property name="name" value="小昭"></property>
            <property name="map" ref="mapBean"></property>
        </bean>

    二、FactoryBean

    • spring中有两种类型的bean,一种是普通的bean(上面讲的那种)另外一种是工厂bean,即FactoryBean
    • 工厂bean跟普通bean不同,其返回的对象不是指定类的一个实例,其返回的是该工厂bean的getObject方法锁返回的对象
    • 工厂bean必须实现org,springframework.bean.factory.FactoryBean接口

    #案例:通过FactoryBean实现对Car类的属性赋值

    1)创建一个FactoryBeanTest类实现FactoryBean接口

    package com.wufq.factorySpring;
    
    import com.wufq.spring.Car;
    import org.springframework.beans.factory.FactoryBean;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**
     * @Author wufq
     * @Date 2021/4/8 15:39
     */
    public class FactoryBeanTest implements FactoryBean<Car> {
        /*
        * FactoryBean具体创建的bean对象是由getObject()方法来返回的
        * 当前案例:FactoryBean<T>接口内的类型是Car类型,所以需要返回Car类型的对象
        * */
    
        @Override
        public Car getObject() throws Exception {
            return new Car("扣扣","宝马",50000);
        }
    
        /*
        * 返回具体bean对象的类型
        * */
    
        @Override
        public Class<?> getObjectType() {
            return Car.class;
        }
    
        /*
        * bean可以是单例的,也可以是原型的(非单例)
        * */
    
        @Override
        public boolean isSingleton() {
            return false;
        }
    
    }

     2)创建spring的xml配置文件:factoryBean-di.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">
    
        <!--通过FactoryBean来配置
    
            FactoryBean具体返回的对象由getObject方法来决定
        -->
        <bean id="factoryBean" class="com.wufq.factorySpring.FactoryBeanTest"></bean>
    
    
    </beans>

    3)在FactoryBeanTest类内通过main测试

     public static void main(String[] args){
            ApplicationContext con = new ClassPathXmlApplicationContext("factoryBean-di.xml");
            Car car = con.getBean("factoryBean", Car.class);
            System.out.println(car);
        }
    
    =====执行结果=====
    Car{brand='扣扣', crop='宝马', price='50000.0',speed='null'}

    理解:普通bean是通过缺省构造器和构造方法来创建对象的,比较被动。而FactoryBean  创建的目的是Spring支持我们参与到bean对象的创建过程中,这样会灵活一些

     三、bean的高级配置

    1、bean和bean之间的继承关系(关键字:parent

    #案例 :实现address1继承address2的bean

    1)创建一个Address类,有city和Street(街道)两个属性

    2)创建spring的xml文件:spring-relation.xml

    <!--bean的继承关系-->
        <bean id="address1" class="com.wufq.relation.Address">
            <property name="city" value="beijing"></property>
            <property name="street" value="chaoyangjie"></property>
        </bean>
    
        <!--因为address2内class和city属性和address1一样,所以我们可以让address2继承address1来复用address1的class和city
    
            继承关键字:parent
        -->
        <bean id="address2" parent="address1">
            <property name="street" value="changanjie"></property>
        </bean>

    3)创建测试类AddressTest测试address2是否继承了address1的bean

    public class AddressTest {
    
        ApplicationContext context = null;
    
        @Before
        public void brf(){
            context=  new ClassPathXmlApplicationContext("spring-relation.xml");
        }
    
        @Test
        public void testAddress(){
            Address add1= context.getBean("address1",Address.class);
            System.out.println("Address1:"+add1);
    
            Address add2 = context.getBean("address2", Address.class);
            System.out.println("Address2:"+add2);
    
        }
    }
    
    ====执行结果====
    Address1:Address{city='beijing', street='chaoyangjie'}
    Address2:Address{city='beijing', street='changanjie'}
    由执行结果Address2可以看出来继承了Address1的

     2、bean也可以实现抽象(关键字abstract

    <!-- abstract="true":抽象bean 不能被创建对象,class可以忽略不写
    
            继承抽象的父bean可以继承一些配置,但是id,abstract,autowire是不能被继承的
    
            注意:由于抽象bean不能被创建对象,所以测试类的时候不能创建Address1的对象。Address add1= context.getBean("address1",Address.class);
        -->
        <bean id="address1" abstract="true"  >
            <property name="city" value="beijing"></property>
            <property name="street" value="chaoyangjie"></property>
        </bean>
    
        <!--因为address2内class和city属性和address1一样,所以我们可以让address2继承address1来复用address1的class和city
    
            继承关键字:parent
        -->
        <bean id="address2" class="com.wufq.relation.Address" parent="address1">
            <property name="street" value="changanjie"></property>
        </bean>

     3、bean之间的依赖关系(关键字:depends-on)

     创建一个bean的时候必须保证另外一个bean也被创建,这时候我们称前面的bean对后面的bean有依赖。

    <!--依赖关系-->
        <bean id="address3" class="com.wufq.relation.Address" parent="address1" depends-on="address4">
    
        </bean>
    
        <bean id="address4" class="com.wufq.relation.Address"></bean>

    “address3”依赖“address4”,如果没有创建address4时就会报错

    四、bean的作用域

    在<bean>中可以用scope关键字设置作用域,以决定这个bean是单例的还是多例的

    |-- singleton:单例的(默认值),在这个IOC容器中只能存在一个bean的对象而且在IOC容器对象被创建时,就创建单例的bean的对象,后续每次通过getBean()方法获取bean对象时,返回的都是同一个对象

    #案例演示:

    1)创建Car类,包含两个私有属性brand,prices。创建set、get方法,重写toString()方法,创建缺省构造器:内部打印“Ainit car....”

    2)创建spring的xml文件,设置作用域为:singleton(默认,可以不写)

     <bean id="car" class="com.wufq.Spring.scope.Car" scope="singleton">
            <property name="brand" value="奥迪"></property>
            <property name="prices" value="500000"></property>
    
        </bean>

    3)创建测试类测试

    public class CarTest {
    
        ApplicationContext context=null;
    
        @Before
        public void bef(){
            context = new ClassPathXmlApplicationContext("spring-scope.xml");
        }
      
      @Test
      public void testScope1(){}; //Ainit car.... //不获取bean对象,去执行同样会把缺省构造器内的此内容打印出来,说明在singleton模式下,在创建IOC容器时就已经创建了对象

    @Test
    public void testScope2(){ Car car1 = context.getBean("car", Car.class); Car car2 = context.getBean("car",Car.class); System.out.println(car1==car2); //true -->正常情况下new对象,每个对象都是不一样的,这里两个对象是true说明创建IOC容器的时候就值创建了一个对象,所以在两次获取bean对象都是同一个对象 } }

     |-- prototype:原型的/多例的。在整个IOC容器中可有多个bean的对象在IOC容器对象被创建时,不会创建原型的bean的对象,而是等到每次通过getBean()方法获取bean对象时,才会创建一个新的bean对象

    #案例演示:

    1)修改spring的xml文件,设置作用域为:prototype

    <bean id="car" class="com.wufq.Spring.scope.Car" scope="prototype">
            <property name="brand" value="奥迪"></property>
            <property name="prices" value="500000"></property>
    
        </bean>

    2)测试类测试

    public class CarTest {
    
        ApplicationContext context=null;
    
        @Before
        public void bef(){
            context = new ClassPathXmlApplicationContext("spring-scope.xml");
        }
    
        @Test
        public void testScope1(){
    
        } //没有结果-->说明只创建IOC容器不会创建对象
        @Test
        public void testScope2(){
            Car car1 = context.getBean("car", Car.class);
            Car car2 = context.getBean("car",Car.class);
    
            System.out.println(car1==car2); //true -->说明创建IOC容器的时候就值创建了一个对象,所以在两次获取bean对象都是同一个对象
        }
    /*
    打印结果:
    Ainit car...
    Ainit car...
    false
    说明只有获取getBean方法时才会创建对象,并且每获取一次就创建一个对象,并且创建的对象不一样
    */
    }
  • 相关阅读:
    服务器
    python的并发编程学习
    python的网络编程学习
    python的基础学习 模块
    pymysql基础操作
    查询简单练习
    数据准备
    数据库的三大设计范式
    数据库基础-建表约束
    mysql基础-基本语法
  • 原文地址:https://www.cnblogs.com/frankruby/p/14628905.html
Copyright © 2020-2023  润新知