• Spring学习记录(二)---容器和bean属性配置


    下载spring包,在eclipse搭建spring环境。

    这步我在eclipse中无法导入包,看网上的:

    http://sishuok.(和谐)com/forum/blogPost/list/2428.html

    建一个java project

    三个java文件,一个xml文件

     1 package com.guigu.spring.beans;
     2 
     3 public class HelloWord {
     4     private String name;
     5     public String getName() {
     6         return name;
     7     }
     8     public void setName(String name) {
     9         this.name = name;
    10     }
    11     public  void hello(){
    12         System.out.println("hello: "+name);
    13     }
    14 }
     1 import java.applet.AppletContext;
     2 
     3 import org.springframework.context.ApplicationContext;
     4 import org.springframework.context.support.AbstractApplicationContext;
     5 import org.springframework.context.support.ClassPathXmlApplicationContext;
     6 
     7 
     8 public class Main {
     9     public static void main(String[] args) {
    10 //  传统调用方式
    11 //        HelloWord h = new HelloWord();
    12 //        h.setName("evan");
    13 //        h.hello();
    14         //1、读取配置文件实例化一个IoC容器  ,会动态创建对象,调用构造函数,xml中有属性还会调用setname()
    15         ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");  
    16         //2、从容器中的id获取Bean,注意此处完全“面向接口编程,而不是面向实现”  
    17          HelloWord hello = (HelloWord) context.getBean("helloword");  
    18          //3、执行业务逻辑  
    19          hello.hello();  
    20     }
    21 
    22 }
     1 <?xml version="1.0" encoding="UTF-8"?>  
     2 <beans  
     3 xmlns="http://www.springframework.org/schema/beans"  
     4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
     5 xmlns:context="http://www.springframework.org/schema/context"  
     6 xsi:schemaLocation="  
     7 http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
     8 http://www.springframework.org/schema/context                http://www.springframework.org/schema/context/spring-context-3.0.xsd">  
     9   <!-- id 表示你这个组件的名字,class表示组件类 -->  
    10   <bean id="helloword" class="com.guigu.spring.beans.HelloWord">
    11         <property name="name" value="Spring"></property>
    12     </bean>
    13</
    beans>

     helloword是一个id标识,它属于com.guigu.spring.beans.HelloWord类,是它的一个实例。一个类可以有多个实例。所以可以有多个bean的类相同,表示一个类的不同实例。

     bean中可以添加属性,用property属性

    IoC容器

    用的是ApplicationContext(应用上下文),它是由BeanFactory(Bean工厂)扩展而来,BeanFactory提供了IoC容器最基本功能如: getBean();

    ApplicationContext扩展了BeanFactory,还提供了与Spring AOP集成、国际化处理、事件传播及提供不同层次的context实现。

    【  ApplicationContext 的初始化和BeanFactory 有一个重大的区别:BeanFactory在初始化容器时,并未实例化Bean,直到第一次访问某个Bean 时才实例目标Bean,即调用getBean才初始化;而ApplicationContext 则在初始化应用上下文时就实例化所有单实例的Bean 。】

    (了解更多去大牛博客:http://elf8848.iteye.com/blog/324796)

     ApplicationContext的实现有两个:

     • ClassPathXmlApplicationContext从类路径获取配置文件。

     ApplicationContext context = new ClassPathXmlApplicationContext("application.xml") 

    • FileSystemXmlApplicationContext从文件系统获取配置文件。

    ApplicationContext context = new FileSystemXmlApplicationContext("c:/application.xml");  

     ApplicationContext获取bean的方法:

    1、通过id获取容器中的bean 

    1 ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");  
    2 HelloWord hello = (HelloWord) context.getBean("helloword");  

    2、通过类类型获取。但是只能在HelloWord类只有一个bean对象才行,不然就不知道到底获取哪一个而报错

    1  ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");  
    2  HelloWord hello = context.getBean(HelloWord.class);  //不用类型强转,因为已经知道返回类型了

    IOC容器注入依赖资源,三种注入方式:

    1、属性注入(最常用)

    2、构造器注入

    3、工厂方法注入(很少用,不推荐)

    属性注入:通过setter方法注入;使用<property>,使name属性指定bean的属性名称

     <property name="name" value="Spring"></property>

     表示bean所在类有一个name属性,值是Spring

    构造器注入 

    用bean里的constructor-arg属性

    例子--新建一个Car类

     1 public class Car{
     2     private String brand;
     3     private String corp;
     4     private double price;
     5     private int maxSpeed;
     6 }
     7   public Car(String brand,String corp,double price){
     8     super();
     9     this.brand=brand;
    10     this.corp=corp;
    11     this.price=price;
    12 }

    xml中添加,index表示对应的属性,若不写,默认按顺序匹配

    1 <bean id="car" class="com.guigu.spring.beans.Car">
    2      <constructor-arg value="aodi" index="0"></constructor-arg>
    3      <constructor-arg value="ShangHai" index="1"></constructor-arg>
    4      <constructor-arg value="300000" index="2"></constructor-arg>
    5  </bean>

    main函数中

    1   ApplicationContext ctx= new ClassPathXmlApplicationContext("application.xml");  
    2   HelloWord car=ctx.getBean(Car.class);  
    3   system.out.println(car); //调用Car中的toString函数,已省略

    输出结果:Car [brand=aodi, corp=ShangHai, price=300000, maxSpeed=0];

    若构造函数是多个呢?重载的构造函数,xml中对应哪一个呢?

     1 public class Car{
     2       private String brand;
     3       private String corp;
     4       private double price;
     5       private int maxSpeed;
     6   }
     7     public Car(String brand,String corp,double price){
     8       super();
     9       this.brand=brand;
    10      this.corp=corp;
    11      this.price=price;
    12  }
    13      public Car(String brand,String corp,int maxSpeed){
    14       super();
    15       this.brand=brand;
    16      this.corp=corp;
    17      this.maxSpeed=maxSpeed;
    18  }
    1  <bean id="car2" class="com.guigu.spring.beans.Car">
    2       <constructor-arg value="aodi" type="java.lang.String"></constructor-arg>   //除基本类型外,其余都要写全类名
    3       <constructor-arg value="ShangHai" type="java.lang.String"></constructor-arg>
    4       <constructor-arg value="240" type="int"></constructor-arg>   //基本类型,不用谢全类名
    5   </bean>
    1    ApplicationContext ctx= new ClassPathXmlApplicationContext("application.xml");  
    2    HelloWord car=ctx.getBean("car");  
    3    system.out.println(car); 
    4    HelloWord car=ctx.getBean("car2");  
    5    system.out.println(car); 

    输出结果:

    Car [brand=aodi, corp=ShangHai, price=300000.0, maxSpeed=0];

    Car [brand=aodi, corp=ShangHai, price=0.0, maxSpeed=240];

    总结:通过构造器方法时,可以用参数的位置和参数的类型来区分重载构造函数,位置和参数是可以同时使用,如下

    1  <bean id="car" class="com.guigu.spring.beans.Car">
    2        <constructor-arg value="aodi" index="0"></constructor-arg>
    3        <constructor-arg value="ShangHai" index="1"></constructor-arg>
    4        <constructor-arg value="240" type="int"></constructor-arg>
    5    </bean>

    细节1:value用节点表示

    1   <bean id="car" class="com.guigu.spring.beans.Car">
    2         <constructor-arg value="aodi" index="0"></constructor-arg>
    3         <constructor-arg value="ShangHai" index="1"></constructor-arg>
    4         <constructor-arg  type="int">
    5             <value>240</value>
    6         </constructor-arg>
    7     </bean>                

     这个可以解决value是特殊字符的问题 如:<ShangHai> ,直接字面写就报错,用value节点再结合<![CDATA[]]解决

    1    <bean id="car" class="com.guigu.spring.beans.Car">
    2           <constructor-arg value="aodi" index="0"></constructor-arg>
    3           <constructor-arg index="1">
    4               <value><![CDATA[<ShangHai>]]></value>  // 值是:<ShangHai>
    5           </constructor-arg>
    6           <constructor-arg value="240" type="int">
    7           </constructor-arg>
    8       </bean>          

    细节2:属性是引用类型 ref元素或ref属性

    若又一个Person类,有一个Car属性,Car就是前面的对象

     1   public class Person{
     2         private String name;
     3         private Car car;
     4     }
     5     
     6     public  void setName(String name){
     7             this.name=name;
     8     }
     9     public getName(){
    10             return name;
    11     }
    12     public  void setCar(Carcar){
    13             this.car=car;
    14     }
    15     public getCar(){
    16             return car;
    17     }
    18 
    19   }

    用ref="car2" 指向之前的car2对象,来引用;同样可以改成节点式<ref bean="car2"/>

    1  <bean id="person" class="com.guigu.spring.beans.Person">
    2         <property name="name" value="Tom"></proerty>
    3         <property name="car" ref="car2"></proerty>
    4     </bean>              

    细节3:内部bean,达到和引用的目的。但这个bean不能被外部引用,只能自己内部使用

     1   <bean id="person" class="com.guigu.spring.beans.Person">
     2          <property name="name" value="Tom"></proerty>
     3          <property name="car">
     4                 <bean class="com.guigu.spring.beans.Car">
     5                     <constructor-arg value="Ford"></constructor-arg>
     6                     <constructor-arg value="ChangAn"></constructor-arg>
     7                     <constructor-arg value="200000" type="double"></constructor-arg>
     8                 </bean>
     9          </proerty>
    10      </bean>           

    细节4:赋空值: <null/>;或者,直接不写就行。

     1  <bean id="person" class="com.guigu.spring.beans.Person">
     2            <property name="name" value="Tom"></proerty>
     3            <property name="car">
     4                   <bean class="com.guigu.spring.beans.Car">
     5                       <constructor-arg value="Ford"></constructor-arg>
     6                       <constructor-arg value="ChangAn"></constructor-arg>
     7                       <constructor-arg><null/></constructor-arg>
     8                   </bean>
     9            </proerty>
    10       </bean>        

    细节5:像struts一样,可以为级联属性赋值。它调用了改属性的set方法,所以类中必须要有改属性的set方法。

    1   <bean id="person" class="com.guigu.spring.beans.Person">
    2          <constructor-arg
    name
    ="name" value="Tom"></constructor-arg> 3 <constructor-arg name="car" ref="car2"> 4 <property name="car.maxSpeed" value="230"></property> //  5 </constructor-arg> 6 </bean>

      注意:和struts不同,不能不初始化直接赋值

     1     <bean id="person" class="com.guigu.spring.beans.Person">
     2            <property name="name" value="Tom"></proerty>
     3            <!--
     4            <property name="car">
     5                   <bean class="com.guigu.spring.beans.Car">
     6                       <constructor-arg value="Ford"></constructor-arg>
     7                       <constructor-arg value="ChangAn"></constructor-arg>
     8                       <constructor-arg value="200000" type="double"></constructor-arg>
     9                   </bean>
    10            </proerty>
    11            -->
    12            <property name="car.maxSpeed" value="260"></property>
    13       </bean>           

    这里的意思是,不创建car对象,直接对它的属性赋值。

    在struts中可以,会自动先创建一个car对象,然后赋值。二spring不可以,必须先初始化一个对象,再赋值。

    细节6:集合属性赋值

    一个person可以有多个car,怎么表示?  如下,用节点<list>  。数组list和Set与集合类似。也可以用内部bean

     1     public class Person{
     2           private String name;
     3           private List<Car> cars;
     4       }
     5       
     6       public  void setName(String name){
     7               this.name=name;
     8       }
     9       public getName(){
    10              return name;
    11      }
    12      public  void setCar(List<Car> cars){
    13              this.cars=cars;
    14      }
    15      public List<Car> getCars(){
    16              return cars;
    17      }
    18  
    19    }
    1    <bean id="person1" class="com.guigu.spring.beans.Person">
    2           <constructor-arg name="name" value="Tom"></constructor-arg>
    3           <property name="car">
    4                  <list>
    5                       <ref bean="car1"/>
    6                       <ref bean="car2"/>
    7                  </list>
    8           </property >
    9       </bean>   

    注意:集合中Map又不一样,因为它是键值对,用<map>、entry

     1 public class NewPerson{
     2     private String name;
     3     private Map<String, Car> cars;
     4 
     5     public String getName(){
     6         return name;
     7     }    
     8     public void setName(){
     9         this.name=name;
    10     }   
    11     public Map<String, Car> getCars(){
    12         return cars;
    13     }
    14     public void setCars(Map<String, Car> cars)    {
    15     this.cars=cars;
    16 }
    1     <bean id="newPerson" class="com.guigu.spring.beans.Person">
    2            <property name="name" value="evan"></property >
    3            <property name="cars">
    4                   <map>
    5                        <entry key="AA" value-ref="car"/>
    6                        <entry key="BB" value-ref="car2"/> 
    7                    </map>
    8            </property >
    9        </bean>   

    细节7:配置properties 。 一个DataSource类,xml配置properties。如连接数据库

    1 public class DataSource{
    2      private Properties properties;
    3      public Properties getProperties(){
    4        return properties; 
    5 }
    6      public void setProperties(Properties properties){
    7             this.properties = properties;
    8 }
    1 <bean id="dataSource" class="com.guigu.spring.beans.DataSource">
    2     <property name="properties">
    3          <props>
    4                <prop key="user">root<prop>
    5                <prop key="password">1234<prop>
    6                <prop key="jdbcUrl">jdbc:mysql://test<prop>
    7          </prop>
    8     <properties>
    9 </bean>
    1 DataSource datasource = ctx.getBean(DataSource.class);
    2 System.out.print(datasource.getProperties);

    输出:

    {user=root, password=1234, jdbcUrl=jdbc://test}

    细节8:上面集合的配置,如果多个对象要使用,怎么提高内部属性的利用率<props>、<map>。用一个util命名空间

    //单独拿出来,可以供多个bean调用
    <util:list id="cars">
      <ref bean="car"/>
      <ref bean="car2"/>
    </util:list>
    //引用
    <bean id="person3" class="com.guigu.spring.beans.Person">
        <property name="name" value="jack"></property >
        <property name="cars" ref="cars"></property >
    </bean>
  • 相关阅读:
    高阶函数
    Vue-cli 3.0 搭建,以及vuex、axios、使用
    Git --- 基本操作以及Git 特殊命令,公司常用命令
    Git 剖析,以及Git相关操作
    git ssh key 生成
    React.Fragment 组件没有必要的多层嵌套,外层不需要过多嵌套
    spring cloud连载第三篇之Spring Cloud Netflix
    spring cloud连载第二篇之Spring Cloud Config
    AbstractQueuedSynchronizer
    Timer定时器
  • 原文地址:https://www.cnblogs.com/ooooevan/p/5797796.html
Copyright © 2020-2023  润新知