javascript
Spring 入门知识点笔记整理
一.Spring?概述
1.?什么是spring?
Spring?是個java企業級應用的開源開發框架。Spring主要用來開發Java應用,但是有些擴展是針對構建J2EE平臺的web應用。Spring?框架目標是簡化Java企業級應用開發,并通過POJO為基礎的編程模型促進良好的編程習慣。
2. 如何實現簡化java開發的目標?
為了降低java開發的復雜性,spring主要采取以下4種關鍵策略:
- 基于POJO的輕量級和最小侵入性編程。
- 通過依賴注入和面向接口編程實現松耦合。
- 基于切面和慣例進行聲明式編程。
- 通過切面和模版減少樣式代碼。
3.?使用Spring框架的好處是什么?
- 輕量:Spring?是輕量的,基本的版本大約2MB。
- 控制反轉:Spring通過控制反轉實現了松散耦合,對象們給出它們的依賴,而不是創建或查找依賴的對象們。
- 面向切面的編程(AOP):Spring支持面向切面的編程,并且把應用業務邏輯和系統服務分開,并使系統服務模塊化。
- 容器:Spring?包含并管理應用中對象的生命周期和配置。
- MVC框架:Spring的WEB框架是個精心設計的框架,是Web框架的一個很好的替代品。
- 事務管理:Spring?提供一個持續的事務管理接口,可以擴展到上至本地事務下至全局事務(JTA)。
- 異常處理:Spring?提供方便的API把具體技術相關的異常(比如由JDBC,Hibernate?or?JDO拋出的)轉化為一致的unchecked?異常。
- 提供模版:減少了樣板式代碼
4.??Spring由哪些模塊組成?
spring可以分為6個定義明確的模塊組成:
- 核心容器模塊:是spring中最核心的模塊。負責Bean的創建,配置和管理。主要包括:beans,core,context,expression等模塊。
- Spring的AOP模塊:主要負責對面向切面編程的支持,幫助應用對象解耦。
- 數據訪問和集成模塊:包括JDBC,ORM,OXM,JMS和事務處理模塊,其細節如下:
- ? ? JDBC模塊提供了不再需要冗長的JDBC編碼相關了JDBC的抽象層。
? ? ?ORM模塊提供的集成層。流行的對象關系映射API,包括JPA,JDO,Hibernate和iBatis。
? ? ? ? ? ? OXM模塊提供了一個支持對象/ XML映射實現對JAXB,Castor,使用XMLBeans,JiBX和XStream 的抽象層。
? ? ? ? ? ? Java消息服務JMS模塊包含的功能為生產和消費的信息。
? ? ? ? ? ? 事務模塊支持編程和聲明式事務管理實現特殊接口類,并為所有的POJO。
- Web和遠程調用:包括web,servlet,struts,portlet模塊。
- 測試模塊:test
- 工具模塊
5.常用的幾個應用上下文
- ClassPathXmlApplicationContext:從類路徑下的xml配置文件中加載上下文定義.
- FileSystemXmlApplicationContext:讀取文件系統下xml配置文件并加載
- XmlWebApplicationContext:讀取Web應用下的Xml配置文件并加載上下文定義
二.容器
創建應用對象之間關系的傳統方法通常會導致對象之間耦合性過高,且難以復用和測試.spring通過容器使得對象無需自己負責查找和創建與其關聯的其他對象,做到解耦.
裝配:創建應用對象之間協作關系的行為稱為裝配,這是依賴注入的本質.
1.依賴注入(DI)
概念:對象的依賴關系將有負責協調系統中各個對象的第三方組建在創建對象時設定。對象無需自行創建或管理它們的依賴關系—依賴關系將自動注入到需要它們的對象中去。
對象無需知道依賴對象來自何處或依賴的實現方式。
依賴注入能讓相互協作的軟件組件保持松散耦合。AOP編程允許把你遍布應用各處的功能分離出來形成可重用的組件
2.Spring容器可歸為兩種:
Bean工廠(由org.springframework.beans.factory.BeanFactory)
應用上下文(org.springframework.context.ApplicationContext)
3.Spring框架中bean的生命周期。
- Spring容器?從XML?文件中讀取bean的定義,并實例化bean。
- Spring根據bean的定義填充所有的屬性。
- 如果bean實現了BeanNameAware?接口,Spring?傳遞bean?的ID?到?setBeanName方法。
- 如果Bean?實現了?BeanFactoryAware?接口,?Spring傳遞beanfactory?給setBeanFactory?方法。
- 如果有任何與bean相關聯的BeanPostProcessors,Spring會在postProcesserBeforeInitialization()方法內調用它們。
- 如果bean實現IntializingBean了,調用它的afterPropertySet方法,如果bean聲明了初始化方法,調用此初始化方法。
- 如果有BeanPostProcessors?和bean?關聯,這些bean的postProcessAfterInitialization()?方法將被調用。
- 如果bean實現了?DisposableBean,它將調用destroy()方法。
4.spring的核心框架帶有10個命名空間配置
5.構造器注入
<constructor-arg value="" /> <constructor-arg ref="" /> View Code6.通過工廠方法創建Bean
<bean id="" class="工廠類" factory-method="對應方法" />7.Bean的作用域
Spring框架支持以下五種bean的作用域:
- singleton?:?bean在每個Spring?ioc?容器中只有一個實例。
- prototype:一個bean的定義可以有多個實例。
- request:每次http請求都會創建一個bean,該作用域僅在基于web的Spring?ApplicationContext情形下有效。
- session:在一個HTTP?Session中,一個bean定義對應一個實例。該作用域僅在基于web的Spring?ApplicationContext情形下有效。
- global-session:在一個全局的HTTP?Session中,一個bean定義對應一個實例。該作用域僅在基于web的Spring?ApplicationContext情形下有效。
缺省的Spring?bean?的作用域是Singleton.
8.Bean的初始化的銷毀
? 為Bean定義初始化和銷毀只需要使用init-method和destroy-method參數配置<bean>元素就可以.定義全部bean的默認的初始化和銷毀在<beans> 元素里配置default-init-method和default-destroy-metho.另一種方式時通過分別實現 InitializingBean和DisposableBean 接口,但這種方法產生了應用與框架的耦合,建議使用第一種.
<beans ….... default-init-method="onLight" default-destroy-method=”offLight” ><bean id="light" class="joe.spring.util.Light"/> </beans> <!--注:該方法所在的類必須創建Bean --> View Code9.注入bean屬性
<!--簡單值--> <property name="" value=""/> <!--引用--> <property name="" ref=""/> 或 <property name=""><bean class="" /> </property><!--使用命名空間p裝配--> <bean id="" class="" p:strs="" p:user-ref="" /> View Code集合屬性的裝配包括:list,set,map,properties.
- list:內容成員有<ref bean=""/>,<value>,<bean><null/>. list中還可以包含另一個<list>作為成員.list屬性也可以用set來裝配,同理set屬性也可以用list來裝配.(如果Bean的屬性類型為數據類型或者java.util.Collection接口的任意實現都可以用<list>元素).
- set:同上
- map: 成員包括<entry key="" key-ref=""/> 和<entry value=""? value-ref=""/>
- props:可以代替map.但限定鍵和值必須為String類型.成員<prop key=""> value</prop>
10.SpEL擁有的特性
- 使用bean的ID引用bean
- 調用方法和訪問對象的屬性
- 對值進行算術,關系和邏輯運算
- 正則表達式匹配
- 集合操作
11.SpEL常用操作
- 字面值:#{5} 值為5,<property name="" value="#{user}"> bean的id. 同時可以訪問bean的方法和屬性如:#{user.name},#{user.getAge()}
- 操作類:T() 訪問類的靜態方法和屬性. #{T(java.lang.Math).PI},#{T(java.lang.Math).random() }.
- 運算操作:算術運算(+,-,*,/,%,^),關系運行(lt,gt,eq,le,ge),邏輯運算(and,or,not,|),條件運算(? : ),正則運算(matches).
- <util:list> :spring命名空間,定義bean的list集合. <util:list id="cities"> ....</util:list> ,取值用#{cities[2]}
- 從java.util.Properties取值:<util:properties id="settings' location="classpath:settings.properties"/>? #{settings['jdbc.Driver']}
- systemEnviroment: 包含應用程序所在機器的所有環境變量,時java.util.Properties的一個集合. #{systemEnviroment['HOME']}
- systemPorperties:包含java應用程序啟動時所設置的所有屬性. 如-Dapplication.home=/etc/myapp??? #{systemProperties['application.home']}
- 查詢結合 :".^[]"集合中第一個匹配項和".$[]"集合中最后一個匹配項.#{cities.^[population gt 100000]}
- 投影集合".![]":從集合中的每一個成員中選擇特定的屬性放入一個新的集合中.
12.自動裝配Bean屬性
spring提供了4中類型的自動裝配方式:
- no:默認的方式是不進行自動裝配,通過顯式設置ref?屬性來進行裝配。
- byName: 把與Bean的屬性具有相同名字(或ID)的其他Bean自動裝配到Bean對應的屬性中.如果沒有與屬性名字一樣的bean,則該屬性不進行裝配.(缺點:名字必須一樣)
- byType:把與Bean的屬性具有相同類型的其他Bean自動裝配到Bean對應的屬性中.如果沒有,則不裝配.如果有多個Bean的類型相同的話Spring會拋出異常,可以通過設置首選Bean或取消某個Bean的自動裝配候選資格.設置首選可以在<Bean>中的primary屬性設置為true,取消候選資格可以將autowire-candidate設置為false.(如果同時設置:則該bean的設置為取消候選資格.primary默認設置為false,所以需要用primary時得將其他bean的primary設置為true)
- constructor:把與Bean的構造器參數具有相同類型的的其他Bean自動裝配到Bean構造器對應的參數中.設置該項,這配置文件中的<constructor-arg>可以省略
- autodetect:首先嘗試使用constructor裝配,失敗則用byType裝配
設置默認自動裝配,即在beans中加入屬性default-autowire=”true”
自動裝配和手工裝配結合的混合裝配模式優先考慮手工裝配,如果無手工裝配,則采用自動裝配.
13.注解裝配
spring 容器默認關閉注解裝配,啟用方式是用Spring的context命名空間配置<context:annotation-config>
有三種方式進行注解裝配:
- ?spring自帶的@Autowire.可以放在setter上或 任何需要轉配bean的方法上.也可以放在私有或公共屬性上(可以刪除setter).以byType類型去查找bean,所以如果有多個Bean則會報錯.解決方案時加入@Qualifier注解指定注入的Bean.可以設置@Autowire(required=false)如果找不到對應的bean則設置為null. required表示是否一定要裝配,設置為false找不到這設置為null并且不報錯.當多個構造器使用@Autowire 會調用參數滿足最多的構造器.
- JSR-330的Inject注解.也可以轉配屬性,方法,構造器,不同的是沒有required這個屬性,所以依賴關系必須存在否則報錯.針對bean歧義,采用@Name注解. 提供Provider接口可以實現bean的延遲注入以及注入bean的多個實例功能.
- JSR-250 的@Recourse
@Value用于裝配String類型的值和基本類型的值(如int,boolean).可以使用SpEL.
14.自動檢測Bean
使用自動檢測首先需要在spring配置文件配置一下代碼
<context:component-scan base-package=”joe.spring.service” ></context:component-scan>
<context:component-scan>會掃描指定的包及其所有子包,并查找能夠自動注冊的spring Bean類. 默認查找構造型注解所標注的類:
@Component 標注類為spring組件
@Controller 定義為spring mvc controller
@Repository 定義為數據倉庫
@Service 將該類定義為服務
使用@Component標注的任意自定義注解
<context:component-scan>配置<context:include-filter type="" expression="">和<context:exclude-filter type="過濾類型" expression="">,進行過濾.
過濾類型包括:
- annotation:過濾器掃描使用制定注解所標注的那些類,通過expression指定要掃面的注解.
- assignable:過濾器掃描派生與expression屬性所指定的類型的那些類.
- aspectj:過濾器掃描與expression屬性所指定的AspectJ表達式所匹配的那些類.
- custom:使用自定義的org.springframework.core.type.TypeFilter實現類,該類由expression屬性指定.
- regex:過濾器掃描的名稱與expression所指定的正則表達式所匹配的哪些類.
三.面向切面AOP
橫向關注點:分布在應用多處的功能.
面向切面編程的目標是將這些橫向關注點和業務邏輯分開.
依賴注入(Dependency Injection ,DI)實現了應用之間的解耦,面向切面編程(aspect-oriented programing ,AOP)實現了橫向關注點與它們所影響的對象解耦.
切面:橫切關注點可以被模塊化特殊的類(通知和切點的結合,即what,when,where--它是什么,在何時何處完成其功能.)
通知:切面的工作(定義了切面是什么以及何時調用).五種類型通知:
- before :方法被調用之前調用
- after: 方法完成后調用通知,無論方法執行是否成功
- After-returning: 在方法成功執行之后調用通知
- After-throwing 方法拋出異常后調用通知
- Around :通知包裹了被通知的方法,在被通知的方法調用之前或之后執行自定義的行為
連接點:應用可能對數以千計的時機應用通知,這些時機稱為連接點.連接點是在應用執行過程中能夠插入一個切面的點.這個點可能是調用方法,拋出異?;蛐薷淖侄螘r.切面代碼可以利用這些點插入到正常程序流程中,并加入其他行為.
切點:縮小切面所通知的連接點范圍.切點即定義何處切入.
引入:允許我們向現有的類添加方法或屬性.
織入:將切面應用到目標對象來創建新的代理對象過程.切面在制定的連接點被織入到對象中.在目標對象的聲明周期里有多個點可以織入:
- 編譯器,切面在目標類編譯時被織入
- 類加載器,切面在目標類加載到jvm 時被織入.需要特殊的類加載器,在目標類被引入應用時增強該目標類的字節碼
- 運行期,切面在應用運行的某個時刻被織入
spring 提供了4中AOP編程:
1.基于代理的AOP編程
2.@Aspectj 注解驅動的切面
3.純POJO切面
4.注入式Aspectj切面編程
前面3個是spring基于代理的AOP編程,所以局限于方法攔截.如果要對屬性或構造器攔截者應調用 Aspectj里面的切面.
AspectJ的切點表達式語言:
- arg() :限制連接點匹配參數為指定類型的執行方法
- @args():限制連接點匹配參數由指定注解標注的執行方法
- execution():用于匹配是連接點的執行方法
- this():限制連接點匹配AOP代理的Bean引用為指定類型的類(沒懂)
- target():限制連接點匹配目標對象為制定類型的類
- @target():限制連接點匹配目特定的執行對象,這些對象對應的類要具備指定類型的注解.
- within():限制連接點匹配指定的類型
- @within:限制連接點匹配指定注解所標注的類型
- @annotation:限制匹配帶有制定注解的連接點
還可以使用bean()指示器,使用bean的ID或名稱作為參數限定匹配切點只匹配特定的Bean.
使用注解切面時需要在配置文件中加入
<aop:aspectj-autoproxy>
環繞通知,參數 (ProceedingJoinPoint joinpoint)
joinpoint.proceed() 即執行被調用方法
?
?
轉載于:https://www.cnblogs.com/jaylon/p/4918914.html
總結
以上是生活随笔為你收集整理的Spring 入门知识点笔记整理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 转载:Linux查看设置系统时区
- 下一篇: 你真的会玩SQL吗?EXISTS和IN之