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>