Spring是一個非常活躍的開源架構, 它是一個基于IOC和AOP來構架多層JavaEE系統的架構,它的主要目地是簡化企業開發
Spring以一種非侵入式的方式來管理你的代碼, Spring提倡”最少侵入”,這也就意味着你可以适當的時候安裝或解除安裝Spring
Spring架構的首頁:http://www.springsource.org/ Spring
架構下載下傳位址:http://www.springsource.org/download
在項目中引入spring立即可以帶來下面的好處
降低元件之間的耦合度,實作軟體各層之間的解耦。
IOC(依賴注入):包含并管理應用對象的配置和生命周期,你可以配置你的每個bean如何被建立,也可以配置每個bean是隻有一個執行個體,還是每次需要時都生成一個新的執行個體,以及它們是如何互相關聯的
*謂依賴注入就是指:在運作期,由外部容器動态地将依賴對象注入到另一個對象中。
AOP(面向切面):采用了面向切面程式設計來實作很多基礎但是與業務邏輯無關的功能的解耦,比如:事務管理、日志、權限驗證.....
DAO:Spring 還提供了對資料庫JDBC的封裝,使用JdbcTemplate來簡化資料操作
ORM:提供了對主流的對象關系映射架構的支援
JEE: 對Java企業級開發提供了一些解決方案,例如EJB、JMS等
WEB: 提供了自己的Spring MVC和對顯示層架構的集合支援
執行個體化Spring容器常用的兩種方式:
方法一: 在類路徑下尋找配置檔案來執行個體化容器 ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"beans.xml"}); 可以在整個類路徑中尋找xml檔案 * 通過這種方式加載。需要将spring的配置檔案放到目前項目的classpath路徑下 * classpath路徑指的是目前項目的src目錄,該目錄是java源檔案的存放位置。
方法二: 在檔案系統路徑下尋找配置檔案來執行個體化容器 ApplicationContext ctx = new FileSystemXmlApplicationContext(new String[]{“d:\\beans.xml“});
Spring初始化bean或銷毀bean時,有時需要作一些處理工作,是以spring可以在建立和銷毀bean的時候調用bean的兩個生命周期方法。
<bean id=“foo” class=“...Foo” init-method=“setup” destory-method=“teardown”/>
----當bean被載入到容器的時候調用setup
----當bean從容器中删除的時候調用teardown(scope= singleton有效)
singleton(預設值) 在每個Spring IoC容器中一個bean定義隻有一個對象執行個體(共享)。
預設情況下會在容器啟動時初始化bean,但我們可以指定Bean節點的lazy-init=“true”來延遲初始化bean,這時候,隻有第一次擷取bean會才初始化bean。
如: <bean id="xxx" class="cn.itcast.OrderServiceBean" lazy-init="true"/> .
prototype 允許bean可以被多次執行個體化(使用一次就建立一個執行個體)
注入依賴對象可以采用手工裝配或自動裝配,在實際應用中建議使用手工裝配,因為自動裝配會産生未知情況,開發人員無法預見最終的裝配結果。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// 1. 實體類 class User{ } //2. dao class UserDao{ .. 通路db //3. service class UserService{ UserDao userDao = new UserDao(); //4. action class UserAction{ UserService userService = new UserService(); .. 拿到資料或結果 使用者通路: /user.action ----> Tomcat (伺服器建立Action、Service、dao 思考: 1. 對象建立建立能否寫死? 2. 對象建立細節 對象數量 action 多個 【維護成員變量】 service 一個 【不需要維護公共變量】 dao 一個 【不需要維護公共變量】 建立時間 action 通路時候建立 service 啟動時候建立 dao 啟動時候建立 3. 對象的依賴關系 action 依賴 service service依賴 dao ======================================================= 總結: spring就是解決上面的問題的! 簡單來說,就是處理對象的建立的、以及對象的依賴關系! |
2. Spring架構
專業術語了解
元件/架構設計
侵入式設計
引入了架構,對現有的類的結構有影響;即需要實作或繼承某些特定類。
例如: Struts架構
非侵入式設計
引入了架構,對現有的類結構沒有影響。
例如:Hibernate架構 / Spring架構
控制反轉:
Inversion on Control , 控制反轉 IOC
對象的建立交給外部容器完成,這個就做控制反轉.
依賴注入, dependency injection
處理對象的依賴關系
差別:
控制反轉, 解決對象建立的問題 【對象建立交給别人】
依賴注入,
在建立完對象後, 對象的關系的處理就是依賴注入 【通過set方法依賴注入】
AOP
面向切面程式設計。切面,簡單來說來可以了解為一個類,由很多重複代碼形成的類。
切面舉例:事務、日志、權限;
Spring架構
a. 概述
Spring架構,可以解決對象建立以及對象之間依賴關系的一種架構。
且可以和其他架構一起使用;Spring與Struts, Spring與hibernate
(起到整合(粘合)作用的一個架構)
Spring提供了一站式解決方案:
1) Spring Core spring的核心功能: IOC容器, 解決對象建立及依賴關系
2) Spring Web Spring對web子產品的支援。
-à 可以與struts整合,讓struts的action建立交給spring
-à spring mvc模式
3) Spring DAO Spring 對jdbc操作的支援 【JdbcTemplate模闆工具類】
4) Spring ORM spring對orm的支援:
à 既可以與hibernate整合,【session】
à 也可以使用spring的對hibernate操作的封裝
5)Spring AOP 切面程式設計
6)SpringEE spring 對javaEE其他子產品的支援
b. 開發步驟
spring各個版本中:
在3.0以下的版本,源碼有spring中相關的所有包【spring功能 + 依賴包】
如2.5版本;
在3.0以上的版本,源碼中隻有spring的核心功能包【沒有依賴包】
(如果要用依賴包,需要單獨下載下傳!)
1) 源碼, jar檔案:spring-framework-3.2.5.RELEASE
commons-logging-1.1.3.jar 日志
spring-beans-3.2.5.RELEASE.jar bean節點
spring-context-3.2.5.RELEASE.jar spring上下文節點
spring-core-3.2.5.RELEASE.jar spring核心功能
spring-expression-3.2.5.RELEASE.jar spring表達式相關表
以上是必須引入的5個jar檔案,在項目中可以使用者庫管理!
2) 核心配置檔案: applicationContext.xml
Spring配置檔案:applicationContext.xml / bean.xml
限制參考:
spring-framework-3.2.5.RELEASE\docs\spring-framework-reference\htmlsingle\index.html
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> </beans> |
3)Api
public class App { // 1. 通過工廠類得到IOC容器建立的對象 @Test public void testIOC() throws Exception { // 建立對象 // User user = new User(); // 現在,把對象的建立交給spring的IOC容器 Resource resource = new ClassPathResource("cn/itcast/a_hello/applicationContext.xml"); // 建立容器對象(Bean的工廠), IOC容器 = 工廠類 + applicationContext.xml BeanFactory factory = new XmlBeanFactory(resource); // 得到容器建立的對象 User user = (User) factory.getBean("user"); System.out.println(user.getId()); //2. (友善)直接得到IOC容器對象 public void testAc() throws Exception { // 得到IOC容器對象 ApplicationContext ac = new ClassPathXmlApplicationContext("cn/itcast/a_hello/applicationContext.xml"); // 從容器中擷取bean User user = (User) ac.getBean("user"); System.out.println(user); |
bean對象建立的細節
/** * 1) 對象建立: 單例/多例 * scope="singleton", 預設值, 即 預設是單例 【service/dao/工具類】 * scope="prototype", 多例; 【Action對象】 * * 2) 什麼時候建立? * scope="prototype" 在用到對象的時候,才建立對象。 * scope="singleton" 在啟動(容器初始化之前), 就已經建立了bean,且整個應用隻有一個。 * 3)是否延遲建立 * lazy-init="false" 預設為false, 不延遲建立,即在啟動時候就建立對象 * lazy-init="true" 延遲初始化, 在用到對象的時候才建立對象 * (隻對單例有效) * 4) 建立對象之後,初始化/銷毀 * init-method="init_user" 【對應對象的init_user方法,在對象建立愛之後執行 】 * destroy-method="destroy_user" 【在調用容器對象的destriy方法時候執行,(容器用實作類)】 */ // 得到IOC容器對象 【用實作類,因為要調用銷毀的方法】 ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("cn/itcast/a_hello/applicationContext.xml"); System.out.println("-----容器建立-----"); User user1 = (User) ac.getBean("user"); User user2 = (User) ac.getBean("user"); System.out.println(user1); System.out.println(user2); // 銷毀容器對象 ac.destroy(); |
SpringIOC容器
1) 建立對象
SpringIOC容器,是spring核心内容。
作用: 建立對象 & 處理對象的依賴關系
IOC容器建立對象:
建立對象, 有幾種方式:
1) 調用無參數構造器
2) 帶參數構造器
3) 工廠建立對象
工廠類,靜态方法建立對象
工廠類,非靜态方法建立對象
<?xml version="1.0" encoding="UTF-8"?> <!-- ###############對象建立############### --> <!-- 1. 預設無參數構造器 <bean id="user1" class="cn.itcast.b_create_obj.User"></bean> --> <!-- 2. 帶參數構造器 --> <bean id="user2" class="cn.itcast.b_create_obj.User"> <constructor-arg index="0" type="int" value="100"></constructor-arg> <constructor-arg index="1" type="java.lang.String" value="Jack"></constructor-arg> </bean> <!-- 定義一個字元串,值是"Jack" ; String s = new String("jack")--> <bean id="str" class="java.lang.String"> <constructor-arg value="Jacks"></constructor-arg> <bean id="user3" class="cn.itcast.b_create_obj.User"> <constructor-arg index="1" type="java.lang.String" ref="str"></constructor-arg> <!-- 3. 工廠類建立對象 --> <!-- # 3.1 工廠類,執行個體方法 --> <!-- 先建立工廠 --> <bean id="factory" class="cn.itcast.b_create_obj.ObjectFactory"></bean> <!-- 在建立user對象,用factory方的執行個體方法 --> <bean id="user4" factory-bean="factory" factory-method="getInstance"></bean> <!-- # 3.2 工廠類: 靜态方法 --> <!-- class 指定的就是工廠類型 factory-method 一定是工廠裡面的“靜态方法” --> <bean id="user" class="cn.itcast.b_create_obj.ObjectFactory" factory-method="getStaticInstance"></bean> </beans> |
2) 對象依賴關系
Spring中,如何給對象的屬性指派? 【DI, 依賴注入】
1) 通過構造函數
2) 通過set方法給屬性注入值
3) p名稱空間
4)自動裝配(了解)
5) 注解
# (常用)Set方法注入值
<!-- dao instance --> <bean id="userDao" class="cn.itcast.c_property.UserDao"></bean> <!-- service instance --> <bean id="userService" class="cn.itcast.c_property.UserService"> <property name="userDao" ref="userDao"></property> <!-- action instance --> <bean id="userAction" class="cn.itcast.c_property.UserAction"> <property name="userService" ref="userService"></property> |
# 内部bean
<!-- ##############内部bean############## --> <property name="userService"> <bean class="cn.itcast.c_property.UserService"> <property name="userDao"> <bean class="cn.itcast.c_property.UserDao"></bean> </property> |
# p 名稱空間注入屬性值 (優化)
<!-- ###############對象屬性指派############### --> 給對象屬性注入值: # p 名稱空間給對象的屬性注入值 (spring3.0以上版本才支援) <bean id="userDao" class="cn.itcast.c_property.UserDao"></bean> <bean id="userService" class="cn.itcast.c_property.UserService" p:userDao-ref="userDao"></bean> <bean id="userAction" class="cn.itcast.c_property.UserAction" p:userService-ref="userService"></bean> <!-- 傳統的注入: <bean id="user" class="cn.itcast.c_property.User" > <property name="name" value="xxx"></property> </bean> <!-- p名稱空間優化後 --> <bean id="user" class="cn.itcast.c_property.User" p:name="Jack0001"></bean> |
# 自動裝配(了解)
ü 根據名稱自動裝配:autowire="byName"
-à 自動去IOC容器中找與屬性名同名的引用的對象,并自動注入
<!-- ###############自動裝配############### --> <bean id="userDao" class="cn.itcast.d_auto.UserDao"></bean> <bean id="userService" class="cn.itcast.d_auto.UserService" autowire="byName"></bean> <!-- 根據“名稱”自動裝配: userAction注入的屬性,會去ioc容器中自動查找與屬性同名的對象 --> <bean id="userAction" class="cn.itcast.d_auto.UserAction" autowire="byName"></bean> |
也可以定義到全局, 這樣就不用每個bean節點都去寫autowire=”byName”
http://www.springframework.org/schema/context/spring-context.xsd" default-autowire="byName"> 根據名稱自動裝配(全局) <bean id="userDao" class="cn.itcast.d_auto.UserDao"></bean> <bean id="userService" class="cn.itcast.d_auto.UserService"></bean> <bean id="userAction" class="cn.itcast.d_auto.UserAction"></bean> |
ü 根據類型自動裝配:autowire="byType"
必須確定改類型在IOC容器中隻有一個對象;否則報錯。
http://www.springframework.org/schema/context/spring-context.xsd" default-autowire="byType"> <!-- 如果根據類型自動裝配: 必須確定IOC容器中隻有一個該類型的對象 --> <!-- 報錯: 因為上面已經有一個該類型的對象,且使用了根據類型自動裝配 <bean id="userService_test" class="cn.itcast.d_auto.UserService" autowire="byType"></bean> </beans> |
Spring提供的自動裝配主要是為了簡化配置; 但是不利于後期的維護。
(一般不推薦使用)
# 注解
注解方式可以簡化spring的IOC容器的配置!
使用注解步驟:
1)先引入context名稱空間
xmlns:context="http://www.springframework.org/schema/context"
2)開啟注解掃描
<context:component-scan base-package="cn.itcast.e_anno2"></context:component-scan>
3)使用注解
通過注解的方式,把對象加入ioc容器。
建立對象以及處理對象依賴關系,相關的注解:
@Component 指定把一個對象加入IOC容器
@Repository 作用同@Component; 在持久層使用
@Service 作用同@Component; 在業務邏輯層使用
@Controller 作用同@Component; 在控制層使用
@Resource 屬性注入
1) 使用注解,可以簡化配置,且可以把對象加入IOC容器,及處理依賴關系(DI)
2) 注解可以和XML配置一起使用。