1. 程式人生 > >Spring 2:IOC

Spring 2:IOC

※ 1. Spring IOC(must):※ IOC:Inversion of Control 控制反轉        一種說法:物件之間的依賴關係,由容器在執行時依據配置檔案動態的建立        另一種說法:物件的控制器轉移了,轉到外部容器了,避免了程式碼的糾纏,程式碼更        容易被維護,模板之間的耦合性降低,容易測試 IoC 控制反轉意味著將你設計好的類交給容器去控制,而不是在類的內部進行控制,即控制權由 應用程式碼中轉到了外部容器    IoC:包括兩部分內容   ※ DI:Dependency Injection依賴注入

元件不做定位查詢,只提供相應方法,由容器建立物件,並呼叫相應方法設定所需物件需要的元件

第三方(Spring)
2.你需要什麼(將需要的寫成全域性變數)
3.怎麼放入(給全域性變數賦值:1.set方法,2.構造器)

1.程式自身
    我是誰(告訴Spring:全包名+類名)

xml

<bean class=“com.briup.UserService”>//指明service
  <property name=“dao” ref=“da”/>//需要dao
</bean>
<bean name=“da” class=“com.briup.UserDao”>//指明dao

注意:servlet是由Tomcat構建的,不能通過這種方式指明(框架的整合,有servlet與service結合的jar包)(寫註解方式)

   ※ (不要求)DL:Dependency Lookup依賴查詢

容器建立物件並提供回撥介面和上下文環境給元件,需要時通過介面從容器中查詢物件     依賴查詢,現在使用不太多。(EJB使用的更多,將物件建立好後,放到容器中。)

Spring IOC:依賴查詢(主動的找)


高內聚,低耦合
解決依賴問題:(建立工廠)

public calss BeanFactory{
   static final String SERVICE="service";
   static final String DAO="dao";
   public static Object getBean(String msg){
      if(msg=="service"){
        new  Service();
      }else{
        new Dao();
      }
   }
}


呼叫時不再new物件

Class RegisterSer{

doGet(){
String name=Request.getParameter(“name”)
String passwd=Request.getParameter(“passwd”)
…
 UserService ser=BeanFactory.getBean(BeanFactory.SERVICE);
ser.register(name,passwd…);
    }
}

//service層
Class UserService{
public void register(String name,String passwd…){
…
UserDao dao=BeanFactory.getBean(BeanFactory.DAO);
dao.saveUser(name,passwd…);
     } 
}

//dao層
Class UserDao{
saveUser(String name,String passwd…);

}


構建配置檔案(pro.properties) 維護全包名類名
方法一:靜態程式碼塊
dao=com.briup.Dao.UserDao
service=com.briup.Service.UserService


public calss BeanFactory{
   static final String SERVICE="service";
   static final String DAO="dao";
   
   static Properties pro=null;
   static {
       pro=new Properties();
       pro.load(new FileNputStream(new File("pro.perties")));
   }
   public static Object getBean(String msg){
      if(msg=="service"){
        Class.forName(pro.getProgerty("service")).newInstance();
      }else{
        Class.forName(pro.getProgerty("dao")).newInstance();
      }
   }
}


方法二:靜態方法
public calss BeanFactory{
   static final String SERVICE="service";
   static final String DAO="dao";

   public static Properties getPro(){
       if(pro==null){
         pro=new Properties();
         pro.load(new FileNputStream(new File("pro.perties")));
        }
       return pro;
   }
   public static Object getBean(String msg){
      getPro();
      if(msg=="service"){
         Class.forName(pro.getProgerty("service")).newInstance();
      }else{
         Class.forName(pro.getProgerty("dao")).newInstance();
      } 
   }
}


更改dao和service時,只用更改properties檔案中的value(全包名)值。

    IOC解決:物件誰來建立的問題     DI解決:物件間的關係如何建立的問題。  org.springframework.beans及org.springframework.context包是IOC容器的基礎 =================================================※ 2. SpringIOC核心API - BeanFactory介面和容器    BeanFactory是Spring中Bean容器,IoC的核心介面,主要用於處理Bean的初始化和配置,    建立物件間的依賴關係    定義瞭如下方法:   

   Object getBean(String name) //根據指定名稱返回一個Bean例項

   <T> T getBean(Class<T> requiredType)  
                              //返回一個與給定Class唯一匹配的Bean例項

   <T> T getBean(String name, Class<T> requiredType)

   Object getBean(String name, Object... args)

   Class<?> getType(String name)       //得到名稱為name的Bean的Class物件
   
   boolean isPrototype(String name)   //判斷名稱為name的Bean是否是原型,
                                          即是否總是返回一個新例項
   boolean isSingleton(String name)   //判斷名稱為name的Bean是否是單例

   boolean containsBean(String name)  //判斷是否包含給定名稱的Bean例項

   boolean isTypeMatch(String name, Class<?> targetType)
                         //判斷名稱為name的Bean例項是否為targetType型別
   String[] getAliases(String name)  //如果名稱為name的Bean有別名返回
   

   通過getBean方法便可以得到相應的類例項,但是最好永遠不呼叫,而使用注入,    避免對Spring API的依賴        在Spring中,同一Spring容器中的bean預設情況下是Singleton(單例),將在bean    的作用域介紹.

ApplicationContext介面    該介面繼承於BeanFactory,增強了BeanFactory,提供了事務處理AOP,國際化,事件傳遞

1.介面型Dao,Service
bean包:

package com.briup.bean;

public class UserDao {

}

package com.briup.bean;

public class UserService {
 private UserDao dao;
public UserService() {
	System.err.println("-------");
}
 public UserService(UserDao dao) {
	 this.dao=dao;
 }
public UserDao getDao() {
	return dao;
}

public void setDao(UserDao dao) {
	this.dao = dao;
}
 
}

IOC包:

<?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讓Spring構建物件
       name指的是構建物件的名字
       class指向構建物件的全限定名
       us=Class.forName("com.briup.bean.UserService").newInstance();
       
       scope屬性:控制的是物件建立的是不是單例物件 
          prototype 原型別(非單例)
          singleton 預設單例-->
     <bean name="us" class="com.briup.bean.UserService"
     scope="prototype">
       <!-- property決定給當前物件設定屬性的方式採用set拼接name屬性setDao() 
            引數是基本資料型別value屬性指明,
            物件用ref指明-->
       <property name="dao" ref="ud"></property>
     </bean>
     <bean name="ud" class="com.briup.bean.UserDao"></bean>
  </beans>

測試類:


 @Test
 public void ioc_test() {
	 try {
		//啟動Spring容器,載入配置檔案,構建物件
		 ClassPathXmlApplicationContext cp=
				 new ClassPathXmlApplicationContext("com/briup/IOC/ioc.xml");
		 //getBean()方法從容器中獲取物件
		 //預設情況下Spring構建的都是單例物件
		 UserService ser=(UserService) cp.getBean("us");
		 UserService ser1=cp.getBean(UserService.class);
		 UserService ser2=cp.getBean("us",UserService.class);
		 System.out.println(ser);
		 //isPrototype判斷Spring容器中物件是不是原型別
		 System.out.println(cp.isPrototype("us"));//true
		 System.out.println(cp.isPrototype("ud"));//false
		 //isSingleton判斷Spring容器中物件是不是單例物件
		 System.out.println(cp.isSingleton("us"));//false
		 System.out.println(ser.getDao());
		 System.out.println(cp.getBean("ud"));
		 //System.out.println(ser1);
		 //System.out.println(ser2);
	} catch (BeansException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
 }

=================================================※ 3. 配置檔案 配置Spring通過讀取配置元資料來對應用中各個物件進行例項化,配置以及組裝,通常使用 XML檔案來作為配置元資料的描述格式    可以將XML配置分別寫在多個檔案中   可以將多個配置放在一個String陣列中傳遞給容器進行初始化      

   eg: ApplicationContext ac = new ClassPathXmlApplicationContext(
            new String[]{"services.xml","daos.xml"})
   也可以在XML中使用<import resource="" />來進行匯入

   XML基本結構如下:
   <?xml version="1.0" encoding="UTF-8"?>
   <beans xmlns=".....">
      <bean id=".." class="..." >
         <property name="..." ... />
      </bean>
      ...
   </beans>

容器的初始化和ClassPathXmlApplicationContext    ClassPathXmlApplication實現ApplicationContext,用於讀取Xml初始化上下文,初始化方法如下:       ApplicationContext ac = new ClassPathXmlApplicationContext(".../path/beans.xml");    與Hibernate類似,不同的是Spring沒有預設的配置檔案

=================================================※ ※ 4.  IOC注入(需要,第三方容器給你)1)setter方式(必須依靠無參構造器)       A、基本型別(8中基本型別+字串)的裝配       B、物件型別的裝配       C、集合的裝配

類中是基本資料型別
set方式
Value屬性給基本資料型別賦值(String)
<property name=“” value=“”>

類中有類型別
class UserService{
UserDao dao}
ref為屬性值的是bean物件構建類型別的名字
<property name=“dao” ref=“tt”>

<property name=“dao”>
<ref bean=“tt”/>
</property>

<property name=“dao”>
<bean class=“UserDao”>
</property>

<bean name=“tt” class=“UserDao”>
2.實體型別Student
bean包

package com.briup.bean;

public class Student {
private long id;
private String name;
private int age;
private String email;
public long getId() {
	return id;
}
public void setId(long id) {
	this.id = id;
}
public String getName() {
	return name;
}
public void setName(String name) {
	this.name = name;
}
public int getAge() {
	return age;
}
public void setAge(int age) {
	this.age = age;
}
public String getEmail() {
	return email;
}
public void setEmail(String email) {
	this.email = email;
}
@Override
public String toString() {
	return "Student [id=" + id + ", name=" + name + ", age=" + age + ", email=" + email + "]";
}

}

IOC包配置檔案:

<?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">
          <!-- name屬性指的是Spring中儲存物件的名字,scope="prototype"設定單例物件時,不同名字構建的物件仍不同
               name可以指向多個名字,中間逗號隔開
               id標籤也是指的是Spring中儲存物件的名字,不能用逗號,
               id中的名字是一個整體
                -->
          <bean id="student" name="stu,stu1,stu2" class="com.briup.bean.Student" scope="prototype">
          <!-- 1.構建物件
               2.設定屬性
                 setId   反射getDeclaredMethod("setId")
                         方法映象public void setId(long);
                         方法引數getParameterTypes()[long]
                         long id=Long.parseLong("1");
                         stu.setId(id);
           -->
          <property name="id" value="1"></property>
           <property name="name" value="tom"></property>
            <property name="age">
            <value>33</value>
            </property>
             <property name="email" value="[email protected]"></property>
          </bean>
          <!-- 給某個名字對應物件起別名 -->
          <alias name="stu" alias="studd"/>
          </beans>
測試類:

@Test
	public void setter_test() {
		 ClassPathXmlApplicationContext cp=
				 new ClassPathXmlApplicationContext("com/briup/IOC/setter.xml");
		 System.out.println(cp.getBean("stu"));
		 System.out.println(cp.getBean("stu1"));
		 System.out.println(cp.getBean("stu2"));
		 System.out.println(cp.getBean("student"));
	}

A、基本型別的裝配 注意: 用setter方式注入的話,必須要用set、get方法 方式: 配置元素<value/>

例子:
public class HelloBean {
private String name;
private int age;
public String sayHello(){
return "hello "+name +",your age is" + age;
}
.............
}
配置檔案applicationContext.xml
<bean id="helloBean" class="ioc.HelloBean">
<property name="name">
<value>terry</value>
</property>
<property name="age" value="20">
</property>
</bean>
<!--id是Bean的唯一標識,要求在整個配置檔案中要唯一,也可使用name屬性
,bean標籤裡面的id和name屬性都可以用來標識這個配置的物件,
 -->
<!--property 對於所有用setter方式來注入的必須用Property來指定-->
<!--value 是對以基本型別,都用value來注入,可以實現自動的資料型別轉換-->
測試類:
public class Test {
public static void main(String[] args) {
ApplicationContext ac =
 new ClassPathXmlApplicationContext("ioc1applicationContext.xml");
//獲取容器的一個例項
HelloBean hb = (HelloBean) ac.getBean("helloBean");
System.out.println(hb.sayHello());
}
}

 B. 物件型別的裝配   (1)、<ref local=" "/>   (2)、<ref bean=" "/>   (3)、使用property的ref屬性引用  

public class OtherBean {
private String str1;
public String getStr1() {
return str1;
}
public void setStr1(String str1) {
this.str1 = str1;
}
public String toString(){
return "OtherBean "+str1;
}
}
public class SomeBean {
private OtherBean ob;
public void printInfo(){
System.out.println("someBean "+ob);
}
public OtherBean getOb() {
return ob;
}
public void setOb(OtherBean ob) {
this.ob = ob;
}
}
配置applicationContext.xml
<bean id="someBean" class="ioc.SomeBean">
<property name="ob">
<ref bean="otherBean" />
</property>
</bean>
配置other.xml檔案
 <bean id="otherBean" class="ioc2.OtherBean">
<property name="str1">
<value>string1</value>
</property>
</bean>
測試類:
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext(new String[]{"ioc2//applicationContext.xml","ioc2//other.xml"});
SomeBean sb = (SomeBean) ac.getBean("someBean");
sb.printInfo();
}
rel.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 name="us" class="com.briup.bean.UserService">
    <property name="id" value="1"></property>
    <property name="name" value="test"></property>
    1.porperty內屬性ref引入物件的名字(spring)
    <property name="dao" ref="dap"></property>
  </bean> -->
  <bean name="us" class="com.briup.bean.UserService">
    <property name="id" value="1"></property>
    <property name="name" value="test"></property>
    <!-- ref引入物件的名字(spring) -->
    <property name="dao" >
    <!-- 2.ref便籤 -->
     <ref bean="dap"/>
     <!--有些版本(低)也支援  
     <ref local="dap"/> -->
    </property>
  </bean>
  <bean name="us1" class="com.briup.bean.UserService">
    <property name="id" value="1"></property>
    <property name="name" value="test"></property>
    <!-- 3.ref引入物件的名字(spring) -->
    <property name="dao">
    <!-- bean標籤 -->
    <bean name="dap" class="com.briup.bean.UserDao"></bean>
    </property>
  </bean>
  
  <bean name="us2" class="com.briup.bean.UserService">
    <property name="id" value="1"></property>
    <property name="name" ref="str"></property>
    <property name="dao">
    <bean name="dap" class="com.briup.bean.UserDao"></bean>
    </property>
  </bean>
  <bean name="str" class="java.lang.String">
    <!-- 基於構造器方式注入
    index表示該引數在當前物件構造器中的位置,角標從0開始 
    Class.forName("java.lang.String").newInstance("test")-->
    <constructor-arg index="0" value="test"></constructor-arg>
    </bean>
  <bean name="dap" class="com.briup.bean.UserDao">
  
  </bean>
  
  </beans>

測試類:

@Test
	public void rel_test() {
		 try {
			ClassPathXmlApplicationContext cp=
					 new ClassPathXmlApplicationContext("com/briup/IOC/rel.xml");
			 UserService us=(UserService) cp.getBean("us2");
//			 UserService us1=
//			 cp.getBean("us",UserService.class);
			 System.out.println(us);
			 System.out.println(us.getName());
		} catch (BeansException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

C. 集合的裝配 方式:配置元素<list> <set> <map> <props>  

public class SomeBean {
private List listProperty;
private Set setProperty;
private Map mapProperty;
private Properties<String,String> property;
public List getListProperty() {
return listProperty;
}
public void setListProperty(List listProperty) {
this.listProperty = listProperty;
}
public Set getSetProperty() {
return setProperty;
}
public void setSetProperty(Set setProperty) {
this.setProperty = setProperty;
}
public Map getMapProperty() {
return mapProperty;
}
public void setMapProperty(Map mapProperty) {
this.mapProperty = mapProperty;
}
public Properties getProperty() {
return property;
}
public void setProperty(Properties property) {
this.property = property;
}
public void printInfo(){
System.out.println("listProperty");
System.out.println(listProperty);
System.out.println("setProperty");
System.out.println(setProperty);
Set set = mapProperty.entrySet();
Iterator it = set.iterator();
while(it.hasNext()){
 Map.Entry entry = (Entry) it.next();
 System.out.println("Key " +entry.getKey() );
 System.out.println("value "+entry.getValue());
}
System.out.println("props: ");
Set set2 = property.entrySet();
Iterator it2 = set2.iterator();
while(it2.hasNext()){
Map.Entry entry= (Entry) it2.next();
System.out.println("key "+entry.getKey());
System.out.println("value "+entry.getValue());
}
}
}
applcationContext.xml的寫法:
<bean id="someBean" class="ioc.SomeBean">
<property name="listProperty">
 <list>
    <value>list1</value>
    <value>list1</value>
    <value>list3</value>
 </list>
</property>
<property name="setProperty">
 <set>
    <value>set1</value>
    <value>set1</value>
    <value>set3</value>
 </set>
</property>
    <property name="mapProperty">
 <map>
    <entry key="key1">
          <value>value1</value>
    </entry>
   <entry key="key2">
          <value>value2</value>
    </entry>
 </map>
</property>
  <property name="property">
     <props>
  <prop key="key1">prop1</prop>
  <prop key="key2">prop2</prop>
  <prop key="key3">prop3</prop>
  </props>
</property>
</bean>
測試類:Test
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext  ac =
 new ClassPathXmlApplicationContext("ioc3applicationContext.xml");
    SomeBean sb = (SomeBean) ac.getBean("someBean");
    sb.printInfo();
}
實體類:

package com.briup.bean;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class CollTest {
private String[] array;
private List<String> list;
private Set<String> set;
private Map<String, String> map;
private Properties pros;
public String[] getArray() {
	return array;
}
public void setArray(String[] array) {
	this.array = array;
}
public List<String> getList() {
	return list;
}
public void setList(List<String> list) {
	this.list = list;
}
public Set<String> getSet() {
	return set;
}
public void setSet(Set<String> set) {
	this.set = set;
}
public Map<String, String> getMap() {
	return map;
}
public void setMap(Map<String, String> map) {
	this.map = map;
}
public Properties getPros() {
	return pros;
}
public void setPros(Properties pros) {
	this.pros = pros;
}

}


IOC配置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 name="str" class="java.lang.String">
  <constructor-arg index="0" value="array5"></constructor-arg>
</bean>
<bean name="coll" class="com.briup.bean.CollTest">
  <property name="array">
  <list>
  <value>array1</value>
  <value>array2</value>
  <value>array3</value>
  <ref bean="str"/>
  </list>
  <!-- 陣列的裝配 array,list標籤都可以寫-->
  <!-- <array>
    <value>array1</value>
    <value>array2</value>
    <value>array3</value>
    <ref bean="str"/>
    <bean class="java.lang.String">
      <constructor-arg index="0" value="array4"></constructor-arg>
    </bean>
  </array> -->
  </property>
  <property name="list">
  <!-- list集合的裝配,spring預設構建的集合是ArrayList 
       在beans的scheme的約束下不能指定具體的構建什麼樣的集合,
       util的scheme可以自定義集合型別
       value-type指的是集合的型別-->
  <!-- <array value-type="java.lang.String">
  <value>list1</value>
   <value>list2</value>
    <value>list3</value>
  </array> -->
  <list>
  <value>list1</value>
   <value>list2</value>
    <value>list3</value>
  </list>
  </property>
  
  <property name="set">
  <!-- set集合的裝配,標籤選擇set,預設構建的結合是LinkedHashSet -->
  <set value-type="java.lang.String">
  <value>set1</value>
   <value>set2</value>
    <value>set3</value>
    <ref bean="str"></ref>
  </set>
  </property>
  
  <property name="map">
  <!-- map集合的裝配,預設構建的集合是LinkedHashMap
       map下的entry表示一組鍵值對內容
       entry屬性  key表示鍵(基本資料型別或String)key-ref表示鍵是物件 key-ref指向做鍵的物件名字(存在Spring中)
       value表示基本資料型別的值(String)value-ref把Spring中某個名字的物件作為值 -->
  <map key-type="java.lang.String" value-type="java.lang.String">
  <entry key="key1" value="1"></entry>
   <entry key="key2" value="2"></entry>
    <entry key-ref="str" value-ref="str"></entry>
  </map>
  </property>
  
  <property name="pros">
  <!--properties集合的裝配  -->
  <props value-type="java.lang.String">
  <prop key="pro1">pro1</prop>
  <prop key="pro2">pro2</prop>
  <prop key="pro3">pro3</prop>
  </props>
  
  </property>
</bean>
</beans>

測試類:

	public void coll_test() {
			ClassPathXmlApplicationContext cp=
					 new ClassPathXmlApplicationContext("com/briup/IOC/coll.xml");
			CollTest col=(CollTest) cp.getBean("coll");
			System.out.println(col);
//			String[] strs=col.getArray();
//			System.out.println(Arrays.toString(strs));
			
//			List<String> list=col.getList();
//			System.out.println(list.getClass());
//			System.out.println(list);
			
//			Set<String> sets=col.getSet();
//			System.out.println(sets.getClass());
//			System.out.println(sets);
			
//			Map<String, String> map=col.getMap();
//			System.out.println(map.getClass());
//			System.out.println(map);
			
			Properties pro=col.getPros();
			System.out.println(pro.getClass());
			System.out.println(pro);
		 }
2.加util標籤庫

配置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"
      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 name="str" class="java.lang.String">
  <constructor-arg index="0" value="array5"></constructor-arg>
</bean>
<!-- Spring容器構建集合物件 id標籤表示集合的名字-->
<util:list id="strlist" list-class="java.util.LinkedList" value-type="java.lang.String">
<value>list1</value>
<value>list2</value>
<value>list3</value>
</util:list>
<bean name="de_coll" class="com.briup.bean.CollTest">
<property name="array">
<array>
<value>array1</value>
<value>array2</value>
<value>array3</value>
</array>
</property>
<property name="list" ref="strlist">
<!-- list-class指定Spring構建list集合的型別 -->
<!-- <util:list list-class="java.util.LinkedList" value-type="java.lang.String">
<value>list1</value>
<value>list2</value>
<value>list3</value>
</util:list> -->
</property>
<property name="set">
<!-- set-class指定Spring構建的set集合物件 -->
<util:set set-class="java.util.HashSet" value-type="java.lang.String">
<value>set1</value>
<value>set2</value>
<value>set3</value>
</util:set>
</property>
<property name="map">
<util:map map-class="java.util.HashMap">
<entry key="1" value="te1"></entry>
<entry key="2" value="te2"></entry>
<entry key="3" value="te3"></entry>
<entry key-ref="str" value-ref="str"></entry>
</util:map>
</property>
<property name="pros">
<!-- <props>
<prop key="pro1">pro</prop>
<prop key="pro2">pro</prop>
<prop key="pro3">pro</prop>
</props> -->
<!-- location直接將properties檔案的key=value內容載入到集合物件中,路徑也是基於classpath(src的下一級目錄開始) -->
<util:properties location="com/briup/IOC/db.properties"></util:properties>
</property>
</bean>

</beans>

測試類:
@Test
	public void de_coll_test() {
		try {
			//ClassPathXmlApplicationContext構造器內參數是可變參,可以寫多個路徑
				ClassPathXmlApplicationContext cp=
						 new ClassPathXmlApplicationContext("com/briup/IOC/definecoll.xml");
//				ClassPathXmlApplicationContext cp=
//				 new ClassPathXmlApplicationContext(new String[] {"com/briup/IOC/coll.xml","com/briup/IOC/de_coll.xml"});
				CollTest col=(CollTest) cp.getBean("de_coll");
				List<String> list=(List<String>) cp.getBean("strlist");
				System.out.println(list);
				System.out.println(col);
//			String[] strs=col.getArray();
//			System.out.println(Arrays.toString(strs));
				
//			List<String> list=col.getList();
//			System.out.println(list.getClass());
//			System.out.println(list);
				
//			Set<String> sets=col.getSet();
//			System.out.println(sets.getClass());
//			System.out.println(sets);
				
				Map<String, String> map=col.getMap();
				System.out.println(map.getClass());
				System.out.println(map);
				
//			Properties pro=col.getPros();
//			System.out.println(pro.getClass());
//			System.out.println(pro);
		} catch (BeansException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		 }

2)基於構造器

方式: 配置<constructor-arg>元素 在Bean中不用寫set方法,但是要有相應的構造器

過載:個數,型別,順序  

<constructor-arg type="int" value="">
<constructor-arg  index="0" value="">
例子:
public class SomeBean {
//構造器配置
private String str1;
private String str2;
private int value1;
public SomeBean(String str1, String str2, int value1) {
super();
this.str1 = str1;
this.str2 = str2;
this.value1 = value1;
}
public void printInfo(){
   System.out.println("str1 "+str1 +"str2 "+str2+" value1 "+value1 );
}
}
配置檔案applicationContext.xml的寫法
<bean id="someBean" class="ioc.SomeBean">
方式一:使用型別注入
<constructor-arg type="java.lang.String">
  <value>String1</value>
</constructor-arg>
<constructor-arg type="java.lang.String" value="String2">
</constructor-arg>
<constructor-arg type="int">
  <value>100</value>
</constructor-arg>
方式二:使用引數的索引注入
<constructor-arg index="1"> <!--表示第二個引數-->
  <value>String1</value>
</constructor-arg>
<constructor-arg index="0">
</constructor-arg>
<constructor-arg index="2">
  <value>100</value>
</constructor-arg>
</bean>
配置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">
        <!-- 基於構造器給Spring構建的物件傳參,使用的子標籤constructor-arg-->
<bean name="stu" class="com.briup.bean.Student">
<!-- 1.基於角標傳引數,角標從0開始,角標代表的是賦值的位置
     配置constructor-arg位置不會影響賦值 -->
    <constructor-arg index="0" value="11"></constructor-arg>
    <constructor-arg index="1" value="tom"></constructor-arg>
    <constructor-arg index="2" value="30"></constructor-arg>
    <constructor-arg index="3" value="[email protected]"></constructor-arg>
</bean>
<!-- 2.基於構造器引數的型別配置 
     基本資料型別直接寫型別-->
<bean name="stu1" class="com.briup.bean.Student">
<!-- type屬性要和構造器中設定引數的型別匹配(long,String,int,String)
     基於型別匹配構造器不能換位置 -->
   <constructor-arg type="long" value="11"></constructor-arg>
    <constructor-arg type="java.lang.String" value="tom1"></constructor-arg>
     <constructor-arg type="int" value="33"></constructor-arg>
      <constructor-arg type="java.lang.String" value="[email protected]"></constructor-arg>
</bean>
<!-- 3.基於構造器中的變數名設定值 
     name指向構造器中的變數名-->
<bean name="stu2" class="com.briup.bean.Student">
  <constructor-arg name="id" value="33"></constructor-arg>
   <constructor-arg name="name" value="jake"></constructor-arg>
    <constructor-arg name="age" value="12"></constructor-arg>
     <constructor-arg name="email" value="[email protected]"></constructor-arg>
</bean>
<!-- 上面三種結合 -->
<bean name="stu3" class="com.briup.bean.Student">
  <constructor-arg index="0" name="id"><value>11</value></constructor-arg>
  <constructor-arg index="1" name="name" ref="str"></constructor-arg>
  <constructor-arg index="2" name="age" value="34"></constructor-arg>
  <constructor-arg index="3" name="eamil"><ref bean="str"></ref></constructor-arg>
</bean>
<bean id="str" class="java.lang.String">
  <constructor-arg index="0" value="kks"></constructor-arg>
</bean>
</beans>

測試類:

	@Test
	public void construct_test() {
		ClassPathXmlApplicationContext cp=
				new ClassPathXmlApplicationContext("com/briup/IOC/construct.xml");
		Student s=(Student) cp.getBean("stu2");
		System.out.println(s);
	}

3)自動裝配 :容器依照一些規則去裝配bean中的一個屬性        在beans標籤中配置裝載方式:default-autowire="byName" 或者在bean標籤中指定配置方式 a. autowire="byName": spring容器會到當前的類中找property的名字,然後 再根據這個名字去spring容器中找有沒有和這個property 名字相同的物件,有的話,就把這個物件當做引數放到 setXxxx這個方法裡面注入進來. 注意:瞭解property指的類中的什麼東西。

b,autowire="byType": spring容器會根據當前類中的set方法裡面引數的型別, 去容器中找相匹配的物件,如果沒找到就算了,如果找到 一個就注入進來,如果找到多個,那麼就會報錯了. c,autoWirde = "constructor" 根據構造器的引數型別去匹配     如果所有屬性(基本型別) d,autoWire = "autoDetect" 自動檢測 e.autowire = "default"

例子:
public class SomeBean {
 //自動裝配
private String str2;
private OtherBean ob;
public SomeBean(OtherBean ob) {
super();
this.ob = ob;
}
public String getStr2() {
return str2;
}
public void setStr2(String str2) {
this.str2 = str2;
}
public OtherBean getOb() {
return ob;
}
public void setOb(OtherBean ob) {
this.ob = ob;
}
public void printInfo(){
System.out.println("str2 "+str2 +" ob "+ob);
}
}
public class OtherBean {
//自動裝配
private String str1;
public String getStr1() {
return str1;
}
public void setStr1(String str1) {
this.str1 = str1;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "str1 "+str1;
}  
}
配置檔案的寫法
<bean id="otherBean" class="ioc.OtherBean">
<property name="str1" value="String1" />
</bean>
<!-- <bean id="someBean" class="ioc.SomeBean" autowire="byName">
<property name="str2" value="String2" />
</bean>
 <bean id="someBean" class="ioc.SomeBean" autowire="byType">
<property name="str2" value="String2" />
</bean>
  <bean id="someBean" class="ioc.SomeBean" autowire="constructor">
<property name="str2" value="String2" />
</bean>
配置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"
          default-autowire="byName">  
          <!-- autowire自動匹配,自動轉載
               byType基於型別匹配並轉載,特點:基於set方法的引數型別匹配,使用byType時,必須保證該型別只能出現一次
               byName基於名字匹配,特點:基於set後首字母小寫的名字和bean標籤中的名字匹配
               default採用預設的,前提:和一級標籤beans中的屬性default-autowire結合使用
               default-autowire設定的是全域性的匹配方式
               如果bean標籤配置 類匹配物件的方式,一級標籤配置的 default-autowire失效(就近原則)
               autowire="no" 不採用自動匹配 -->
     <!-- <bean name="us" class="com.briup.bean.UserService" autowire="byType">
     </bean> -->     
     <!-- <bean name="us" class="com.briup.bean.UserService" autowire="byName">
     </bean> -->
     <bean name="us" class="com.briup.bean.UserService" autowire="default">
     </bean>
     <bean name="dao1" class="com.briup.bean.UserDao">
     <property name="id" value="101"></property>
     </bean> 
     <bean name="dao" class="com.briup.bean.UserDao">
     <property name="id" value="100"></property>
     </bean>
     
     
     <!--autowire="constructor"基於構造器中的引數匹配,預設基於型別匹配,如果型別找到多個的時候,再基於名字匹配  -->
     <bean name="us1" class="com.briup.bean.UserService" autowire="constructor">
     <constructor-arg index="0" value="1"></constructor-arg>
      <constructor-arg index="1" value="tom"></constructor-arg>
      <constructor-arg index="2" value="dao"></constructor-arg>
     </bean>
</beans>

測試類:

@Test
	public void auto_test() {
		try {
			ClassPathXmlApplicationContext cp=
					new ClassPathXmlApplicationContext("com/briup/IOC/auto.xml");
			UserService ser=(UserService) cp.getBean("us");
			System.out.println(ser);
			System.out.println(ser.getDao());
		} catch (BeansException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

注意:自動裝配的優先順序低於手動裝配 自動裝配一般用於快速開發建立系統原型的情況,但是在正式的開發中很少使用, 因為容易出錯,難以維護;

4)繼承裝入: 並不是oo的繼承關係 (bean的定義的繼承,指bean的配置可去繼承                 True 抽象化 客戶端不能getBean了   Abstract =                   False 預設 Parent = "父類bean的id"

例子:
public class Car {
//bean的定義的繼承
private String owner;
private String name;
private int price;
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return owner+" "+name+" "+price;
}
}
<bean id="abstractCar" class="ioc.Car" abstract="true">
<property name="owner" value="zwb" />
</bean>
<bean id="car1" parent="abstractCar">
<property name="name" value="qq" />
<property name="price" value="10" />
</bean>
<bean id="car2" parent="abstractCar">
<property name="name" value="baoma" />
<property name="price" value="70" />
</bean>
public class Test {
public static void main(String[] args){
ApplicationContext ac = new ClassPathXmlApplicationContext("ioc6applicationContext.xml");
    Car car1=(Car) ac.getBean("car1");
    Car car2=(Car) ac.getBean("car2");
    System.out.println(car1.toString());
    System.out.println(car2.toString());
}
}

======================================================= 8,建立Bean例項的方式  1) 通過構造器(有參或無參)       方式: <bean id="" class=""/>

 2) 通過靜態工廠方法   方式: <bean id/name="目標物件" class="工廠類" factory-method="靜態工廠方法"/> 注意:工廠類不會被例項化 利用靜態factory方法建立,可以統一管理各個bean的建立,如各個bean在建立之前需要相同 的初始化處理,則可用這個factory方法險進行統一的處理等等。      例子:       public class HelloBeanFactory {            public static HelloBean createHelloBean() {                return new HelloBean();               }        }          xml:配置     //構造器配置      ﹤bean id="sayhello" class="test.service.impl.HelloBean"/﹥         //靜態工廠       ﹤bean id="sayhello2" class="test.service.impl.HelloBeanFactory" factory-method="createHelloBean"/﹥                 3)通過例項工廠方法(非靜態方法)   方式:     <bean id="factory" class="工廠類"/> <bean id="" factory-bean="factory" factory-method="例項工廠方法"/> 利用例項化factory方法建立,即將factory方法也作為了業務bean來控制

工廠Java檔案: public class HelloBeanInstanceFactory {    public Hello createHelloBean() {    return new HelloBean();    } xml: ﹤bean id="factory" class="test.service.impl.HelloBeanInstanceFactory"/﹥          ﹤bean id="sayhello" factory-bean="factory" factory-method="createHelloBean"/﹥

4)Bean實現Spring提供FactoryBean介面 介面提供工廠方法和返回構建物件的Class以及是否單例的方法 注意:  <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">         <property name="location" value="com/briup/ioc/factory/db.properties"></property>     </bean>     <bean class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">         <property name="location" value="com/briup/IOC/static.properties"></property>     </bean>

=================================================

9,SpringBean類的生命週期 在ApplicationContext中Bean的生命週期

生命週期執行的過程如下: 1)需找所有的bean根據bean定義的資訊來例項化bean 預設bean都是單例 2)使用依賴注入,spring按bean定義資訊配置bean的所有屬性 3若bean實現了BeanNameAware介面,工廠呼叫Bean的setBeanName()方法傳遞bean的ID。 4)若bean實現了BeanFactoryAware介面,工廠呼叫setBeanFactory() 方法傳入工廠自身。 5)若bean實現了ApplicationContextAware()介面,setApplicationContext()方法會被呼叫 6)若bean實現了InitializingBean,則 afterPropertiesSet被呼叫 7)若bean指定了init-method="init"方法,它將被呼叫。 8)若BeanPostProcessor和bean關聯, 則它們的postProcessBeforeInitialization()方法被呼叫 9)、若有BeanPostProcessor和bean關聯,      則它們的postProcessAfterInitialization()方法被呼叫     注意:通過已上操作,此時的Bean就可以被應用的系統使用,並將保留在BeanFactory工廠中直到不再需要為止.但我們也可以通過10或者11進行銷燬 10)、若bean實現了DisposableBean介面,distroy()方法被呼叫 11)、如果指定了destroy-method="close"定製的銷燬方法,就呼叫這個方法