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>
原文地址:https://www.cnblogs.com/ooooevan/p/5797796.html