zoukankan      html  css  js  c++  java
  • Spring基础学习(二)—详解Bean(上)

         在Spring配置文件中,用户不但可以将String、int等字面值注入Bean中,还可以将集合、Map等类型注入Bean中,此外还可以注入配置文件中其他定义的Bean。

    一、字面值

         (1)可用字符串表示的值,可以通过<value>元素标签或value属性进行注入。

         (2)基本数据类型及其封装类、Stting类型都可以采用字面值注入的方式。

         (3)若字面值包含特殊字符,可以使用<![CDATA[]]>把字面值包裹起来。

    <bean id="car" class="com.kiwi.domain.Car">
            <property name="brand" >
                <value><![CDATA[BMW&x5]]></value>
            </property>
            <property name="color" value="Black"/>
            <property name="price" value="800000"/>
            <property name="maxSpeed" value="200"/>
        </bean>

         由于brand属性包含了一个XML的特殊符号,因此特意在属性值外添加一个XML特殊处理标签<![CDATA[]]>,这个标签的作用就是让XML解析器将标签中的字符串当作普通文本对待,以防止某些字符对XML格式造成破坏。

    二、引用其他Bean

         (1)要使Bean能相互访问,就必须在Bean的配置文件中指定对Bean的引用。

         (2)在Bean的配置文件中,可以通过<ref>属性或元素配置。

         (3)也可以在属性内部包含Bean的声明,这样的Bean称为内部Bean。

         (4)内部Bean不能被外部使用。

    Person.java

    public class Person{
    
    	private String name;
    	private int age;
    	private Car car;
    
    	@Override
    	public String toString(){
    		return "Person [name=" + name + ", age=" + age + ", car=" + car + "]";
    	}
    
    	//省略get set...
    }

    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="car" class="com.kiwi.domain.Car">
            <property name="brand" value="BMW"/>
            <property name="color" value="Black"/>
            <property name="price" value="800000"/>
            <property name="maxSpeed" value="200"/>
        </bean>
        
        <bean id="person" class="com.kiwi.domain.Person">
            <property name="name" value="Tom"/>
            <property name="age" value="26"/>
            
            <!-- 使用ref属性建立bean之间的引用关系 -->
            <property name="car" ref="car"/>
            
        </bean>
            
    </beans>

    Test.java

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

    结果:

         Person [name=Tom, age=26, car=Car [brand=BMW, color=Black, price=800000.0, maxSpeed=200]]

         如果不引用外部的Bean,可以在内部声明一个内部Bean,这个内部Bean不能被其他外部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="car" class="com.kiwi.domain.Car">
            <property name="brand" value="BMW" />
            <property name="color" value="Black" />
            <property name="price" value="800000" />
            <property name="maxSpeed" value="200" />
        </bean>
    
        <bean id="person" class="com.kiwi.domain.Person">
            <property name="name" value="Tom" />
            <property name="age" value="26" />
    
            <!-- 定义一个内部bean,内部bean外面不能引用 -->
            <property name="car">
                <bean class="com.kiwi.domain.Car">
                    <property name="brand" value="Audi" />
                    <property name="color" value="Black" />
                    <property name="price" value="300000" />
                    <property name="maxSpeed" value="250" />
                </bean>
            </property>
    
        </bean>
    
    </beans>

    结果:

         Person [name=Tom, age=26, car=Car [brand=Audi, color=Black, price=300000.0, maxSpeed=250]]

        也可以为级联属性赋值。

    <?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="car" class="com.kiwi.domain.Car">
            <property name="brand" value="BMW" />
            <property name="color" value="Black" />
            <property name="price" value="800000" />
            <property name="maxSpeed" value="200" />
        </bean>
    
        <bean id="person" class="com.kiwi.domain.Person">
            <property name="name" value="Tom" />
            <property name="age" value="26" />
            <property name="car" ref="car"/>
            <!-- 为级联属性赋值,前提是属性先初始化然后才可以为其级联属性赋值 -->
            <property name="car.maxSpeed" value="250"/>
    
        </bean>
    
    </beans>

    结果:

         Person [name=Tom, age=26, car=Car [brand=BMW, color=Black, price=800000.0, maxSpeed=250]]

    三、集合属性

    1.List和Set

    (1)配置List需要指定<list>标签,标签里包含一些元素,这些元素可以通过<value>指定简单的常量值,也可以使用<ref>指定对其他Bean的引用。

    (2)配置set需要使用<set>标签,其他属性和List一样。

    Person.java

    public class Person{
    
    	private String name;
    	private int age;
    	private List<Car> cars;
    	
    	//省略get set...
    }

    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="car" class="com.kiwi.domain.Car">
            <property name="brand" value="BMW" />
            <property name="color" value="Black" />
            <property name="price" value="800000" />
            <property name="maxSpeed" value="300" />
        </bean>
        
        <bean id="car2" class="com.kiwi.domain.Car">
            <property name="brand" value="Audi" />
            <property name="color" value="Black" />
            <property name="price" value="400000" />
            <property name="maxSpeed" value="250" />
        </bean>
    
        <bean id="person" class="com.kiwi.domain.Person">
            <property name="name" value="Tom" />
            <property name="age" value="26" />
            <!-- 配置集合属性List -->
            <property name="cars">
            
                <list>
                    <ref bean="car"/>
                    <ref bean="car2"/>
                </list>
                
            </property>
        </bean>
    
    </beans>

    结果:

          Person [name=Tom, age=26, cars=[Car [brand=BMW, color=Black, price=800000.0, maxSpeed=300], Car [brand=Audi, color=Black, price=400000.0, maxSpeed=250]]]

    2.Map

    (1)通过<map>标签定义,子标签使用<entry>标签。

    (2)在<entry>标签里可以使用key、key-ref、value、value-ref属性。

    Person.java

    public class Person{
    
    	private String name;
    	private int age;
    
    	private Map<String,Car> cars;
    
    	//省略get set...
    }

    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="car" class="com.kiwi.domain.Car">
            <property name="brand" value="BMW" />
            <property name="color" value="Black" />
            <property name="price" value="800000" />
            <property name="maxSpeed" value="300" />
        </bean>
        
        <bean id="car2" class="com.kiwi.domain.Car">
            <property name="brand" value="Audi" />
            <property name="color" value="Black" />
            <property name="price" value="400000" />
            <property name="maxSpeed" value="250" />
        </bean>
    
        <bean id="person" class="com.kiwi.domain.Person">
            <property name="name" value="Tom" />
            <property name="age" value="26" />
            
            <!-- 配置集合属性Map -->
            <property name="cars">
                <map>
                    <entry key="1" value-ref="car"/>
                    <entry key="2" value-ref="car2"/>
                </map>
            </property>
        </bean>
    
    </beans>

    结果:

          Person [name=Tom, age=26, cars={1=Car [brand=BMW, color=Black, price=800000.0, maxSpeed=300], 2=Car [brand=Audi, color=Black, price=400000.0, maxSpeed=250]}]

    3.Properties

        Properties类型可以看作Map类型的特例,Map元素的键和值可以是任何类型的对象,而Properties的键和值只能是字符串。

    Boss.java

    public class Boss{
    
    	private Properties mails;
    
    	@Override
    	public String toString(){
    		return "Boss [mails=" + mails + "]";
    	}
    
    	public Properties getMails(){
    		return mails;
    	}
    
    	public void setMails(Properties mails){
    		this.mails = mails;
    	}
    }
    applicationContext.xml
    <bean name="boss" class="com.kiwi.domain.Boss">
            <property name="mails">
                <props>
                    <prop key="jobMail">123@126.com</prop>
                    <prop key="lifeMail">789@qq.com</prop>
                </props>
            </property>
        </bean>

    结果:

          Boss [mails={lifeMail=789@qq.com, jobMail=123@126.com}]

    4.配置集合类型的Bean

    (1)使用基本集合标签定义集合时,不能将集合作为独立的Bean定义,导致其他Bean无法引用该集合,所以无法在不同Bean直接共享集合。

    (2)如果希望配置一个集合类型的Bean,而非一个集合类型的属性,则可以通过util命名空间进行配置。

    (3)必须先引用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.xsd
                            http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
    
    
        <bean id="car" class="com.kiwi.domain.Car">
            <property name="brand" value="BMW" />
            <property name="color" value="Black" />
            <property name="price" value="800000" />
            <property name="maxSpeed" value="300" />
        </bean>
        
        <bean id="car2" class="com.kiwi.domain.Car">
            <property name="brand" value="Audi" />
            <property name="color" value="Black" />
            <property name="price" value="400000" />
            <property name="maxSpeed" value="250" />
        </bean>
        
        <!-- 定义一个公共的Map其他Bean能够直接引用它 -->
        <util:map id="cars">
            <entry key="1" value-ref="car"/>
            <entry key="2" value-ref="car2"/>
        </util:map>
    
        <bean id="person" class="com.kiwi.domain.Person">
            <property name="name" value="Tom" />
            <property name="age" value="26" />
            <!-- 引用公共的Map -->
            <property name="cars" ref="cars"/>
        </bean>
        
    </beans>

    四、使用p命名空间

         为了简化XML文件的配置,越来越多的XML文件采用属性而非子元素配置信息。    

    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"
        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="car" class="com.kiwi.domain.Car" 
                       p:brand="AuDi" p:color="Silver" 
                       p:price="500000" p:maxSpeed="3000"/>
                       
        <bean id="person" class="com.kiwi.domain.Person" 
              p:name="Tom" p:age="27"  p:car-ref="car"/>
        
    </beans>

         这样写省略了<property>的子标签,使配置文件更加简洁。

    五、自动装配

         <bean>元素提供了一个指定自动装配类型的属性:atuowire。Spring提供了4种自动装配类型。

         image

    Person.java

    public class Person{
    
    	private String name;
    	private Car car;
    	private Address address;
    	
    	//...
    }

    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"
        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="car" class="com.kiwi.domain.Car"
              p:brand="LandRover" 
              p:price="1200000"    
            />
            
            
        <bean id="address" class="com.kiwi.domain.Address"
              p:province="BJ"
              p:city="CangPing"    
            />    
        
        <!-- 
            可以使用autowire属性指定自动装配的方式 。
            byName: 根据名称自动装配,必须将目标bean的名称和属性名设置的完全相同。
            byType: 根据类型自动装配,若IOC容器中有多个与目标 bean类型一致的 bean, 
                    在这种情况下,Spring 将无法判定哪个bean最合适该属性,所以不能执行自动装配。
        -->
        <bean id="person" class="com.kiwi.domain.Person"
              p:name="Tom"
              autowire="byName"
        />        
        
    </beans>

    结果:

         Person [name=Tom, car=Car [brand=LandRover, price=1200000.0], address=Address [province=BJ, city=CangPing]]

         一般情况下,在实际的项目中很少使用自动装配功能,因为和自动装配功能所带来的好处比起来,明确清晰的配置文档更有说服力一些。

    六、Bean之间的关系

         Bean直接存在两种关系: 继承、依赖。

    1.继承

    (1)Spring允许继承bean的配置,被继承的bean称为父bean。

    (2)子bean从父bean继承配置,包括属性配置,也可以覆盖父bean的配置。

    (3)若只想把父bean作为模板,可以设置其属性abstract属性为true,这样Spring将不会实例化这个bean。

    (4)并不是<bean>所有的属性都会被继承,比如:autowire、abstract。

    applicationContext.xml

    <bean id="address" class="com.kiwi.domain.Address"
              p:province="BJ"
              p:city="CangPingQu"    
            />
                
        <bean id="address2" parent="address"
              p:city="HaiDianQu"    
            />

    结果:

          Address [province=BJ, city=CangPingQu]
          Address [province=BJ, city=HaiDianQu]

    2.依赖

         depend-on: 表示一个bean的实例化依靠另一个bean先实例化。如果在一个bean A上定义了depend-on B那么就表示:A 实例化前先实例化 B。这种情况下,A可能根本不需要持有一个B对象。

    七、Bean的作用域

    (1)在Spring中,可以在<bean>元素的scope属性设置Bean的作用域。

    (2)默认情况下,Spring只为每个IOC容器里声明Bean创建唯一的一个实例,整个IOC容器都能共享该实例,该作用域为默认的singleton。

              image

    applicationContext.xml

    <!-- 
            使用bean的scope属性来配置bean的作用域
            singleton: 默认值。容器初始化时创建bean实例,在整个容器生命周期内只创建这一个bean,单例的。
            prototype: 容器初始化时不创建bean的实例,而在每次getBean()时都创建一个实例。
         -->
        <bean id="car" class="com.kiwi.domain.Car"
              p:brand="LandRover" 
              p:price="1200000"    
              scope="singleton"
            />
    Test.java
    	@Test
    	public void testCar(){
    		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    		Car car = (Car)context.getBean("car");
    		Car car2 = (Car)context.getBean("car");
    		System.out.println(car == car2);
    	}

    结果:

          true

         如果修改为scope="prototype",结果将返回false。

  • 相关阅读:
    codeforces C. Cows and Sequence 解题报告
    codeforces A. Point on Spiral 解题报告
    codeforces C. New Year Ratings Change 解题报告
    codeforces A. Fox and Box Accumulation 解题报告
    codeforces B. Multitasking 解题报告
    git命令使用
    shell简单使用
    知识束缚
    php 调用系统命令
    数据传输方式(前端与后台 ,后台与后台)
  • 原文地址:https://www.cnblogs.com/yangang2013/p/5553624.html
Copyright © 2011-2022 走看看