SSH框架之Spring第一篇
- 2019 年 10 月 6 日
- 筆記
版權聲明:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接:https://blog.csdn.net/zhao1299002788/article/details/101167712
1.1. spring概述: 1.1.1 spring介紹 : Spring是分層的Java SE/EE應用 full-stack輕量級開源框架,以IoC(Inverse Of Control : 反轉控制) 和 AOP(Aspect Oriented Programming : 面向切面編程) 為內核,提供了展現層SpringMVC和持久層Spring JDBC以及業務層事務管理等眾多的企業級應用技術,還能整合開源世界眾多著名的第三方框架和類庫,成為使用最多的JavaEE企業開源框架. 1.1.3 spring的優勢 方便解耦,簡化開發. 通過Spring提供的IoC容器,可以將對象間的依賴關係交由Spring進行控制,避免硬編碼所造成的過渡程序耦合.用戶也不必再為單例模式類,屬性文件解析等這些很底層的需求編寫代碼, 可以更專註於上層的應用. AOP編程的支撐 通過Spring的AOP功能,方便進行面向切面的編程,許多不容易用傳統OOP實現的功能可以通過AOP輕鬆應付. 聲明式事務的支持 可以將我們從單調煩悶的事務管理代碼中解脫出來,通過聲明式方式靈活的進行事務的管理,提高開發效率和質量. 方便程序的測試 可以用非容器依賴的編程方式進行幾乎所有的的測試工作,測試不再是昂貴的操作,而是隨手可做的事情. 方便集合各種優秀框架 Spring可以降低各種框架的使用難度,提供了對各種優秀框架(Struts,Hibernate,Hessian,Quartz等)的直接支持. 降低JavaEE API的使用難度 Spring對JavaEE API(如JDBC,JavaMail,遠程調用等)進行了薄薄的封裝層,是這些API的使用難度大為降低. Java源碼是經典學習範例 Spring的源代碼設計精妙,結構清晰,匠心獨用,處處體現着大師對Java設計模式靈活運用以及對Java技術的高深造詣.它的源代碼無意是Java技術的最佳實踐的範例. 1.1.4 spring的體系結構 1.2 程序的耦合和解耦: 1.2.1 什麼是程序的耦合 類之間不可避免的產生依賴關係,這種依賴關係稱之為耦合. 在開發中,理想的狀態應該是 : 我們應該儘力達到的 : 編譯時不依賴,運行時才依賴. 1.2.2 解決程序耦合的思路 : 使用配置文件 1.2.3 工廠模式解耦: 在實際開發中我們把所有的dao和service和action對象使用配置文件配置起來,當啟動服務器應用加載的時候,通過讀取配置文件, 把這些對象創建出來並存起來.在接下來的使用的時候,直接拿過來用就好了. 1.2.4 控制反轉 (Inversion Of Control) IOC技術 : 出現的目的解決耦合性過高的問題. IOC : 控制反轉,將對象的創建的權利反轉給Spring框架. 控制反轉,它是spring框架的核心之一。 它的作用只有一個:削減計算機程序的耦合。 1.3 入門的步驟: IOC的入門 1.3.1 創建web工程,下載Spring的jar包 1.3.2 在工程中導入IOC需要的jar包(6個) 1.3.3 編寫UserDao接口和UserDaoImpl實現類 1.3.4 把UserDaoImpl交給Spring的IOC容器管理,其實編寫配置文件即可. 在src目錄下創建applicationContext.xml配置 導入約束 配置UserDaoImpl <!-- 管理實現類的 --> <bean id="ud" class="com.baidu.demo1.UserDaoImpl"></bean> 1.3.5 創建Spring的工廠,加載applicationContext.xml配置文件,從工廠中獲取到UserBean對象,調用方法. public void run1() { //創建工廠,加載applicationContext.xml配置文件 ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); //從工廠中獲取到對象 UserDao dao = (UserDao)ac.getBean("ud"); //調用對象的方法 dao.login(); } 3.1 Spring基於XML的IOC細節 3.1.1 BeanFactory和ApplicationContext的區別 BeanFactory才是Spring容器中的頂層接口. ApplicationContext是它的子接口. BeanFactory和ApplicationContext的區別: 創建對象的時間點不一樣. ApplicationContext : 只要一讀取配置文件,默認情況下就會創建對象. BeanFactory : 什麼時候使用什麼時候創建對象. ClassPathXmlApplicationContext : 是加載相對路徑,就是項目下的路徑. FileSystemXmlApplicationContext : 是加載絕對路徑,就是把xml文件放在任意磁盤下都可以加載. 3.1.2 bean標籤 : IOC容器bean的管理,管理實現類的.把實現類交給IOC容器創建維護 id : 自己起唯一的名稱 class : 管理類的全路徑(包名+類名) scope : 創建後對象的作用的範圍 singleton : 單例的,默認值 (所謂單例:就是在內存中只有這一個對象) scope="singleton" 一個應用只有一個對象的實例。它的作用範圍就是整個引用。 生命周期: 對象出生:當應用加載,創建容器時,對象就被創建了。 對象活着:只要容器在,對象一直活着。 對象死亡:當應用卸載,銷毀容器時,對象就被銷毀了。 prototype : 多例的 每次訪問對象時,都會重新創建對象實例。 生命周期: 對象出生:當使用對象時,創建新的對象實例。 對象活着:只要對象在使用中,就一直活着。 對象死亡:當對象長時間不用時,被java的垃圾回收器回收了。 了解的以下都是多例的 request : WEB項目中,Spring創建一個Bean的對象,將對象存入到request域中. session : WEB項目中,Spring創建一個Bean的對象,將對象存入到session域中. globalSession : 全局的session(可以在多個服務器之間共享數據) WEB項目中,應用在Portlet環境.如果沒有Portlet環境那麼globalSession相當於session. init-method : 初始化方法 destroy-method : 銷毀的方法 3.2.3 實例化的Bean的三種方式: 第一種方式:使用默認無參構造函數 <!--在默認情況下: 它會根據默認無參構造函數來創建類對象。如果bean中沒有默認無參構造函數,將會創建失敗。 --> <bean id="customerService" class="com.baidu.service.impl.CustomerServiceImpl"/> 第二種方式:spring管理靜態工廠-使用靜態工廠的方法創建對象 /** * 模擬一個靜態工廠,創建業務層實現類 */ public class StaticFactory { public static ICustomerService createCustomerService(){ return new CustomerServiceImpl(); } } <!-- 此種方式是: 使用StaticFactory類中的靜態方法createCustomerService創建對象,並存入spring容器 id屬性:指定bean的id,用於從容器中獲取 class屬性:指定靜態工廠的全限定類名 factory-method屬性:指定生產對象的靜態方法 --> <bean id="customerService" class="com.baidu.factory.StaticFactory" factory-method="createCustomerService"></bean> 第三種方式:spring管理實例工廠-使用實例工廠的方法創建對象 /** * 模擬一個實例工廠,創建業務層實現類 * 此工廠創建對象,必須現有工廠實例對象,再調用方法 */ public class InstanceFactory { public ICustomerService createCustomerService(){ return new CustomerServiceImpl(); } } <!-- 此種方式是: 先把工廠的創建交給spring來管理。 然後在使用工廠的bean來調用裏面的方法 factory-bean屬性:用於指定實例工廠bean的id。 factory-method屬性:用於指定實例工廠中創建對象的方法。 --> <bean id="instancFactory" class="com.baidu.factory.InstanceFactory"></bean> <bean id="customerService" factory-bean="instancFactory" factory-method="createCustomerService"></bean> 3.3 spring依賴注入 3.3.1 依賴注入的概念 : 它是spring框架核心,ioc的具體實現方式.簡單的說,就是坐等框架把對象傳入,而不用我們自己 去獲取. 3.3.2 依賴注入 : 依賴 : service成功運行的話,需要用到dao,service依賴dao. 注入 : service和dao都交給了IOC容器管理,把dao對象傳入到service對象中呢? 3.3.2.1 構造函數注入 使用類中的構造函數,給成員變量賦值.注意,賦值的操作不是我們自己做的,而是通過配置的方式,讓spring 框架來為我們注入. 如下: /** */ public class CustomerServiceImpl implements ICustomerService { private String name; private Integer age; private Date birthday; public CustomerServiceImpl(String name, Integer age, Date birthday) { this.name = name; this.age = age; this.birthday = birthday; } @Override public void saveCustomer() { System.out.println(name+","+age+","+birthday); } } <!-- 使用構造函數的方式,給service中的屬性傳值 要求: 類中需要提供一個對應參數列表的構造函數。 涉及的標籤: constructor-arg 屬性: index:指定參數在構造函數參數列表的索引位置 type:指定參數在構造函數中的數據類型 name:指定參數在構造函數中的名稱 用這個找給誰賦值 =======上面三個都是找給誰賦值,下面兩個指的是賦什麼值的============== value:它能賦的值是基本數據類型和String類型 ref:它能賦的值是其他bean類型,也就是說,必須得是在配置文件中配置過的bean --> <bean id="customerService" class="com.baidu.service.impl.CustomerServiceImpl"> <constructor-arg name="name" value="張三"></constructor-arg> <constructor-arg name="age" value="18"></constructor-arg> <constructor-arg name="birthday" ref="now"></constructor-arg> </bean> <bean id="now" class="java.util.Date"></bean> 3.3.3 set方法注入 就是在類中提供需要注入成員的set方法。具體代碼如下: /** */ public class CustomerServiceImpl implements ICustomerService { private String name; private Integer age; private Date birthday; public void setName(String name) { this.name = name; } public void setAge(Integer age) { this.age = age; } public void setBirthday(Date birthday) { this.birthday = birthday; } @Override public void saveCustomer() { System.out.println(name+","+age+","+birthday); } } <!-- 通過配置文件給bean中的屬性傳值:使用set方法的方式 涉及的標籤: property 屬性: name:找的是類中set方法後面的部分 ref:給屬性賦值是其他bean類型的 value:給屬性賦值是基本數據類型和string類型的 實際開發中,此種方式用的較多。 --> <bean id="customerService" class="com.baidu.service.impl.CustomerServiceImpl"> <property name="name" value="test"></property> <property name="age" value="21"></property> <property name="birthday" ref="now"></property> </bean> <bean id="now" class="java.util.Date"></bean> 3.3.4 使用p名稱空間注入數據(本質還是調用set方法) 此種方式是通過在xml中導入p名稱空間,使用p:propertyName來注入數據,它的本質仍然是調用類中的set方法實現注入功能。 Java類代碼: /** * 使用p名稱空間注入,本質還是調用類中的set方法 */ public class CustomerServiceImpl4 implements ICustomerService { private String name; private Integer age; private Date birthday; public void setName(String name) { this.name = name; } public void setAge(Integer age) { this.age = age; } public void setBirthday(Date birthday) { this.birthday = birthday; } @Override public void saveCustomer() { System.out.println(name+","+age+","+birthday); } } 配置文件代碼: <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"> <bean id="customerService" class="com.baidu.service.impl.CustomerServiceImpl4" p:name="test" p:age="21" p:birthday-ref="now"/> </bean> 3.3.5 注入集合屬性 就是給類中的集合成員傳值,它用的也是set方法注入的方式,只不過變量的數據類型都是集合. /** */ public class CustomerServiceImpl implements ICustomerService { private String[] myStrs; private List<String> myList; private Set<String> mySet; private Map<String,String> myMap; private Properties myProps; public void setMyStrs(String[] myStrs) { this.myStrs = myStrs; } public void setMyList(List<String> myList) { this.myList = myList; } public void setMySet(Set<String> mySet) { this.mySet = mySet; } public void setMyMap(Map<String, String> myMap) { this.myMap = myMap; } public void setMyProps(Properties myProps) { this.myProps = myProps; } @Override public void saveCustomer() { System.out.println(Arrays.toString(myStrs)); System.out.println(myList); System.out.println(mySet); System.out.println(myMap); System.out.println(myProps); } } <!-- 注入集合數據 List結構的: array,list,set Map結構的 map,entry,props,prop --> <bean id="customerService" class="com.baidu.service.impl.CustomerServiceImpl"> <!-- 在注入集合數據時,只要結構相同,標籤可以互換 --> <!-- 給數組注入數據 --> <property name="myStrs"> <set> <value>AAA</value> <value>BBB</value> <value>CCC</value> </set> </property> <!-- 注入list集合數據 --> <property name="myList"> <array> <value>AAA</value> <value>BBB</value> <value>CCC</value> </array> </property> <!-- 注入set集合數據 --> <property name="mySet"> <list> <value>AAA</value> <value>BBB</value> <value>CCC</value> </list> </property> <!-- 注入Map數據 --> <property name="myMap"> <props> <prop key="testA">aaa</prop> <prop key="testB">bbb</prop> </props> </property> <!-- 注入properties數據 --> <property name="myProps"> <map> <entry key="testA" value="aaa"></entry> <entry key="testB"> <value>bbb</value> </entry> </map> </property> </bean>