Spring的學習(1)

第1章 使用Spring的IOC完成保存客戶的操作:

1.1案例需求

需求概述
CRM系統中客戶信息管理模塊功能包括:
新增客戶信息
客戶信息查詢
修改客戶信息
刪除客戶信息

本功能要實現新增客戶

第2章 Spring的概述

2.1什麼是Spring

Spring是分層的、JavaSE/EE一站式(full-stack)、輕量級開源框架。

JavaEE分層
JavaEE規範的三層結構體系:
表現層(頁面數據顯示、頁面跳轉調度),例如jsp/servlet
業務層(業務處理和功能邏輯、事務控制),例如service
持久層(數據存取和封裝、和數據庫打交道),例如dao
如圖:
在這裏插入圖片描述
一站式
Spring提供了JavaEE各層的解決方案:
表現層:struts1、struts2、Spring MVC
業務層:Ioc、AOP、事務控制
持久層:JdbcTemplate、HibernateTemplate、ORM框架(對象關係映射)整合在這裏插入圖片描述
輕量級:Spring的出現取代了EJB的臃腫、低效、繁瑣複雜、脫離現實。
在這裏插入圖片描述

2.2 Spring的體系結構

Spring框架是一個分層架構,它包含一系列的功能要素並被分爲大於20個模塊。這些模塊分爲Core Container、Data Access/Integration、Web、AOP(Aspect Oriented Programming)、Instrumentation和測試部分,如圖:
在這裏插入圖片描述
核心容器(Core Container) 包括Core、Beans、Context、EL模塊。
1:Core和Beans模塊提供了Spring最基礎的功能,提供IoC和依賴注入特性。這裏的基礎概念是BeanFactory,它提供對Factory模式的經典實現來消除對程序性單例模式的需要,並真正地允許你從程序邏輯中分離出依賴關係和配置。
2:Context模塊基於Core和Beans來構建,它提供了用一種框架風格的方式來訪問對象,有些像JNDI註冊表。Context封裝包繼承了beans包的功能,還增加了國際化(I18N),事件傳播,資源裝載,以及透明創建上下文,例如通過servlet容器,以及對大量JavaEE特性的支持,如EJB、JMX。核心接口是ApplicationContext。
3:Expression Language,表達式語言模塊,提供了在運行期間查詢和操作對象圖的強大能力。支持訪問和修改屬性值,方法調用,支持訪問及修改數組、容器和索引器,命名變量,支持算數和邏輯運算,支持從Spring 容器獲取Bean,它也支持列表投影、選擇和一般的列表聚合等。
數據訪問/集成部分(Data Access/Integration)
1:JDBC模塊,提供對JDBC的抽象,它可消除冗長的JDBC編碼和解析數據庫廠商特有的錯誤代碼。
2:ORM模塊,提供了常用的"對象/關係"映射APIs的集成層。 其中包括JPA、JDO、Hibernate 和 iBatis 。利用ORM封裝包,可以混合使用所有Spring提供的特性進行"對象/關係"映射,如簡單聲明性 事務管理 。
3:OXM模塊,提供一個支持Object和XML進行映射的抽象層,其中包括JAXB、Castor、XMLBeans、JiBX和XStream。
4:JMS模塊,提供一套"消息生產者、消費者"模板用於更加簡單的使用JMS,JMS用於用於在兩個應用程序之間,或分佈式系統中發送消息,進行異步通信。
5:Transaction模塊,支持程序通過簡單聲明性 事務管理,只要是Spring管理對象都能得到Spring管理事務的好處,即使是POJO,也可以爲他們提供事務。
Web
1:Web模塊,提供了基礎的web功能。例如多文件上傳、集成IoC容器、遠程過程訪問、以及Web Service支持,並提供一個RestTemplate類來提供方便的Restful services訪問
2:Web-Servlet模塊,提供了Web應用的Model-View-Controller(MVC)實現。Spring MVC框架提供了基於註解的請求資源注入、更簡單的數據綁定、數據驗證等及一套非常易用的JSP標籤,完全無縫與Spring其他技術協作。
3:Web-Struts模塊, 提供了對Struts集成的支持,這個功能在Spring3.0裏面已經不推薦了,建議你遷移應用到使用Struts2.0或Spring的MVC。
4:Web-Portlet模塊,提供了在Portlet環境下的MVC實現
AOP
1:AOP模塊,提供了符合AOP 聯盟規範的面向方面的編程實現,讓你可以定義如方法攔截器和切入點,從邏輯上講,可以減弱代碼的功能耦合,清晰的被分離開。而且,利用源碼級的元數據功能,還可以將各種行爲信息合併到你的代碼中 。
2:Aspects模塊,提供了對AspectJ的集成。
3:Instrumentation模塊, 提供一些類級的工具支持和ClassLoader級的實現,可以在一些特定的應用服務器中使用。
Test
1:Test模塊,提供對使用JUnit和TestNG來測試Spring組件的支持,它提供一致的ApplicationContexts並緩存這些上下文,它還能提供一些mock對象,使得你可以獨立的測試代碼。

2.3Spring的核心

IoC(Inverse of Control 控制反轉): 將對象創建權利交給Spring工廠進行管理。
AOP(Aspect Oriented Programming 面向切面編程),基於動態代理的功能增強方式。

百度百科:Spring 是基於IOC和AOP的一套編程框架。
在這裏插入圖片描述
在這裏插入圖片描述
今天的主要學習IoC

2.4 Spring的優點

Spring 出現爲了解決JavaEE 實際問題
(1)方便解耦,簡化開發
Spring就是一個大工廠,可以將所有對象創建和依賴關係維護,交給Spring管理
(2)AOP編程的支持
Spring提供面向切面編程,可以方便的實現對程序進行權限攔截、運行監控等功能
(3)聲明式事務的支持
只需要通過配置就可以完成對事務的管理,而無需手動編程
(3)方便程序的測試
Spring對Junit4支持,可以通過註解方便的測試Spring程序
(5)方便集成各種優秀框架
Spring不排斥各種優秀的開源框架,其內部提供了對各種優秀框架(如:Struts、Hibernate、MyBatis、Quartz、webservice、activity等)的直接支持
(6)降低JavaEE API的使用難度
Spring 對JavaEE開發中非常難用的一些API(JDBC、JavaMail、遠程調用等),都提供了封裝,使這些API應用難度大大降低
關於框架的特性,我們也會俗稱Spring爲開發架構的粘合劑

第3章 Spring IoC快速入門

3.1 Spring核心內容的基本開發步驟:

下載開發包,導入jar包
編寫代碼(基礎代碼和調用代碼)
編寫配置文件(XML)
測試

3.1 Spring的開發包

開發包的下載
在這裏插入圖片描述
Spring官方:http://spring.io/
在這裏插入圖片描述
在這裏插入圖片描述
下載網址:http://repo.spring.io/libs-release-local/org/springframework/spring/
官方最新版本:
在這裏插入圖片描述
在這裏插入圖片描述
不同系列版本對開發環境的最低需求:
在這裏插入圖片描述
我們採用的版本是:4.2.x的版本(企業主流版本,框架整合也需要對應版本jar):
在這裏插入圖片描述
Spring4.2版本開發包目錄結構:
在這裏插入圖片描述
第一步:其中docs:
查看docs\spring-framework-reference\pdf中的spring-framework-reference.pdf規範文檔中基本內容瞭解:
在這裏插入圖片描述
第三章 核心技術 (IoC和AOP)
第四章 測試部分
第五章 數據訪問 持久層 (JdbcTemplate、聲明式事務管理)
第六章 表現層 SpringMVC ,整合Struts2
第七章 集成 零散技術 , 需要在項目實戰講解

第二步:其中jar:
打開spring-framework-4.2.4.RELEASE-dist\spring-framework-4.2.4.RELEASE\libs
在這裏插入圖片描述
開發過程中還需要其他開源技術框架依賴Jar包集(dependencies,作用是方便依賴的其他技術的jar的導入):
在這裏插入圖片描述
第三步:其中schema:
打開:spring-framework-4.2.4.RELEASE-schema\beans,查看spring配置文件的規範約束
在這裏插入圖片描述
3.2開發環境測試搭建(Jar的導入)
第一步:新建Web工程Spring4_d01_c03,
第二步:導入jar包

1.Spring項目的核心容器的最基本Jar包(4個):
在這裏插入圖片描述
打開spring-framework-4.2.4.RELEASE-dist\spring-framework-4.2.4.RELEASE\libs,可以看到
在這裏插入圖片描述
2.Spring框架所需的日誌包(2個,依賴jar庫中找):
默認採用apache commons-logging(JCL)日誌框架+log4j的日誌實現,還需要添加log4j的配置文件。
打開:課前資料,spring-framework-3.0.2.RELEASE-dependencies
找到:org.apache.commons文件夾和org.apache.log4j文件夾
在這裏插入圖片描述
關於java日誌的補充閱讀:
Java的常見的日誌系統有log4J,jdk-jul,logback等,這些日誌系統各自獨立,編程方式也不一致。如果你一個系統要用到多個框架庫,而這些框架庫又可能要用不同的日誌系統,那麼你一個系統中就得使用多套日誌系統,那多套日誌系統如何融合在一起是個很大的問題。
那麼如何解決呢?進行抽象,抽象出一個接口層,對每個日誌實現都適配或者轉接,這樣這些提供給別人的庫都直接使用抽象層即可,不需要關注具體的日誌實現。常見的日誌抽象出來的框架有Apache commons-logging和slf4j。
這裏有個故事:最新是開源社區提供了commons-logging抽象,被稱爲JCL日誌框架,出色地完成了兼容主流的日誌實現(log4j、JUL、simplelog),基本一統江湖,就連頂頂大名的spring也是依賴了JCL。
看起來事物確實是美好,但是美好的日子不長,接下來另一個優秀的日誌框架slf4j的加入導致了更加混亂的場面。比較巧的是slf4j的作者(Ceki Gülcü)就是log4j的作者,他覺得JCL不夠優秀,所以他要自己搞一套更優雅的出來,於是slf4j日誌體系誕生了,併爲slf4j實現了一個親子——logback,確實更加優雅。
但是由於之前很多代碼庫已經使用JCL,雖然出現slf4j和JCL之間的橋接轉換,但是集成的時候問題依然多多,對很多新手來說確實會很懊惱,因爲比單獨的log4j時代“複雜”多了,可以關注下這個,抱怨聲確實很多。到此本來應該完了,但是Ceki Gülcü覺得還是得回頭拯救下自己的“大阿哥”——log4j,於是log4j2誕生了,同樣log4j2也參與到了slf4j日誌體系中。日誌體系的江湖又將面臨血雨腥風的混亂了。
hibernate-jboss-hibernate3(slf4j+log4j)hibernate4:jboss logging(整合其他的日誌)
導好的jar:
在這裏插入圖片描述
添加log4j的日誌文件:
添加log4j.properties文件放置到src下。

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c\:mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=info, stdout

3.3 傳統方式業務代碼編寫(業務層、數據持久層)

採用的示例業務是模擬用戶登錄操作。
第一步:創建包com.igeek

第二步:創建dao
1:創建接口IUserDao

package com.igeek;
//用戶的dao層
public interface IUserDao {
	//向數據查詢數據,根據用戶名和密碼
	public void findByUsernameAndPassword();
}

2:創建IUserDao接口的實現類UserDaompl

package com.igeek;
//dao的實現類
public class UserDaoImpl implements IUserDao {
	@Override
	public void findByUsernameAndPassword() {
		System.out.println("UserDaoImpl-dao層被調用了");
	}
}

第三步:創建service
1:創建接口IUserService

package com.igeek;
//業務層
public interface IUserService {
	//登錄
	public void login();
}

2:創建IUserService接口的實現類UserServiceImpl、

package com.igeek;

//業務層實現
public class UserServiceImpl implements IUserService{

	public void login() {
		System.out.println("UserServiceImpl-service層被調用了。。。");
		//實例化dao層
		//傳統方式
		IUserDao userDao = new UserDaoImpl();
		userDao.findByUsernameAndPassword();
	}
}

第四步:測試
創建SpringTest類進行測試:

package com.igeek;

import org.junit.Test;
//測試
public class SpringTest {
	@Test
	//模擬表現層
	public void testOld(){
		IUserService userService = new UserServiceImpl();
		userService.login();
	}
}

第五步:測試結果
控制檯輸出:
在這裏插入圖片描述
【思考分析】
存在問題:代碼過於耦合,上層代碼過度依賴於下一層代碼的實現:
例如:UserDao userDao = new UserDaoImpl();
如果要更換實現類,或者實現類換一個名字,此時代碼會報錯,必須要修改原來的業務代碼!

解決方案:採用IoC(Inverse of Control,控制反轉)的思想。
簡單的說就是引入工廠(第三者),將原來在程序中手動創建管理的依賴的UserDaoImpl對象,交給工廠來創建管理。在Spring框架中,這個工廠就是Spring中的工廠(簡單的說,spring的工廠就是xml文件),因此,也可以說,將創建管理UserDaoImpl對象的控制權被反轉給了Spring框架了。
例如:
傳統代碼

IOC方式
在這裏插入圖片描述
概念:IoC中文翻譯爲控制反轉,指以前程序自己創建對象,現在將創建對象的控制權交給了第三方(Spring)了。
IoC底層實現:工廠(設計模式)+反射(機制) + 配置文件(xml)。

IoC是一種思想,是控制反轉的思想、是一種解耦合的思想。
Spring是該思想的一種實現。因此Spring容器也通常稱之爲IoC容器。

3.4 IoC控制反轉的實現

3.4.1 Spring核心配置文件的編寫

IoC控制反轉的理解和實現
第一步:在src下建立applicationContext.xml (位置:applicationContext.xml文件放置到任何目錄都可以,習慣上放在src目錄或者 WEB-INF目錄)在這裏插入圖片描述
引入xml的頭部信息bean schema約束,可以參考規範文檔中的spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html
xsd-configuration.html

找到下列章節的示例,拷貝到工程中即可:
搜索
40.2.12 the beans schema
結果如下:

<?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">
</beans>

問題:發現引入規範約束後,沒有關聯對應的配置,原因是:
配置本地提示:點擊eclipse屬性——>選擇XML Catalog
在這裏插入圖片描述
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:是spring工廠幫你new的一個對象(機制:反射機制)
	    class:要new的對象的類型的字符串表示形式(一定全類名)
	    id/name:標識對象的名字,用來獲取bean對象用的標識。習慣上,這個名字命名爲接口的名字首字母小寫
	 -->
	<bean id="userDao"  class="com.igeek.spring.UserDaoImpl"/>
</beans>

3.4.2 通過Spring的工廠獲取Bean完成相關操作

基本過程是:在程序中讀取Spring配置文件,得到Spring的Bean工廠,通過Spring框架獲得Bean,完成相應操作
創建包:com.igeek.spring
複製代碼:到com.igeek包
修改UserServiceImpl 代碼,編寫:

//業務層實現
public class UserServiceImpl implements IUserService{
	
	public void login() {
		System.out.println("UserServiceImpl-service層被調用了。。。");
		//spring的配置方式,IOC控制反轉
		//構建一個spring的工廠,使用applicationContext.xml(spring的核心配置文件)獲取對象
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		//從spring工廠中使用對象的標識獲取對象
		IUserDao userDao = (IUserDao) ac.getBean("userDao");
		userDao.findByUsernameAndPassword();
	}
}

使用SpringTest類進行測試:

//測試
public class SpringTest {
	@Test
	//模擬表現層
	public void testOld(){
		IUserService userService = new UserServiceImpl();
		userService.login();
	}

測試結果:在這裏插入圖片描述
3.5DI依賴注入的實現
DI:Dependency Injection 依賴注入,在Spring框架負責創建Bean對象時,動態的將依賴對象注入到Bean組件(簡單的說,可以將另外一個bean對象動態的注入到另外一個bean中。)

【面試題】IoC和DI的區別 ?

DI和IoC是同一件事情,都是將對象控制權交給第三方(Spring)管理,只是站在不同角度而已。
IoC:在這裏插入圖片描述
在這裏插入圖片描述
耦合代碼變成依賴注入代碼的方法:
在這裏插入圖片描述
即:Spring創建了Service、Dao對象,在配置中將Dao傳入Servcie,那麼Service對象就包含了Dao對象的引用。

Spring的核心配置文件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">

    <!-- 
    ioc
        bean:是spring工廠幫你new的一個對象(機制:反射機制)
	    class:要new的對象的類型的字符串表示形式(一定全類名)
	    id/name:標識對象的名字,用來獲取bean對象用的標識。習慣上,這個名字命名爲接口的名字首字母小寫
	 -->
	<bean id="userDao"  class="com.igeek.spring.UserDaoImpl"/>
	<!--
	service 
	di:必須雙方都是bean:在創建service的時候,主動將dao的依賴對象注入交給serivce
	 -->
	<bean name="userService" class="com.igeek.spring.UserServiceImpl">
		<!-- property:
		setter屬性注入
			* name:setter屬性的名字,和類一致。如果setXxx,這裏xxx,setUserDAO-userDAO
			* spring會自動調用setUserDao(IUserDao userDao)方法
			* ref:spring容器中定義的bean(對象)的名字
		 -->
		<property name="userDao" ref="userDao"/>
	</bean>
</beans>

Service業務層代碼:

//業務層實現
public class UserServiceImpl implements IUserService{
	
	//定義屬性
	private IUserDao userDao;
	//提供set方法,使用setXxx方法完成屬性的注入
	public void setUserDao(IUserDao userDao) {
		this.userDao = userDao;
	}	
	//使用依賴注入的方式獲取dao
	public void login() {
		System.out.println("UserServiceImpl-service層被調用了。。。");
		userDao.findByUsernameAndPassword();
	}
}

springTest.java測試代碼:

//測試
public class SpringTest {
	@Test
	//模擬表現層
	public void testOld(){
		//spring的配置方式,IOC控制反轉
		//構建一個spring的工廠,使用applicationContext.xml(spring的核心配置文件)獲取對象
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		//從spring工廠中使用對象的標識獲取對象
		IUserService userService = (IUserService) ac.getBean("userService");
		userService.login();
	}
}

分析:
在這裏插入圖片描述

3.6 Spring的工廠

ApplicationContext直譯爲應用上下文,是用來加載Spring框架配置文件,來構建Spring的工廠對象,它也稱之爲Spring容器的上下文對象,也稱之爲Spring的容器。
ApplicationContext 只是BeanFactory(Bean工廠,Bean就是一個java對象) 一個子接口:在這裏插入圖片描述
爲什麼不直接使用頂層接口對象來操作呢?

  • BeanFactory 採取延遲加載,第一次getBean時纔會初始化Bean
  • Beanfactory的用法:
    BeanFactory ac = new XmlBeanFactory(new ClassPathResource(“applicationContext.xml”));
    BeanFactory ac = new XmlBeanFactory(new FileSystemResource(“D:\applicationContext.xml”));
  • ApplicationContext是對BeanFactory擴展,提供了更多功能
    國際化處理
    事件傳遞
    Bean自動裝配
    各種不同應用層的Context實現

ApplicationContext 更加強大, 所以現在開發基本沒人使用BeanFactory。
提示:後面還有個FactoryBean,注意區別。
【示例瞭解】

    public void testSpring(){
			//構建spring工廠
			//ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
			//使用BeanFactory
			//BeanFactory applicationContext = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
			//直接使用超級接口
			BeanFactory applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
			IUserService userService=(IUserService) applicationContext.getBean("userService");
			userService.login();
		}

3.7 Spring工廠的直接獲取(兩種方式)-瞭解

src:開發的時候,工程裏的一個目錄,存放的文件,會在編譯發佈後,放入classes下。
在這裏插入圖片描述
在這裏插入圖片描述
applicationContext應用上下文,加載Spring框架配置文件
方法一:從classpath路徑加載
在類路徑下尋找配置文件來實例化容器
ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{“applicationContext.xml”});
可以在整個類路徑中尋找xml文件
* 通過這種方式加載。需要將spring的配置文件放到當前項目的classpath路徑下
* classpath路徑指的是當前項目的src目錄,該目錄是java源文件的存放位置。

方法二:從磁盤路徑加載
在文件系統路徑下尋找配置文件來實例化容器
ApplicationContext ctx = new FileSystemXmlApplicationContext(new String[]{“d:\applicationContext.xml”});
(1)Spring的配置文件可以指定多個,可以通過String數組傳入。
(2)通過getBean方法獲得Spring容器管理Bean對象
如何選擇:
如果applicationContext.xml 在 src下, ClassPathXmlApplication讀取
如果applicationContext.xml 在WEB-INF下,FileSystemXmlApplicationContext讀取

【擴展】
Bean獲取的兩種方式:

  /**1:使用spring容器中的標識獲取對象*/
      ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		//IUserService userService=(IUserService) applicationContext.getBean("userService");
		/**
		 * 2:根據bean的類型來獲取:自動到spring容器中查找哪個bean是這個類型
		 * 如果  Object instanceOf(IUserService.class)或者Object instanceOf(UserServiceImpl.class)
		 * 類型獲取有個鬱悶的情況:如果容器中有兩個同樣的類型,則會報錯!!!!!
		 */
		//IUserService userService=(IUserService) applicationContext.getBean(IUserService.class);
		IUserService userService=(IUserService) applicationContext.getBean(UserServiceImpl.class);//一般不會使用實現類
		//業務方法
		userService.login();

常用根據名稱獲取(id/name),即第一種方式,使用spring容器中的標識獲取對象

如果根據類型獲取,配置了多個類型的話,則拋出異常:
例如spring容器中配置:

  <bean name="userService" class="com.igeek.spring.UserServiceImpl">
		<property name="userDao" ref="userDao"/>
	</bean>
	<bean name="userService1" class="com.igeek.spring.UserServiceImpl">
		<property name="userDao" ref="userDao"/>
	</bean>

使用代碼進行測試

IUserService userService=(IUserService) applicationContext.getBean(UserServiceImpl.class);//一般不會使用實現類

則拋出異常
在這裏插入圖片描述

第4章 IoC容器裝配Bean_基於XML配置方式

4.1實例化Bean的四種方式 (瞭解)

創建web項目:spring4_d01_c04,導入項目所需的6個jar包,拷貝上個項目的配置文件applicationContext.xml
log4j.properties
創建包:com.igeek
第一種方式 無參數構造器 (最常用)
第一步:創建Bean1.java

//1。默認構造器(spring在創建bean的時候自動調用無參構造器來實例化,相當於new Bean1())
public class Bean1 {
}

第二步:在spring容器applicationContext.xml中配置

<!-- 實例化bean的方式 -->
	<!-- 1.:默認構造器 
	在實例化的時候,自動調用默認的構造器,相當於Bean1 bean1 =new Bean1();
	-->
	<bean id="bean1" class="com.igeek.Bean1"/>

第三步:創建測試文件SpringTest.java

@Test
	public void test1(){
		//先構建實例化獲取spring的容器(工廠、上下文)
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		//1。默認構造器獲取bean的對象
		Bean1 bean1=(Bean1) applicationContext.getBean("bean1");
		System.out.println(bean1);		
	}

運行結果:在這裏插入圖片描述
【錯誤演示】:

//1。默認構造器(spring在創建bean的時候自動調用無參構造器來實例化,相當於new Bean1())
public class Bean1 {
    private String name;
	//錯誤原因:沒有無參構造器
	
	//如果設置一個有參數的構造器,會覆蓋無參數的構造器,會報錯。無法實例化Bean
	public Bean1(String name){
		this.name = name;
	}
}

【報錯】:在這裏插入圖片描述
第二種方式: 靜態工廠方法
第一步:創建Bean2.java

//1.靜態工廠方法構造:用來在初始化bean2的時候,可以初始化其他的東西
public class Bean2 {
	
	//靜態方法,用來返回對象的實例
	public static Bean2 getBean2(){
		//在做實例化的時候,可以做其他的事情,即可以在這裏寫初始化其他對象的代碼
		//Connection conn....
		return new Bean2();
	}

}

第二步:Spring的容器applicationContext.xml

<!-- 
	2:靜態工廠的方式創建bean 
	用來自己定義一下工廠,讓spring的大工廠來調用我們的小工廠,可以將對象的創建權限交給小工廠
	factory-method:工廠的靜態方法,在bean的實例化的時候,會自動調用
	-->
	<bean id="bean2" class="com.igeek.Bean2" factory-method="getBean2"/>

第三步:測試類進行測試

@Test
	public void test2(){
		//先構建實例化獲取spring的容器(工廠、上下文)
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		//2.靜態工廠
		Bean2 bean2=(Bean2) applicationContext.getBean("bean2");
		System.out.println(bean2);
	}

第三種方式: 實例工廠方法
第一步:創建Bean3.java

//第三種bean,實例工廠方式創建
public class Bean3 {

}

第二步:創建實例工廠Bean3Factory類

//實例工廠:必須new工廠--》bean
public class Bean3Factory {
	//普通的方法,非靜態方法
	public Bean3 getBean3(){
		//初始化實例對象返回
		return new Bean3();
	}
}

第三步:Spring容器的配置:applicationContext.xml

 <!-- 3:實例工廠的方式實例化bean -->
	<bean id="bean3Factory" class="com.igeek.Bean3Factory"/>
	<!-- factory-bean相當於ref:引用一個bean對象 -->
	<bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3"/>
	

第四步:使用測試代碼,進行測試:

@Test
	public void test3(){
		//先構建實例化獲取spring的容器(工廠、上下文)
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		//3.實例工廠
		Bean3 bean3=(Bean3) applicationContext.getBean("bean3");
		System.out.println(bean3);
	}

第四種方式:FactoryBean方式。(源碼底層用的多)
第一步:創建Bean4.java

public class Bean4 {

}

第二步:創建工廠Bean,Bean4FactoryBean.java,實現FactoryBean的接口

//4。實現FactoryBean接口的方式
//泛型:你要返回什麼類型的對象,泛型就是什麼
public class Bean4FactoryBean implements FactoryBean<Bean4>{
	//用來獲取bean的實例,對象
	public Bean4 getObject() throws Exception {
		//寫一些初始化數據庫連接等等其他代碼
		return new Bean4();
	}
	public Class<?> getObjectType() {
		return null;
	}
	public boolean isSingleton() {
		return false;
	}
}

FactoryBean提供getObject方法,返回目標類型對象.
第三步:spring容器中的配置

<!-- 4.實現接口FactoryBean的方法
	spring在準備實例化bean的時候,new Bean4FactoryBean,沒急着返回bean對象。
	會判斷,類型對象是否實現了FactoryBean接口,如果實現了,就調用接口的getObject()方法,得到bean的示例-返回。
	 -->
	<bean id="bean4" class="com.igeek.Bean4FactoryBean"/>

Bean4對象是 Bean4的類型(FactoryBean的getObject返回類型 )
第四步:測試

@Test
	public void test4(){
		//先構建實例化獲取spring的容器(工廠、上下文)
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		//3.實例工廠
		Bean4 bean4=(Bean4) applicationContext.getBean("bean4");
		System.out.println(bean4);
	}

小結:
Spring容器的配置:看一下4種方式

<?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的方式 -->
	<!-- 1.:默認構造器 
	在實例化的時候,自動調用默認的構造器,相當於Bean1 bean1 =new Bean1();
	-->
	<bean id="bean1" class="com.igeek.Bean1"/>
	<!-- 
	2:靜態工廠的方式創建bean 
	用來自己定義一下工廠,讓spring的大工廠來調用我們的小工廠,可以將對象的創建權限交給小工廠
	factory-method:工廠的靜態方法,在bean的實例化的時候,會自動調用
	-->
	<bean id="bean2" class="com.igeek.Bean2" factory-method="getBean2"/>
	<!-- 3:實例工廠的方式實例化bean -->
	<bean id="bean3Factory" class="com.igeek.Bean3Factory"/>
	<!-- factory-bean相當於ref:引用一個bean對象 -->
	<bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3"/>
	<!-- 4.實現接口FactoryBean的方法
	spring在準備實例化bean的時候,new Bean4FactoryBean,沒急着返回bean對象。
	會判斷,類型對象是否實現了FactoryBean接口,如果實現了,就調用接口的getObject()方法,得到bean的示例-返回。
	 -->
	<bean id="bean4" class="com.igeek.Bean4FactoryBean"/>
	
</beans>

【四種方式】小結:
第一種:最常用
第二、第三種:一些框架初始化的時候用的多。
第三、第四種:spring底層用的多。

【面試題】 BeanFactory和FactoryBean的區別?
BeanFactory:是一個工廠(其實是構建了一個spring上下文的環境,容器),用來管理和獲取很多Bean對象,例如:加載applicationContext.xml文件。
FactoryBean:是一個Bean生成工具,是用來獲取一種類型對象的Bean,它是構造Bean實例的一種方式。

4.2Bean的作用域

由spring創建的bean對象在什麼情況下有效。
在這裏插入圖片描述
【附錄】:什麼是Portal,參考百度百科
在這裏插入圖片描述
項目開發中通常會使用:singleton 單例、 prototype多例
Singleton: 在一個spring容器中,對象只有一個實例。(默認值)
Prototype: 在一個spring容器中,存在多個實例,每次getBean 返回一個新的實例。
建立包:com.igeek.scope
第一步:創建類SingletonBean.java和PrototypeBean.java
創建類SingletonBean.java類

//單例bean
public class SingletonBean {
	public SingletonBean() {
		System.out.println("SingletonBean:初始化了單例");
	}
}

創建類PrototypeBean.java類

//多例bean
public class Prototy peBean {
	public PrototypeBean() {
		System.out.println("--PrototypeBean初始化了多例的");
	}
}

第二步:定義spring容器,applicationContext.xml:

  <!-- 
		bean的作用範圍
		scope:配置作用範圍的,默認值就是singleton單例
	 -->
	<!-- 單例 -->
	<!-- <bean id="singletonBean" class="com.igeek.scope.SingletonBean" scope="singleton"/> -->
	<bean id="singletonBean" class="com.igeek.scope.SingletonBean"/>
	<!-- 多例 -->
	<bean id="prototypeBean" class="com.igeek.scope.PrototypeBean" scope="prototype"/>

第三步:測試代碼,創建SpringTest.java:

//newbean的方式
public class SpringTest {
	
	@Test
	public void testScope(){
		//先構建實例化獲取spring的容器(工廠、上下文)
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		//目標1:看看多次獲取bean的時候,是不是同一個
		//目標2:看看bean什麼時候初始化的
		//獲取單例的bean:應該是同一個
		//單例:每次從spring容器中獲取的對象,是同一個對象
		//單例初始化:是在spring容器初始化的時候,就初始化了
		SingletonBean singletonBean1=(SingletonBean)applicationContext.getBean("singletonBean");
		SingletonBean singletonBean2=(SingletonBean)applicationContext.getBean("singletonBean");
		System.out.println(singletonBean1);
		System.out.println(singletonBean2);
		//獲取多例的bean:
		//多例:每次從spring容器中獲取的對象,不是同一個對象
		//多例初始化:是在getBean的時候初始化,相當於每次getbean就是在new Bean()
		PrototypeBean prototypeBean1=(PrototypeBean)applicationContext.getBean("prototypeBean");
		PrototypeBean prototypeBean2=(PrototypeBean)applicationContext.getBean("prototypeBean");
		System.out.println(prototypeBean1);
		System.out.println(prototypeBean2);
		
	}

}

運行查看,測試結果:
在這裏插入圖片描述
【注意】
單例是默認值,如果需要單例對象,則不需要配置scope。

4.3Bean的生命週期

通過spring工廠,可以控制bean的生命週期。

4.3.1在xml配置Bean的初始化和銷燬方法

通過 init-method屬性 指定初始化後的調用方法
通過 destroy-method屬性 指定銷燬對象前的方法

創建包com.igeek.xmllifecycle

第一步:創建LifeCycleBean,指定一個init的方法,和一個destroy的方法。

//測試生命週期過程中的初始化和銷燬bean
public class LifeCycleBean {

	//定義構造方法
	public LifeCycleBean() {
		System.out.println("LifeCycleBean構造器調用了");
	}
	
	//初始化後自動調用方法:方法名隨意,但也不能太隨便,一會要配置
	public void init(){
		System.out.println("LifeCycleBean-init初始化時調用");
	}

	// 業務方法
	public void save(){
		System.out.println("第六步:調用了LifeCycleBean類的save方法!");
	}
	
	//bean銷燬時調用的方法
	public void destroy(){
		System.out.println("LifeCycleBean-destroy銷燬時調用");
	}

}

第二步:Spring的核心容器,applicationContext.xml的配置

<!-- 生命週期調用的兩個方法 
	init-method:初始化時(後)調用的,bean中的共有方法即可
	destroy-method:銷燬時(前)被調用的。
	-->
	<bean id="lifeCycleBean" class="com.igeek.xmllifecycle.LifeCycleBean" init-method="init" destroy-method="destroy" scope="singleton"/>
	

第三步:SpringTest.java測試代碼:

@Test
	public void test(){
		//先獲取spring的容器,工廠,上下文
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		//對於單例此時已經被初始化
		//獲取bean
		LifeCycleBean lifeCycleBean=(LifeCycleBean) applicationContext.getBean("lifeCycleBean");
		System.out.println(lifeCycleBean);

        lifeCycleBean.save();
		//爲什麼沒有銷燬方法調用。
		//原因是:使用debug模式jvm直接就關了,spring容器還沒有來得及銷燬對象。
		//解決:手動關閉銷燬spring容器,自動銷燬單例的對象
		((ClassPathXmlApplicationContext)applicationContext).close();
		
	}

測試查看控制檯打印,發現銷燬方法沒有執行。

原因:銷燬方法的執行必須滿足兩個條件:
1)單例(singleton)的bean纔會可以手動銷燬。
2)必須手動關閉容器(調用close的方法)時,纔會執行手動銷燬的方法。

換成單列模式scope=“singleton”,控制檯輸出結果是:在這裏插入圖片描述

【擴展】
關於數據(一些屬性等等)的初始化的。
1.直接賦值
2.在構造器中初始化
3.使用單獨的初始化的方法

//測試生命週期過程中的初始化和銷燬bean
public class LifeCycleBean {
	//成員變量
	private String name="Tom";//1.賦值成員變量
	
	//2.構造器初始化
	public LifeCycleBean() {
		System.out.println("LifeCycleBean構造器調用了");
        this.name="Rose";
	}
	
	//初始化後自動調用方法:方法名隨意,但也不能太隨便,一會要配置
	public void init(){
		System.out.println("LifeCycleBean-init初始化時調用");
		//3.單獨的初始化方法來初始化數據
		this.name="Jack";
	}
	
	//bean銷燬時調用的方法
	public void destroy(){
		System.out.println("LifeCycleBean-destroy銷燬時調用");
		System.out.println(name);
	}
}

三種方式:根據代碼情況任選。
第一種方式:直接的,但耦合性最強。一般用於給默認值的。
第二種方式:使用有參構造來初始化。代碼new的時候就能直接將屬性初始化,但有點耦合。
使用set方法對屬性進行賦值。
第三種方式:使用單獨的方法,來初始化。完全解耦,初始化方法專門用來寫初始化的一系列代碼,構造器,只是用來構造class對象。

4.3.2 後處理Bean(BeanPostProcessor接口) 瞭解

後處理Bean也稱之爲Bean的後處理器,作用是:在Bean初始化的前後,對Bean對象進行增強。它既可以增強一個指定的Bean,也可以增強所有的Bean,底層很多功能(如AOP等)的實現都是基於它的,Spring可以在容器中直接識別調用。

【示例】
要對“所有”的bean的初始化的時候進行增強(打印一句話)
第一步:創建MyBeanPostProcessor類,實現接口BeanPostProcessor

//後處理bean,:用來對bean進行功能增強,可以實現,對所有,或某個bean的初始化進行增強
public class MyBeanPostProcessor implements BeanPostProcessor{

	//初始化時(之前)調用的
	//參數1:bean對象,參數2,bean的名字,id、name
	public Object postProcessBeforeInitialization(Object bean, String beanName)
			throws BeansException {
//		System.out.println(beanName+"在初始化前開始增強了");
		//如何只增強一個bean
		if(beanName.equals("lifeCycleBean")){
			System.out.println(beanName+"在初始化前開始增強了");
		}
		return bean;//放行
	}

	//初始化時(之後)調用
	public Object postProcessAfterInitialization(Object bean, String beanName)
			throws BeansException {
//		System.out.println(beanName+"在初始化後開始增強了");
		if(beanName.equals("lifeCycleBean")){
			System.out.println(beanName+"在初始化後開始增強了");
		}
		return bean;
	}

}

第二步:定義applicationContext.xml文件

<!-- 後處理bean:spring在初始化MyBeanPostProcessor的時候,判斷是否實現了BeanPostProcessor,如果實現了,就採用動態代理的方式,對所有的bean對象增強 -->
	<bean class="com.igeek.xmllifecycle.MyBeanPostProcessor"/>

執行任意bean操作的測試,控制檯輸出:在這裏插入圖片描述
注意調用順序。
BeanPostProcessor接口,提供增強途徑,在不修改原來代碼情況下,增添新的功能!

4.4Bean屬性的依賴注入

創建包com.igeek.xmlpropertydi

4.4.1屬性依賴注入的三種方式

什麼是Bean屬性的注入?就是對一個對象的屬性賦值。有三種方式:

第一種:構造器參數注入
第二種:setter方法屬性注入(setter方法的規範需要符合JavaBean規範)
第三種:接口注入
在這裏插入圖片描述
Spring 框架規範中通過配置文件配置的方式,只支持構造器參數注入和setter方法屬性注入,不支持接口注入 !

4.4.2構造器參數注入 constructor-arg

【示例】
第一步:構造器參數注入屬性值。
創建包com.igeek.xmlpropertydi,創建Car類,定義構造方法

//目標,構造器參數注入,new car直接將參數的值直接賦值
public class Car {
	private Integer id;
	private String name;
	private Double price;
	//有參構造
	public Car(Integer id, String name, Double price) {
		this.id = id;
		this.name = name;
		this.price = price;
	}
	
	//取值要用getter
	public Integer getId(){
		return this.id;
	}
	
	
	public String toString() {
		return "Car [id=" + id + ", name=" + name + ", price=" + price + "]";
	}

}

第二步:配置applicationContext.xml

<!-- 構造器注入屬性的值 -->
	<bean id="car" class="com.igeek.xmlpropertydi.Car">
		<!--constructor-arg:告訴spring容器,要調用有參構造方法了,不再調用默認的構造方法了  
		new Car(1,"寶馬",99999d)
		參數第一組:定位屬性
		    * index:根據索引定位屬性,0表示第一個位置
			* name:根據屬性參數名稱定位屬性
			* type:根據屬性數據類型定位屬性
		參數第二組:值
			* value:簡單的值,字符串
			* ref:複雜的(由spring容器創建的bean對象)
		-->
		<!-- <constructor-arg index="0" value="1"/> -->
		<constructor-arg index="0" name="id" value="1"/>
		<!-- <constructor-arg name="name" value="寶馬1代"/> -->
		<constructor-arg name="name" >
			<value>寶馬2代</value>
		</constructor-arg>
		<constructor-arg type="java.lang.Double" value="99999d"/>
	</bean>

第三步:使用SpringTest.java測試:

@Test
	public void test(){
		//spring容器
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		//獲取car
		Car car =(Car) applicationContext.getBean("car");
	    System.out.println(car);
	}

【補充】
1.定位屬性的標籤,可以混用

<constructor-arg index="0" name="id" value="1"/>

2.自標籤的屬性賦值問題,可以使用子標籤的value,效果和value屬性一樣

<constructor-arg name="name" value="寶馬1代"/>

等同於

<constructor-arg name="name" >
	<value>寶馬2代</value>
</constructor-arg>

4.4.3 setter方法屬性注入 property

使用的默認的構造器(new Bean()),但必須提供屬性的setter方法,使用setter方法也是企業經常使用的屬性注入方式。
兩步:在類中加入setter方法,在配置文件中使用

【示例】
第一步:創建Person.java,定義id、name、car屬性

/**
 * 定義人類
 * setter方法屬性注入
 * 相當於new Person();
 */
public class Person {
	private Integer id;
	private String name;
	private Car car;
	//必須提供setter屬性方法
	public void setId(Integer id) {
		this.id = id;
	}
	public void setName(String name) {
		this.name = name;
	}
	public void setCar(Car car) {
		this.car = car;
	}
	
	@Override
	public String toString() {
		return "Person [id=" + id + ", name=" + name + ", car=" + car + "]";
	}

}

第二步:配置spring容器applicationContext.xml

<!-- setter方法屬性注入:調用默認構造器,相當於new Person() -->
	<bean id="person" class="com.igeek.xmlpropertydi.Person">
		<!-- 
		property:專門進行setter屬性注入用的標籤 。
			* name:setter方法的屬性的名字,例如SetXxx-那麼name的屬性值爲xxx。
			* value:簡單的值
			* ref:bean的名字,對象的引用
		-->
		<property name="id" value="1001"/>
		<property name="name" value="Tom"/>
		<!-- <property name="car" ref="car"/> --><!--等同於-->
		<property name="car">
			<ref bean="car"/>
		</property>
	</bean>

第三步:使用SpringTest.java測試:

@Test
	public void test1(){
		//spring容器
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");		
		//獲取人
		Person person=(Person)applicationContext.getBean("person");
		System.out.println(person);
	}

【擴展】
1.標籤的用法:

<!-- <property name="car" ref="car"/> -->
        <!--等同於-->
		<property name="car">
			<ref bean="car"/>
		</property>

2.深入理解setter方法的屬性注入
拋出問題:裏面的name,是不是必須和類中的private String name;的name一致纔可以呢?能不一樣麼?
可以的!
修改Person.java類。

public class Person {
	private Integer id;
	private String pname;//其中pname和setName方法的屬性不一致,而<property name="name" value="關羽"/>其中的name屬性的值指的是setName()的屬性名稱。
	private Car car;
	//必須提供setter屬性方法
	public void setId(Integer id) {
		this.id = id;
	}
	public void setName(String name) {
		this.pname = name;
	}
	public void setCar(Car car) {
		this.car = car;
	}
	
	public String toString() {
		return "Person [id=" + id + ", pname=" + pname + ", car=" + car + "]";
	}

}

4.4.4 p名稱空間的使用-瞭解

什麼是名稱空間?
作用:Schema區分同名元素。(有點類似於java的包)
在這裏插入圖片描述
回顧:Xmlns沒有前綴是默認的名稱空間。
爲簡化XML文件的配置,Spring2.5版本開始引入了一個新的p名稱空間。簡單的說,它的作用是爲了簡化setter方法屬性依賴注入配置的,它不是真正的名稱空間。
它的使用方法:
p:<屬性名>=“xxx” 引入常量值
p:<屬性名>-ref=“xxx” 引用其它Bean對象

操作步驟:
第一步:引入p名稱空間

<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:p="http://www.springframework.org/schema/p"
       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">

第二步:將 子元素 簡化爲 元素的屬性注入

<!-- 使用p名稱空間簡化setter方法屬性注入 -->
<!--
p:name:簡單數據類型的屬性注入
P:car-ref:複雜數據類型(bean)的屬性注入
-->
<bean id="person2" class="com.igeek.xmlpropertydi.Person" p:id="1002" p:name="關羽" p:car-ref="car"/>

第三步:測試

@Test
	public void test2(){
		//spring容器
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person2=(Person)applicationContext.getBean("person2");
		System.out.println(person2);
	}

配置時不需要 子元素,簡化了配置 .

4.4.5spEL表達式的使用 –會用即可

spEL(Spring Expression Language)是一種表達式語言,它是spring3.x版本的新特性。
它的作用是:支持在運行時操作和查詢對象,其語法類似統一的EL語言,但是SpEL提供了額外的功能,功能更強大。
【面試題】什麼是EL、OGNL、spEL?
EL:操作servlet相關的一些對象和相關的值,${request.name}
OGNL:主要操作struts2值棧,<s:property value=”#request.name”>
spEL:操作bean相關的

語法: #{…} , 引用另一個Bean 、屬性、 方法
SpEL表達式的使用功能比較多,Bean操作相關的通常有:
#{beanid} 引用Bean(具體對象)
#{beanId.屬性} 引用Bean的屬性
#{beanId.方法(參數)} 調用Bean的方法

案例一:配置applicationContext.xml

<!-- spEL表達式 -->
<!-- car.name相當於car.getName() -->
<bean id="person3" class="com.igeek.xmlpropertydi.Person" p:id="#{car.id}" p:name="#{car.name}" p:car="#{car}"/>

在這裏插入圖片描述
需要在Car對象中調用getId和getName的方法,獲取id和name的屬性值,然後賦值到Person對象name的屬性中。

public class Car {
    //取值要用getter
	public Integer getId(){
		return this.id;
	}
	
	public String getName(){
		return this.name;
	}
}

案例二:配置applicationContext.xml

<!-- spEL表達式 -->
<!-- car.id相當於car.getId() -->
<bean id="person4" class="com.igeek.xmlpropertydi.Person" p:id="#{1+1}" p:name="#{'Jack'.toUpperCase()}" p:car="#{car}"/>

4.4.6 集合類型屬性注入 (瞭解-使用時查看即可)

作用:主要用於框架整合配置。
Java.utils包中常用集合
(1)List
(2)Set
(3)Map
(4)Properties

Spring爲集合提供了對應的標籤:
<list> 注入 list元素
<set> 注入 set元素
<map> 注入 map元素
<props> 注入 properties 元素 (hashtable類的子類,是特殊的map,key和value都是String )

第一步:創建類CollectionBean.java,並提供set方法用作集合的注入

public class CollectionBean {
	private List<String> list;
	private Set<Integer> set;
	private Map<String, Object> map;
	private Properties properties;//特殊類型的map,key和value都是String
	
	public void setList(List<String> list) {
		this.list = list;
	}
	public void setSet(Set<Integer> set) {
		this.set = set;
	}
	public void setMap(Map<String, Object> map) {
		this.map = map;
	}
	public void setProperties(Properties properties) {
		this.properties = properties;
	}
	
	public String toString() {
		return "CollectionBean [list=" + list + ", set=" + set + ", map=" + map
				+ ", properties=" + properties + "]";
	}

}

第二步:配置spring的核心容器applicationContext.xml

<!-- 集合的屬性注入 -->
	<bean id="collectionBean" class="com.igeek.xmlpropertydi.CollectionBean">
		<!-- setter -->
		<!-- list -->
		<property name="list">
			<list>
				<value>Tom</value>
				<value>Jack</value>
			</list>
		</property>
		<!-- set -->
		<property name="set">
			<set>
				<value>12</value>
				<value>15</value>
			</set>
		</property>
		<!-- map -->
		<property name="map">
			<map>
				<entry key="name" value="張三"/>
				<entry key="age" value="22"/>
                <entry key="car" value-ref="car"></entry>
			</map>
		</property>
		<!-- properties -->
		<property name="properties">
			<props>
				<prop key="name">李四</prop>
				<prop key="age">33</prop>
			</props>
		</property>
	</bean>

第三步:使用SpringTest類進行測試

@Test
	public void test5(){
		//spring容器
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		CollectionBean collectionBean=(CollectionBean)applicationContext.getBean("collectionBean");
		System.out.println(collectionBean);
	}

第四步:輸出結果:
在這裏插入圖片描述

4.4.7 Spring的多個配置文件的開發

一種:創建工廠的時候加載多個配置文件:
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml","applicationContext2.xml");

二種:在一個配置文件中包含另一個配置文件:
<import resource="applicationContext2.xml"></import>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章