什么是 Spring 框架?
Spring 是一個開源的輕量級的Java開發框架,以 Ioc(Inverse Of control:反轉控制)和AOP(Aspect Oriented Programming: 面向切面編程) 為內核,提供了展現層Spring MVC和持久層Spring JDBC以及業務層事務管理等眾多企業級應用技術,其還整合眾多開源的第三方框架,逐漸成為最受歡迎的Java EE企業應用框架,

Spring框架的特征:
- 輕量高效:Spring 是一個開源的輕量級的Java開發框架
- 控制反轉IOC:通過 Spring 提供的 IOC 容器,可以將物件間的依賴關系交由 Spring 進行控制,避免硬編碼所造成的過度程式耦合,用戶也不必再為單例模式類、屬性檔案決議等這些很底層的需求撰寫代碼,可以更專注于上層的應用,
- 面向切面AOP:通過Spring的AOP功能,方便進行面向切面的編程,許多不容易用OOP實作的功能可以通過AOP輕松應付,
- 宣告式事務:可以從單調煩悶的事務管理代碼中解脫出來,通過宣告式方式靈活的進行事務的管理,提高開發效率和質量,
- 容器: Spring包含并管理應用物件的配置和生命周期,在這個意義上它是一個容器,你可以配置你的每個bean如何被創建,
- 框架:集成各種框架,Spring可以將降低各種框架的使用難度,提供了對各種優秀框架(Struts、 Hibernate、 Hessian、 Quart等)的直接支持,
列舉一些重要的Spring模塊?
Spring是很多模塊的集合,使用這些模塊可以很方便地協助我們進行開發,
- 核心容器Core Container: Core是所有組件的核心,可以說 Spring 其他所有的功能都需要依賴于該類別庫,主要提供 IoC 依賴注入功能,Beans 組件和 Context 組件是實作IOC和依賴注入的基礎
- AOP :提供了面向切面的編程實作,Aspects : 該模塊為與AspectJ的集成提供支持(AspectJ:Java生態系統中最完整的AOP 框架),
- 資料訪問/集成:JDBC (Java資料庫連接)、JMS(Java訊息服務)、ORM(用于支持Hibernate等ORM工具)
- Web :為創建Web應用程式提供支持,
- Test : 提供了對 JUnit 和 TestNG 測驗的支持,

詳細講解一下核心容器模塊
核心容器是基本的Spring模塊,提供spring 框架的基礎功能,BeanFactory 是任何以spring為基礎的應用的核心,Spring 框架建立在此模塊之上,它使Spring成為一個容器,
Bean 工廠是工廠模式的一個實作,提供了控制反轉功能,用來把應用的配置和依賴從真正的應用代碼中分離,最常用的就是XmlBeanFactory ,它根據XML檔案中的定義加載beans,該容器從XML 檔案讀取配置元資料并用它去創建一個完全配置的系統或應用,
談談自己對于 Spring IoC 和 AOP 的理解
控制反轉:IOC
IoC(Inverse of Control:控制反轉)是一種設計思想,就是將原本在程式中手動創建物件的控制權,交由Spring框架來管理,大大增加了專案的可維護性且降低了開發難度, IoC 在其他語言中也有應用,并非 Spring 特有,
IoC 容器是 Spring 用來實作 IoC 的載體, IoC 容器實際上就是個Map(key,value),Map 中存放的是各種物件(在xml里配置的bean節點、@Controller、@Component),在專案啟動的時候會讀取組態檔里面的bean節點,根據全限定類名使用反射創建物件放到map里,或掃到上述注解的類,通過反射創建物件放到map里,
這個時候map里就有各種物件了,接下來我們在代碼里需要用到里面的物件時,再通過DI注入( @Autowired、@Resource等注解,xml里bean節點內的ref屬性,專案啟動的時候會讀取xml節點ref屬性根據id注入,也會掃描這注解,根據型別或id(物件名)注入;
依賴注入(Dependency Injection)即組件之間的依賴關系由Ioc容器管理,由容器動態地將某種依賴關系的目標物件實體注入到應用系統中的各個關聯的組件之中,組件不做定位查詢,只提供普通的Java方法讓容器去決定依賴關系,很大程度上簡化應用的開發,把應用從復雜的依賴關系中解放出來,
面向切面編程:AOP
AOP(Aspect-Oriented Programming:面向切面編程):將程式中的交叉業務邏輯(比如安全,日志,事務等),封裝成一個切面,然后注入到目標物件(具體業務邏輯)中去,AOP可以對某個物件或某些物件的功能進行增強,比如物件中的方法進行增強,可以在執行某個方法之前額外的做一些事情,在某個方法執行之后額外的做一些事情,
系統是由許多不同的組件所組成的,每個組件各負責一塊特定功能,除了實作自身核心功能之外,這些組件還經常承擔著額外的職責,AOP能夠將這些與核心功能無關,卻為業務模塊所共同呼叫的邏輯或責任(例如事務處理、日志管理、權限控制等)封裝起來,在需要用到的地方直接使用,這樣減少系統的重復代碼,降低模塊間的耦合度,并有利于未來的可拓展性和可維護性,
Spring AOP是基于動態代理實作的,如果要代理的物件,實作了某個介面,那么Spring AOP會使用JDK Proxy,去創建代理物件,而對于沒有實作介面的物件,就無法使用 JDK Proxy 去進行代理了,這時候Spring AOP會使用Cglib生成一個被代理物件的子類來作為代理,
Spring AOP 和 AspectJ AOP 有什么區別?
Spring AOP 屬于運行時增強,而 AspectJ 是編譯時增強, Spring AOP 基于代理(Proxying),而 AspectJ 基于位元組碼操作(Bytecode Manipulation),
Spring AOP 已經集成了 AspectJ ,AspectJ 應該算的上是 Java 生態系統中最完整的 AOP 框架了,AspectJ 相比于 Spring AOP 功能更加強大,但是 Spring AOP 相對來說更簡單,如果我們的切面比較少,那么兩者性能差異不大,但是,當切面太多的話,最好選擇 AspectJ ,它比Spring AOP 快很多,
Spring 常用注解
將一個類宣告為Spring的 bean :
- @Controller:用來標注控制層組件,通過Controller注解標記的類就是一個SpringMVC物件,分發處理器會掃描使用了該注解的類的方法,并檢測該方法是否使用了@RequestMapping注解,可以把Request請求header部分的值系結到方法的引數上,
- @RestController:相當于Controller注解與ResponseBody的組合效果
- @Component:通用的注解,可標注任意類為 Spring 組件,如果一個Bean不知道屬于哪個層,可以使用
- @Reponsitory:用來標注Dao層,在daoImpl類上注釋
- @Service:用來標注業務層
其他常用注解:
- @ResponseBody:異步請求,該注解用于將Controller的方法回傳的物件,通過適當的HttpMessageConverter轉換為指定格式后,寫入Response物件的body區,回傳的值不是html頁面,而是其他某種格式的資料時使用,
- @RequestMapping:一個用來處理請求地址映射的注解,可以作用與類上或方法上,作用于類上標表示類的所有回應請求的方法都是以該地址作為父路徑,
- @Autowired:可以對類成員變數、方法以及建構式進行標注,完成自動裝配的作業,通過該注解來消除get、set方法,
- @PathVariable:用于將請求URL中的模板變數映射到功能處理方法的引數上,即取出url中的變數作為引數
- @RequestParam:主要用于在SpringMVC控制層獲取引數,類似于request.getParameter(“name”);
- @ModelAttribute:該Controller的所有方法在呼叫前,限制性此方法,可用于注解和方法引數中,可以把這個ModelAttribute特性,應用在BaseController中,所有的Controller繼承BaseCotroller,即可實作在呼叫Controller時,先執行@ModelAttribute方法,
@RestController與@Controller的區別是什么?
Controller 回傳一個頁面:單獨使用 @Controller 不加 @ResponseBody的話一般使用在要回傳一個視圖的情況,這種情況屬于比較傳統的Spring MVC 的應用,對應于前后端不分離的情況,
@RestController (等價于@Controller +@ResponseBody)回傳JSON 或 XML 形式資料:@RestController只回傳物件,物件資料直接以 JSON 或 XML 形式寫入 HTTP 回應(Response)中,這種情況屬于 RESTful Web服務,這也是目前日常開發所接觸的最常用的情況(前后端分離),
@ResponseBody 注解的作用是將 Controller 的方法回傳的物件通過適當的轉換器轉換為指定的格式之后,寫入到HTTP 回應(Response)物件的 body 中,通常用來回傳 JSON 或者 XML 資料,回傳 JSON 資料的情況比較多,
@RequestMapping注解的屬性
RequestMapping是一個用來處理請求地址映射的注解,可用于類或方法上,用于類上,表示類中的所有回應請求的方法都是以該地址作為父路徑,
RequestMapping注解有六個屬性:
- value: 指定請求的實際地址,指定的地址可以是URI Template 模式;
- method: 指定請求的method型別, GET、POST、PUT、DELETE等;
- consumes: 指定處理請求的提交內容型別(Content-Type),例如application/json,text/html;
- produces: 指定回傳的內容型別,僅當request請求頭中的(Accept)型別中包含該指定型別才回傳;
- params: 指定request中必須包含某些引數值是,才讓該方法處理,
- headers: 指定request中必須包含某些指定的header值,才能讓該方法處理請求
@Component 和 @Bean 的區別是什么?
- 作用物件不同: @Component 注解作用于類,而@Bean注解作用于方法,
- @Component通常是通過類路徑掃描來自動偵測以及自動裝配到Spring容器中(我們可以使用@ComponentScan 注解定義要掃描的路徑從中找出標識了需要裝配的類自動裝配到 Spring 的 bean 容器中),@Bean 注解通常是我們在標有該注解的方法中定義產生這個 bean,@Bean告訴了Spring這是某個類的示例,當我需要用它的時候還給我,
- @Bean 注解比 Component 注解的自定義性更強,而且很多地方我們只能通過 @Bean 注解來注冊bean,比如當我們參考第三方庫中的類需要裝配到 Spring容器時,則只能通過 @Bean來實作,
@Configuration
public class AppConfig {
@Bean
public TransferService transferService() {
return new TransferServiceImpl();
}
}
//上面的代碼相當于下面的 xml 配置
<beans>
<bean id="transferService" class="com.acme.TransferServiceImpl"/>
</beans>
@PathVariable和@RequestParam的區別
- 請求路徑上有個id的變數值,可以通過@PathVariable來獲取
@RequestMapping(value =“/page/{id}”, method = RequestMethod.GET) - @RequestParam用來獲得靜態的URL請求入參 spring注解時action里用到,
@Autowired和@Resource之間的區別
-
@Autowired可用于:建構式、成員變數、Setter方法,@Autowired默認是按照型別裝配注入的,默認情況下它要求依賴物件必須存在(可以設定它required屬性為false),
-
@Resource默認是按照名稱來裝配注入的,只有當找不到與名稱匹配的bean才會按照型別來裝配注入,
Bean Factory和 Application Context有什么區別?
Applicationcontext是 Beanfactory的子介面,ApplicationContext提供了更完整的功能:
- ①繼承 Messagesource,因此支持國際化
- ②統一的資源檔案訪問方式,
- ③提供在監聽器中注冊bean的事件,
- ④同時加載多個組態檔,
- ⑤載入多個(有繼承關系)背景關系,使得每個背景關系都專注于一個特定的層次,比如應用的web層,
加載方式:
- Bean Factroy采用的是延遲加載形式來注入Bean的,即只有在使用到某個Bean時呼叫 getbean(),才對該Bean進行加載實體化,這樣,我們就不能發現一些存在的 Spring的配置問題,如果Bean的某一個屬性沒有注入, Beanfacotry加載后,直至第一次使用呼叫 getbean方法才會拋出例外,
- Applicationcontext,它是在容器啟動時,一次性創建了所有的Bean,這樣,在容器啟動時,我們就可以發現 spring中存在的配置錯誤,這樣有利于檢查所依賴屬性是否注入, Applicationcontext啟動后預載入所有的單實體Bean,通過預載入單實體bean,確保當你需要的時候,不需要等待,直接使用,
創建方式:
Bean Factory通常以編程的方式被創建, Applicationcontext還能以宣告的方式創建,如使用ContextLoader,
注冊方式:
Bean Factory和 Application Context,都支持 Bean Postprocessor、 Beanfactory Postprocessor的使用,但兩者之間的區別是: Beanfactory需要手動注冊,而 Applicationcontext則是自動注冊,
相對于基本的 Beanfactory, Applicationcontext唯的不足是占用記憶體空間,當應用程式配置Bean較多時,程式啟動較慢,
ApplicationContext通常的實作是什么?
- FileSystemXmlApplicationContext :此容器從一個XML檔案中加載beans的定義,XML Bean 組態檔的全路徑名必須提供給它的建構式,
- ClassPathXmlApplicationContext:此容器也從一個XML檔案中加載beans的定義,這里,你需要正確設定classpath因為這個容器將在classpath里找bean配置,
- WebXmlApplicationContext:此容器加載一個XML檔案,此檔案定義了一個WEB應用的所有bean
Spring 中的 bean 生命周期?
決議類-》加載物件-》依賴注入-》回呼Aware方法-》后置處理器處理(初始化及初始化前后)-》使用-》銷毀
- Bean 容器決議類得到組態檔中 Spring Bean 的定義(BeanDefinition),(決議)
- Bean 容器利用 Java Reflection API 創建一個Bean的實體,(加載物件)
- 如果涉及到一些屬性值(加了@Autowride注解的屬性)利用 set()方法給物件設定屬性,(依賴注入)
- 回呼Aware方法:如果實作了其他
*.Aware介面,就呼叫相應的方法,(回呼Aware方法)
①如果 Bean 實作了 BeanNameAware 介面,呼叫 setBeanName()方法,傳入Bean的名字,
②如果 Bean 實作了 BeanClassLoaderAware 介面,呼叫 setBeanClassLoader()方法,傳入 ClassLoader物件的實體, - 如果有和加載這個 Bean 的 Spring 容器相關的 BeanPostProcessor物件,執行postProcessBeforeInitialization() 方法,(后置處理器初始化前方法)
- 如果Bean實作了InitializingBean介面,執行afterPropertiesSet()方法,(初始化方法)
- 如果 Bean 在組態檔中的定義包含 init-method 屬性,執行指定的方法,
- 如果有和加載這個 Bean的 Spring 容器相關的 BeanPostProcessor 物件,執行postProcessAfterInitialization() 方法,(后置處理器初始化后方法,會進行AOP)
- 當要銷毀 Bean 的時候,如果 Bean 實作了 DisposableBean 介面,執行 destroy() 方法,
- 當要銷毀 Bean 的時候,如果 Bean 在組態檔中的定義包含 destroy-method 屬性,執行指定的方法,
圖示:

后置處理器BeanPostProcessor :在Bean物件在實體化和依賴注入完畢后,在顯示呼叫初始化方法的前后添加我們自己的邏輯,注意是Bean實體化完畢后及依賴注入完成后觸發的,后置處理器分為 Bean Factory后置處理器(視線了Spring的掃描)和Bean后置處理器(實作了@ Autowired注解的屬性自動賦值、AOP)
bean 標簽有兩個重要的屬性(init-method和destroy-method),用它們你可以自己定制初始化和注銷方法,它們也有相應的注解
Spring 中的 bean 的作用域有哪些?
- singleton(單例模式,默認) : 每個容器中只有一個bean的實體,單例的模式由 Beanfactory自身來維護,該物件的生命周期是與 Spring IOC容器一致的(但在第一次被注入時才會創建),
- prototype (原型模式): 每次請求都會創建一個新的 bean 實體,在每次注入時都會創建個新的物件
- request:每一次HTTP請求都會產生一個新的bean,該bean僅在當前HTTP request內有效,
- session:每一次HTTP請求都會產生一個新的 bean,該bean僅在當前 HTTP session 內有效,
- application:bean被定義為在 Servletcontext的生命周期中復用一個單例物件(可以實作跨容器)
- global-session: 全域session作用域,僅僅在基于portlet的web應用中才有意義,Spring5已經沒有了,Portlet是能夠生成語意代碼片段的小型Java Web插件,它們基于portlet容器,可以像servlet一樣處理HTTP請求,但是,與 servlet 不同,每個 portlet 都有不同的會話,
Spring 中的單例 bean 執行緒安全嗎?
存在安全問題的,Spring中的bean默認是單例模式的,框架并沒有對bean進行多執行緒的封裝處理,當多個執行緒操作同一個物件的時候,對這個物件的成員變數的寫操作會存在執行緒安全問題,
但是大多數bean都是無狀態的(不具有資料存盤功能),比如說controller、 service和dao層,我們一般只是呼叫里面的方法,多執行緒呼叫一個實體的方法,會在記憶體中復制變數,這是自己的執行緒的作業記憶體,是安全的,但是dao層會操作資料庫 Connection, Connection是帶有狀態的,比如說資料庫事務, Spring的事務管理器,需要我們進行處理,
因此,不要在bean中宣告任何有狀態的實體變數或類變數,如果必須如此,可以參考一下方案:
- 使用 Threadloca把變數變為執行緒私有的,比如在dao層,可以使用Threadlocal為不同執行緒維護了一套獨立的 connection副本,保證執行緒之間不會互相影響,
- 改變 Bean 的作用域為 “prototype”:每次請求都會創建一個新的 bean 實體,自然不會存在執行緒安全問題,
- 如果bean的實體變數或類變數需要在多個執行緒之間共享,那么就只能使用 synchronized、OCK、CAS等這些實作執行緒同步的方法了,
Spring 框架中用到了哪些設計模式?
- 工廠設計模式: 由一個工廠類根據傳入的引數,動態決定創建那個產品類,Spring使用工廠模式通過 BeanFactory、ApplicationContext 創建bean 物件,
- 單例設計模式 : 保證一個類僅有一個實體,并提供一個訪問它的全域訪問點,Spring 中的 Bean 默認都是單例的,
- 配接器模式 :Spring AOP 的增強或通知(Advice)使用到了配接器模式、spring MVC 中也是用到了配接器模式(HandlerAdapter)適配Controller,對應的每一種Controller都有一種對應的配接器實作類,
- 代理設計模式 : Spring AOP 功能的實作,AOP把切面應用到物件并創建新的代理物件,
- 觀察者模式:Spring的事件驅動模型使用的是觀察著模式,Spring中Observer模式常用的地方是Listener的實作,
- 策略模式:Spring框架的資源訪問Resource介面,該介面提供了更強的資源訪問能力,Spring框架本身大量使用了Resource的介面來訪問底層資源,
- 裝飾器模式:動態地給一個物件添加額外的職責,Spring中類名包括Wrapper或Decorator使用了裝飾器模式,
- 模板方法模式 : Spring 中 jdbcTemplate、hibernateTemplate 等以 Template 結尾的對資料庫操作的類,它們就使用到了模板模式,
- 包裝器設計模式 : 我們的專案需要連接多個資料庫,而且不同的客戶在每次訪問中根據需要會去訪問不同的資料庫,這種模式讓我們可以根據客戶的需求能夠動態切換不同的資料源,
Spring事務的實作方式
Spring 管理事務的方式有幾種?
- 編程式事務,在代碼中硬編碼,(不推薦使用)
- 宣告式事務,在組態檔中配置(推薦使用)
宣告式事務又分為:
- 基于XML的宣告式事務
- 基于注解的宣告式事務
說一下 Spring的事務機制
- spring事務底層是基于資料庫事務和AOP機制的(事務這個概念是資料庫層面的, Spring只是基于資料庫中的事務進行了擴展)
- 首先對于使用了@Transactional注解的bean,Spring會創建一個代理物件作為Bean
- 當呼叫代理物件的方法時,會先判斷該方法上是否加了@ Transactional注解
- 如果加了,那么則利用事務管理器創建一個資料庫連接,并把事務的自動提交設定為 false,然后再去執行原本的業務邏輯方法(sql),
- 如果執行業務邏輯方法沒有出現例外,那么代理邏輯中就會將事務進行提交
- 如果執行業務邏輯方法出現了例外,那么則會將事務進行回滾
- 針對哪些例外回滾事務是可以配置的,可以利用@Transactional注解中的 rollbackfor屬性進行配置,默認情況下會對 Runtimeexception和Error進行回滾,
- Spring事務的隔離級別對應的就是資料庫的隔離級別
- Spring事務的傳播機制是 Spring事務自己實作的,也是 Spring事務中最復雜的
- Spring事務的傳播機制是基于資料庫連接來做的,一個資料庫連接一個事務,如果傳播機制配置為需要新開個事務,那么實際上就是先建立一個資料庫連接,在此新資料庫連接上執行sql
@Transactional注解了解嗎?
Exception分為運行時例外RuntimeException和非運行時例外,事務管理對于企業應用來說是至關重要的,即使出現例外情況,它也可以保證資料的一致性,
當@Transactional注解作用于類上時,該類的所有 public 方法將都具有該型別的事務屬性,同時,我們也可以在方法級別使用該標注來覆寫類級別的定義,如果類或者方法加了這個注解,那么這個類里面的方法拋出例外,就會回滾,資料庫里面的資料也會回滾,
@Transactional(rollbackFor = Exception.class):
在@Transactional注解中如果不配置rollbackFor屬性,那么事務只會在遇到RuntimeException的時候才會回滾,加上rollbackFor=Exception.class,可以讓事務在遇到非運行時例外時也回滾,
spring事務什么時候會失效?
spring事務的原理是AOP,進行了切面增強,那么失效的根本原因是這個AOP不起作用了,常見情況有如下幾種:@Transactional標識的方法只有被代理物件呼叫時,注解才會生效
- 發生自呼叫,類里面使用this呼叫本類的方法,此時這個this物件不是代理類,而是Userservice物件本身(解決方法很簡單,讓那個this變成 Euserservice的代理類即可)
- 方法不是public的,Transactional只能用于public的方法上,否則事務不會失效,如果要用在非public方法上,可以開啟( Aspectj代理模式),
- 例外被吃掉,事務不會回滾或者拋出的例外沒有被定義,默認為 RuntimeException,
Spring 事務中的隔離級別有哪幾種?
spring事務隔離級別就是資料庫的隔離級別:外加一個默認級別
- isolation_default(默認級別):使用后端資料庫默認的隔離級別
- read_uncommitted(讀未提交讀):最低的隔離級別,允許讀取尚未提交的資料變更,可能會導致臟讀、幻讀或不可重復讀
- read_committed(讀以提交、不可重復讀):允許讀取并發事務已經提交的資料,可以阻止臟讀,但是幻讀或不可重復讀仍有可能發生
- repeatable_read(可重復讀):對同一欄位的多次讀取結果都是一致的,除非資料是被本身事務自己所修改,可以阻止臟讀和不可重復讀,但幻讀仍有可能發生,
- serializable(可串行化):最高的隔離級別,完全服從ACID的隔離級別,所有的事務依次逐個執行,這樣事務之間就完全不可能產生干擾,也就是說,該級別可以防止臟讀、不可重復讀以及幻讀,但是這將嚴重影響程式的性能,通常情況下也不會用到該級別,
資料庫的配置隔離級別是 Read Commited,而 Spring配置的隔離級別是 Repeatable Read,請問這時隔離級別是以哪個為準?
以 Spring配置的為準,如果 spring設定的隔離級別資料庫不支持,效果取決于資料庫
Spring 事務中哪幾種事務傳播行為?
多個事務方法相互呼叫時事務如何在這些方法間傳播:
方法A是一個事務的方法,方法A執行程序中呼叫了方法B,那么方法B有無事務以及方法B對事務的要求不同都會對方法A的事務具體執行造成影響,同時方法A的事務對方法B的事務執行也有影響,這種影響具體是什么就由兩個方法所定義的事務傳播型別所決定,
- REQUIRED(Spring默認的事務傳播型別):如果當前沒有事務,則自己新建一個事務,如果當前存在事務,則加入這個事務
- SUPPORTS:當前存在事務,則加入當前事務,如果當前沒有事務,就以非事務方法執行
- MANDATORY:當前存在事務,則加入當前事務,如果當前事務不存在,則拋出例外
- REQUIRES_NEW:創建一個新事務,如果存在當前事務,則掛起該事務
- NOT_SUPPORTED:以非事務方式執行如果當前存在事務,則掛起當前事務
- NEVER:不使用事務,如果當前事務存在,則拋出例外
- NESTED:如果當前事務存在,則在嵌套事務中執行,否則 REQUIRED的操作一樣(開啟一個事務)
NESTED和 REQUIRES_NEW的區別:
REQUIRES_NEW是新建一個事務并且新開啟的這個事務與原有事務無關,而 NESTED則是當前存在事務時(我們把當前事務稱之為父事務)會開啟一個嵌套事務(稱之為一個子事務),在 NESTED情況下父事務回滾時,子事務也會回滾,而在REQUIRES_NEW情況下,原有事務回滾,不會影響新開啟的事務
NESTED和 REQUIRED的區別:
REQUIRED情況下,呼叫方存在事務時,則被呼叫方和呼叫方使用同一事務,那么被呼叫方出現例外時,由于共用一個事務,所以無論呼叫方是否 catch其例外,事務都會回滾而在 NESTED情況下,被呼叫方發生例外時,呼叫方可以 catch其例外,這樣只有子事務回滾,父事務不受影響,
什么是bean的自動裝配?自動裝配有哪些方式?
在Spring框架中,在組態檔中設定了bean的依賴關系,Spring 容器能夠自動裝配相互合作的bean,這意味著容器不需要配置,能通過Bean工廠自動處理bean之間的協作,Spring可以通過向Bean Factory中注入的方式自動搞定bean之間的依賴關系,自動裝配可以設定在每個bean上,也可以設定在特定的bean上,
使用@Autowired注解自動裝配的程序:
使用@Autowired注解來自動裝配指定的bean,在使用@Autowired注解之前需要在Spring組態檔進行配置,<context:annotation-config />,在啟動spring IoC時,容器自動裝載了一個AutowiredAnnotationBeanPostProcessor后置處理器,當容器掃描到@Autowied、@Resource或@Inject時,就會在IoC容器自動查找需要的bean,并裝配給該物件的屬性,在使用@Autowired時,首先在容器中查詢對應型別的bean:
- 如果查詢結果剛好為一個,就將該bean裝配給@Autowired指定的資料;
- 如果查詢的結果不止一個,那么@Autowired會根據名稱來查找;
- 如果上述查找的結果為空,那么會拋出例外,解決方法時,使用required=false,
在spring中,物件無需自己查找或創建與其關聯的其他物件,由容器負責把需要相互協作的物件參考賦予各個物件,使用Autowire來配置自動裝載模式,在Spring框架xml配置中共有5種自動裝配:
- no:默認的方式是不進行自動裝配的,通過手工設定
ref屬性來進行裝配bean, - byName:通過bean的名稱進行自動裝配,如果一個bean的 property 與另一bean 的name 相同,就進行自動裝配,
- byType:通過引數的資料型別進行自動裝配,
- constructor:利用建構式進行裝配,并且建構式的引數通過byType進行裝配,
- autodetect:自動探測,如果有構造方法,通過 construct的方式自動裝配,否則使用 byType的方式自動裝配,
<!--byName-->
<bean id="cutomer" class="com.XXX.XXX.Cutomer" autowire="byName"/>
<bean id="person" class="com.XXX.XXX.Person"/>
<!--byName-->
<bean id="cutomer" class="com.XXX.XXX.Cutomer" autowire="byType"/>
<bean id="person" class="com.XXX.XXX.Person"/>
<!--construtor-->
<bean id="cutomer" class="com.XXX.XXX.Cutomer" autowire="construtor"/>
<bean id="person" class="com.XXX.XXX.Person"/>
自動裝配有哪些局限性?
- 重寫:你仍需用 和 配置來定義依賴,意味著總要重寫自動裝配,
- 基本資料型別:你不能自動裝配簡單的屬性,如基本資料型別,String字串,和類,
- 模糊特性:自動裝配不如顯式裝配精確,如果有可能,建議使用顯式裝配,
Spring MVC的作業流程了解嗎?
MVC 是一種設計模式,Spring MVC 是一款很優秀的 MVC 框架,Spring MVC 可以幫助我們進行更簡潔的Web層的開發,并且它天生與 Spring 框架集成,Spring MVC 下我們一般把后端專案分為 Service層(處理業務)、Dao層(資料庫操作)、Entity層(物體類)、Controller層(控制層,回傳資料給前臺頁面),
SpringMVC作業流程:
- 用戶發送請求至前端控制器 Dispatcherservlet(用來處理HTTP請求與回應)
- Dispatcherservlet 收到請求呼叫 Handler Mapping處理器映射器,
- 處理器映射器找到具體的處理器(可以根據xml配置、注解進行查找),生成處理器及處理器攔截器(如果有則生成)并回傳給 Dispatcherservlet,
- Dispatcherservlet呼叫 HandlerAdapter處理器配接器
- HandleraAapter經過適配呼叫具體的處理器(Controller,也叫后端控制器)
- Controller執行完成回傳 ModelAndView,
- HandlerAdapter將 controller執行結果 ModelAndView回傳給 Dispatcherservlet,
- Dispatcherservlet將 Modelandview傳給 ViewReslover視圖決議器,
- Viewreslover決議后回傳具體View
- Dispatcherservlet根據view進行渲染視圖(即將模型資料填充至視圖中),
- Dispatcherservle回應用戶(瀏覽器),
Spring MVC 的簡單原理圖如下:

Spring MVC的主要組件?
- 前端控制器 DispatcherServlet:用于接收請求、回應結果,相當于轉發器,有了DispatcherServlet 就減少了其它組件之間的耦合度,
- 處理器映射器HandlerMapping:根據請求的URL來查找Handler,SpringMVC中會有許多請求,每個請求都需要一個Handler處理,處理器映射根據請求決定使用那個Handler,
- 處理器配接器HandlerAdapter:Handler可以是任何形式的,但是Servlet的處理方式是固定(request+response),這時需要通過處理器配接器來進行適配,呼叫具體的處理器,回傳ModelAndView,
- 后端控制器(處理器)(Handler):主要負責處理前端請求,完成業務邏輯,生成ModelAndView物件回傳給HandlerAdapter,
- 視圖決議器(ViewResolver):主要負責決議ModelAndView物件,生成View物件回傳給前端控制器,
- 視圖View:View是一個介面, 它的實作類支持不同的視圖型別(jsp,freemarker,pdf等等)
參考文章:
https://gitee.com/SnailClimb/JavaGuide#/SnailClimb/JavaGuide
https://www.bilibili.com/video/BV1Z44y1q7wf
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/293165.html
標籤:java


