Spring框架學習總結(上)
目錄
@
1、Spring的概述
在學習SSM框架中,我建議初學者最好先學Spring框架,其次mybatis接着springMVC,先學mybatis當然也是可以的,今天我們就以絕對優雅的姿態闖進Spring世界,系好安全帶,準備好了嗎,出發了哦!!!咳咳….平時開發接觸最多的估計就是IOC容器,它可以裝載bean(所謂的bean也就是我們java中的類,當然也包括servicedao裏面),有了這個機制,我們就不用在每次使用這個類的時候為它初始化,很少看到鍵字new。另外spring的aop,事務管理等等都是我們經常用到的,可見Spring的尤為重要的作用Spring的核心是控制反轉(IoC)和面向切面(AOP)
1.1什麼是Spring
肯定有熊dei會問SE/EE開發的一站式框架所謂的一站式是什麼意思,(哼,人類,我早就猜到你會問了)
所謂一站式框架指的是有EE開發的每一層解決方案。
WEB層 :SpringMVC
Service層 :Spring的Bean管理,Spring聲明式事務
DAO層 :Spring的Jdbc模板,Spring的ORM模塊
1.2為什麼學習Spring
俗話說,人狠話不多(兄嘚看圖)
1.3Spring的版本
Spring3.x、Spring4.x和Spring5.x
1.4Spring的體繫結構
正所謂,人狠話不多(兄嘚看圖)
2、Spring的入門(IOC)
2.1什麼IOC
一說起IOC我就想起了武哥對IOC的理解的幾個例子,可謂通俗易懂,非常適合剛入門Spring的兄嘚!有興趣的可以去了解了解武哥,武哥博客:https://blog.csdn.net/eson_15
IOC(Inverse of Control):控制反轉,也可以稱為依賴倒置。
控制反轉:將對象的創建權反轉給(交給)Spring。
所謂依賴,從程序的角度看,就是比如A要調用B的方法,那麼A就依賴於B,反正A要用到B,則A依
賴於B。所謂倒置,你必須理解如果不倒置,會怎麼著,因為A必須要有B,才可以調用B,如果不倒
置,意思就是A主動獲取B的實例:B b = new B(),這就是最簡單的獲取B實例的方法(當然還有各種
設計模式可以幫助你去獲得B的實例,比如工廠、Locator等等),然後你就可以調用b對象了。所
以,不倒置,意味着A要主動獲取B,才能使用B;到了這裏,就應該明白了倒置的意思了。倒置就是
A要調用B的話,A並不需要主動獲取B,而是由其它人自動將B送上門來。
2.2通俗理解IOC
形象的舉例就是:
通常情況下,假如你有一天在家裡口渴了,要喝水,那麼你可以到你小區的小賣部去,告訴他們,你需要一瓶水,然後小賣部給你一瓶水!這本來沒有太大問題,關鍵是如果小賣部很遠,那麼你必須知道:從你家如何到小賣部;小賣部里是否有你需要的水;你還要考慮是否開着車去;等等等等,也許有太多的問題要考慮了。也就是說,為了一瓶水,你還可能需要依賴於車等等這些交通工具或別的工具,問題是不是變得複雜了?那麼如何解決這個問題呢?
解決這個問題的方法很簡單:小賣部提供送貨上門服務,凡是小賣部的會員,你只要告知小賣部你需要什麼,小賣部將主動把貨物給你送上門來!這樣一來,你只需要做兩件事情,你就可以活得更加輕鬆自在:
第一:向小賣部註冊為會員。
第二:告訴小賣部你需要什麼。
這和Spring的做法很類似!Spring就是小賣部,你就是A對象,水就是B對象
第一:在Spring中聲明一個類:A
第二:告訴Spring,A需要B
假設A是UserAction類,而B是UserService類
<bean id="userService" class="org.leadfar.service.UserService"/>
<bean id="documentService" class="org.leadfar.service.DocumentService"/>
<bean id="orgService" class="org.leadfar.service.OrgService"/>
<bean id="userAction" class="org.leadfar.web.UserAction">
<property name="userService" ref="userService"/>
</bean>
在Spring這個商店(工廠)中,有很多對象/服務:userService,documentService,orgService,也有很多會員:userAction等等,聲明userAction需要userService即可,Spring將通過你給它提供的通道主動把userService送上門來,因此UserAction的代碼示例類似如下所示:
package org.leadfar.web;
public class UserAction{
private UserService userService;
public String login(){
userService.valifyUser(xxx);
}
public void setUserService(UserService userService){
this.userService = userService;
}
}
在這段代碼裏面,你無需自己創建UserService對象(Spring作為背後無形的手,把UserService對象通過你定義的setUserService()方法把它主動送給了你,這就叫依賴注入!),當然咯,我們也可以使用註解來注入。Spring依賴注入的實現技術是:動態代理
2.3下載Spring的開發包以及解壓說明
官網下載:http://spring.io/
什麼?不會下載?what???
好吧,已打包好了QAQ:https://pan.baidu.com/s/18wyE-5SRWcCu12iPOX56pg
什麼?沒有網盤?what???
有事請燒香謝謝…
解壓之後,文件說明:
docs :Spring的開發規範和API
libs :Spring的開發的jar和源碼
schema :Spring的配置文件的約束
2.4創建web項目,引入jar包
2.5創建普通接口和實現類
創建普通接口,定義一個eat方法
package com.gx.sping;
public interface IUserDao {
public void eat();
}
創建普通實現類
package com.gx.sping;
public class UserDaoimpl implements IUserDao {
@Override
public void eat() {
// TODO Auto-generated method stub
System.out.println(用戶eat了");
}
}
2.6Spring的IOC底層實現原理
創建普通接口和類出現的問題:
如果底層的實現切換了,需要修改源代碼,能不能不修改程序源代碼對程序進行擴展?
重點來了,要想不改變源碼,Spring的IOC就能實現!如下圖:Spring的IOC底層實現
2.7將實現類交給Spring管理
1、在classpath下(也就是src)創建一個XML文件
2、文件名最好統一叫applicationContext.xml
3、其xml文件的內容頭為schema約束
4、約束文件位置在spring的解壓路徑下lspring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html\xsd-configuration.htm
5、不要求xml文件的內容頭能夠背出來,但要了解的是你要知道它是怎麼來的
6、xml文件的內容頭添加后,將實現類交給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">
<!-- 實現類UserDaoimpl交給Spring管理 -->
<bean id="IuserDao" class="com.gx.Ioc.UserDaoimpl" ></bean>
</beans>
2.8編寫測試類
package com.gx.Ioc;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpingDemo1 {
@Test
public void demo11() {
// 面向接口傳統方式
UserDaoimpl userdao = new UserDaoimpl();
userdao.eat();
}
//Spring的bean管理方式
@Test
public void demo22() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
IUserDao userdao = (IUserDao) applicationContext.getBean("IuserDao");
userdao.eat();
}
}
兄嘚,如果測試不成功最好看看二者是否對應!!!
兄dei,到這裏,Spring的入門(IOC)算是入門了,是不是覺得很有成就感啊?
拉倒吧! 我都不好意思說了.(兄dei,我錯了,是我飄了,呀呀呀,兄dei別打臉鴨QAQ)
但是我依舊是阻止不了你驕傲的心.
那就頂我,讓我感受感受你的驕傲!哈哈哈QAQ
2.9 IOC和DI
IOC不是什麼技術,而是一種設計思想,IOC能指導我們如何設計出松耦合、更優良的程序。傳統應用程序都是由我們在類內部主動創建依賴對象,從而導致類與類之間高耦合,難於測試;有了IoC容器后,把創建和查找依賴對象的控制權交給了Spring容器,由容器進行注入組合對象,所以對象與對象之間是鬆散耦合,這樣利於功能復用,更重要的是使得程序的整個體繫結構變得非常靈活。
IOC:控制反轉,將對象的創建權反轉給了Spring。
DI:依賴注入,前提必須有IOC的環境,Spring管理這個類的時候將類的依賴的屬性注入(設置)進來。比如說下面講到的Spring的屬性注入其實就是典型的DI
所謂繼承:is a
Class A{
}
Class B extends A{
}
所謂依賴:
Class A{
}
Class B{
public void xxx(A a){
}
}
所謂聚合:has a
3、Spring的工廠類
3.1Spring工廠類的結構
3.2老版本的工廠類:BeanFactory
BeanFactory:調用getBean的時候,才會生成類的實例。
3.3新版本的工廠類:ApplicationContext
ApplicationContext:加載配置文件的時候,就會將Spring管理的類都實例化。
ApplicationContext有兩個實現類
1、ClassPathXmlApplicationContext :加載類路徑下的配置文件
2、FileSystemXmlApplicationContext :加載文件系統下的配置文件
4、Spring的配置
4.1XML的提示配置(Schema的配置)
在XML文件中要使用各種標籤來給spring進行配置,博主我這佩奇腦袋怎麼可能記住spring中所有的標籤呢,不怕不怕,博主我會配置XML的提示配置QAQ,會了這一招就算兄dei你是喬治腦袋也不用擔心(再說了我看兄dei各各英俊瀟洒,玉樹臨風,聰明絕頂…咳咳,暴露了暴露了)
4.2Bean的相關的配置(< bean >標籤的id和name的配置)
id :使用了約束中的唯一約束。裏面不能出現特殊字符的。上面提及到了要與getbean參數值對應
name :沒有使用約束中的唯一約束(理論上可以出現重複的,但是實際開發不能出現的)。裏面可以出現特殊字符。
4.3Bean的生命周期的配置(了解)
init-method :Bean被初始化的時候執行的方法
destroy-method :Bean被銷毀的時候執行的方法(Bean是單例創建,工廠關閉)
4.4Bean的作用範圍的配置(重點)
scope屬性 :Bean的作用範圍
scope屬性值如下(主要用的是前二者)
singleton :scope屬性的默認值,Spring會採用單例模式創建這個對象。
prototype :多例模式。(Struts2和Spring整合一定會用到)
request :應用在web項目中,Spring創建這個類以後,將這個類存入到request範圍中。
session :應用在web項目中,Spring創建這個類以後,將這個類存入到session範圍中。
globalsession :應用在web項目中,必須在porlet環境下使用。但是如果沒有這種環境,相對於session。
5、Spring的屬性注入
首先,創建幾個普通類
com.gx.spring.demo.Car
public class Car {
private String name;
private Double price;
public Car(String name, Double price) {
super();
this.name = name;
this.price = price;
}
@Override
public String toString() {
return "Car [name=" + name + ", price=" + price + "]";
}
}
com.gx.spring.demo.Car2
/**
* 用作set方法的屬性注入類
*/
public class Car2 {
private String name;
private Double price;
public void setName(String name) {
this.name = name;
}
public void setPrice(Double price) {
this.price = price;
}
@Override
public String toString() {
return "Car2 [name=" + name + ", price=" + price + "]";
}
}
com.gx.spring.demo.Person
/**
* 用作set方法的對象屬性注入類
*/
public class Person {
private String name;
private Car2 car2;
public void setName(String name) {
this.name = name;
}
public void setCar2(Car2 car2) {
this.car2 = car2;
}
@Override
public String toString() {
return "Employee [name=" + name + ", car2=" + car2 + "]";
}
}
5.1構造方法的方式的屬性注入
構造方法的屬性注入
constructor-arg 標籤用於配置構造方法的屬性注入
name :參數的名稱
value:設置普通數據
ref:引用數據,一般是另一個bean id值
當然了,構造方法的方式的屬性注入也支持對象屬性的注入,標籤中對應屬性也是ref
如果只有一個有參數的構造方法並且參數類型與注入的bean類型匹配,那就會注入到該構造方法中
applicationContext.xml中配置:
<!-- 構造方法的方式 -->
<bean id="car" class="com.gx.spring.demo.Car">
<constructor-arg name="name" value="瑪莎拉蒂"/>
<constructor-arg name="price" value="800000"/>
</bean>
測試方法:
/**
* 構造方法方式的普通屬性注入方法
*/
public void demo1(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Car car = (Car) applicationContext.getBean("car");
System.out.println(car);
}
5.2Set方法的方式的屬性注入【開發常用】
Set方法的普通屬性注入
property 標籤用於配置Set方法的屬性注入
name :參數的名稱
value:設置普通數據
ref:引用數據,一般是另一個bean id值
applicationContext.xml中配置:
<!-- set方法的方式 -->
<bean id="car2" class="com.gx.spring.demo.Car2">
<property name="name" value="法拉利黃金跑車"/>
<property name="price" value="10000000"/>
</bean>
測試方法:
@Test
/**
* set方法方式的屬性注入
*/
public void demo2(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Car2 car2 = (Car2) applicationContext.getBean("car2");
System.out.println(car2);
}
Set方法設置對象類型的屬性
applicationContext.xml中配置:
<!-- set方法注入對象類型的屬性 -->
<bean id="Person" class="com.gx.spring.demo.Person">
<!-- value:設置普通類型的值,ref:設置其他的類的id或name-->
<property name="name" value="濤哥"/>
<property name="car2" ref="car2"/>
</bean>
測試方法:
@Test
/**
* set方法注入對象類型
*/
public void demo3(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person= (Person) applicationContext.getBean("Person");
System.out.println(person);
}
5.3註解的方式屬性注入【開發常用】
@Component (作用在類上通用:組件)
@Component(“userService”)相當於< bean id=”userService” class=”…”>
衍生:
@Controller Web層
@Service 業務層
@Repository 持久層
這三個註解是為了讓標註類本身的用途清晰
屬性注入的註解 ( 可以沒有set方法)
普通類型屬性:@Value
對象類型屬性:@Resource (對應bean中的id)= @Autowired(類型)+ @Qualifier(名稱)
5.3.1註解的理解
額,初學框架,註解二字可能對於大部分熊dei來說,太過於陌生,註解其實就是在一個類、方法、屬性上,使用@註解名稱,就比如是我們最熟悉的接實現口中的方法默認會有一個 @Override (熊dei,這樣理解能接受?)
5.3.2註解的jar包導入
Spring3.x註解的jar包
在Spring3.x的版本中,使用註解開發,只需要 spring核心基礎四包外 + log4j包 + 1個依賴包 即可
Spring4.x註解的jar包
然而在Spring4.x版本之後則需在 再添加一個要引入 spring-aop 的 jar 包,因為,spring4.x版本中一些註解的依賴方法封裝在spring-aop 的 jar 包中
5.3.3引入註解的context約束
所謂約束就是就是就是約束啦(搽汗),其中bean約束是最基本的約束!(下圖也可以看出)
引入約束:(引入 context 的約束):
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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>
5.3.4編寫相關的類
public interface UserDao {
public void sayHello();
}
public class UserDaoImpl implements UserDao {
@Override
public void sayHello() {
System.out.println("Hello Spring...");
} }
5.3.5配置註解掃描
Spring的註解開發:組件掃描(不使用類上註解的時候可以不用組件掃描)
使用註解方式,需要開啟組件掃描< context:component-scan base-package=直接包名或者包名.類名/>,當然開發中一般都是base-package=包名,畢竟這樣可以掃描整個包,方便開發
Spring 的註解開發:組件掃描(類上註解: 可以直接使用屬性注入的註解)
<!-- Spring 的註解開發:組件掃描(類上註解: 可以直接使用屬性注入的註解) -->
<context:component-scan base-package="com.gx.spring.demo1"/>
5.3.6 在相關的類上添加註解
1、使用類上註解方式@Component(value=“userDao”),相當於< bean id=”userDao class=”com.gx.類名”>< /bean>
當然value屬性名可以省去直接@Component(”userDao”),當然@Component(“value值任意寫建議取的要有意義”)
2、註解方式可以沒有set方法
@Component(value="userDao") //相當於配置了<bean id="userDao" class="com.gx.UserDaoImpl "></bean>
public class UserDaoImpl implements UserDao {
@Override
public void sayHello() {
System.out.println("Hello Spring Annotation...");
} }
5.3.7 編寫測試類
@Test
public void demo3() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
userDao.sayHello();
}
5.4P名稱空間的屬性注入(Spring2.5以後)
通過引入p名稱空間完成屬性的注入:
寫法:
普通屬性 p:屬性名=”值”
對象屬性 p:屬性名-ref=”值”
P名稱空間的約束引入
使用p名稱空間
5.5 SpEL的屬性注入(Spring3.0以後)
SpEL:Spring Expression Language,Spring的表達式語言。
語法: #{SpEL}
5.6集合類型屬性注入(了解)
集合類型屬性配置:
集合的注入都是在< property>標籤中添加子標籤
數組:< array >
List:< list >
Set:< set >
Map:< map > ,map存放k/v 鍵值對,使用 描述
Properties:< props> < prop key=””>< /prop>
普通數據:< value >
引用數據:< ref >
<!-- Spring的集合屬性的注入============================ -->
<!-- 注入數組類型 -->
<bean id="collectionBean" class="com.gx.spring.demo.CollectionBean">
<!-- 數組類型 -->
<property name="arrs">
<list>
<value>天才</value>
<value>王二</value>
<value>冠希</value>
</list>
</property>
<!-- 注入list集合 -->
<property name="list">
<list>
<value>李兵</value>
<value>趙如何</value>
<value>鄧鳳</value>
</list>
</property>
<!-- 注入set集合 -->
<property name="set">
<set>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</set>
</property>
<!-- 注入Map集合 -->
<property name="map">
<map>
<entry key="aaa" value="111"/>
<entry key="bbb" value="222"/>
<entry key="ccc" value="333"/>
</map>
</property>
</bean>
6、Spring的分模塊開發的配置
分模塊配置:
在加載配置文件的時候,加載多個,沒錯,這就是傳說中的騷操作,堪稱開掛級別的操作(當然,這是可以的不是開掛)
在一個配置文件中引入多個配置文件,簡直優秀!!!
到這裏,恭喜恭喜,各位熊dei以優雅的儀式感闖進Spring世界,對Spring的IOC以及DI有了一定了解了,是不是也很期待Spring的Aop吶,畢竟Spring的核心是控制反轉(IOC)和面向切面(AOP)。
(哎哎,別打..別打..別打臉….)
如果本文對你有一點點幫助,就請點個讚唄,手留余香,謝謝!
最後,歡迎各位關注我的公眾號,一起探討技術,嚮往技術,追求技術…
本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理【其他文章推薦】
※網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線
※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益
※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象