中國建設(shè)銀行官方網(wǎng)站站長之家端口掃描
文章目錄
- 請談一下你對 spring 的理解?說一下 Spring 的核心是什么?請談 一下你對 Spring IOC 和 和 AOP 的理解?
- 請說一下 Spring 的 的 Bean 作用域?
- 請談一下Spring中bean對象的生命周期?
- Spring中的事務(wù)是如何實現(xiàn)的 ?
- 請談一下Spring的兩種事務(wù)形式?
- Spring容器啟動流程是怎樣的?
- Spring事務(wù)什么時候會失效?
- BeanFactory 和 ApplicationContext有什么區(qū)別?
- Spring 事務(wù)的傳播行為了解嗎?Spring 提供了幾種事務(wù)的傳播行為?
- Spring事務(wù)的隔離級別?
- 請談一下 Spring 事務(wù)回滾機制 ?
- 說一下過濾器和 Spring 攔截器的區(qū)別 ?
- 攔截器的實現(xiàn)原理是什么?簡單說一下攔截器用場景 ?
- 反射機制了解嗎?知道 spring 中哪些用的反射嗎 ?
- 使用@Autowired注解自動裝配的過程是怎樣的 ?
請談一下你對 spring 的理解?說一下 Spring 的核心是什么?請談 一下你對 Spring IOC 和 和 AOP 的理解?
(1)Spring 框架是一個輕量級的 JavaSE/JavaEE 應(yīng)用開發(fā)框架,是構(gòu)建企業(yè)級應(yīng)用程序的一站式解決方案。
(2)Spring 是模塊化的,并被分為大約 20 個模塊(core、beans、context、web 等),允許我們只使用需要的部分,而不需
要引入其他部分。
(3)Spring 的兩大核心內(nèi)容是 IOC 和 AOP(控制翻轉(zhuǎn)和面向切面編程);
談一下 IOC(Inversion Of Control)
IOC 的意思是控制反轉(zhuǎn),它是一種設(shè)計思想,是一個重要的面向?qū)ο缶幊痰姆▌t;
在 Java 開發(fā)中,Ioc 可以讓我們把設(shè)計好的對象交給容器控制,而不是在對象內(nèi)部直接控制;
對于 spring 框架來說,就是由 spring 來負責控制對象的生命周期和對象間的關(guān)系;
談一下 AOP
(1)AOP 被稱為面向切面編程,是一種編程范式,是對面向?qū)ο缶幊?OOP)的一種完善。
(2)OOP 最大問題就是無法解耦組件進行開發(fā),而 AOP 就是為了克服這個問題而出現(xiàn)的。
(3)AOP 將整個系統(tǒng)分為"核心業(yè)務(wù)邏輯"和"非核心的服務(wù)";
AOP 的關(guān)注點是系統(tǒng)中的“非核心服務(wù)”【權(quán)限;事務(wù);安全;異常;日志等】;
Spring 將非核心服務(wù)封裝成一個 AOP 組件,然后通過配置信息形成"核心業(yè)務(wù)和 AOP 組件"之間的調(diào)用關(guān)系,
當執(zhí)行核心業(yè)務(wù)時,AOP 組件會在合適的時機進行調(diào)用
請說一下 Spring 的 的 Bean 作用域?
- singleton:在 Spring IOC 容器中僅存在一個 Bean 的實例,Bean 以單例的方式存在;
- prototype:每次從容器中調(diào)用 Bean 時,都返回一個新的實例,也就是每次調(diào)用 getBean()方法時,相當于執(zhí)行了 new 對
象的操作; - request:每次 http 請求都會創(chuàng)建一個新的 Bean,該作用域僅適合 WebApplicationContext 環(huán)境;
- session:同一個 http session 共享一個 Bean 實例,不同 session 使用不同的 Bean 實例,該作用域僅適用
WebApplicationContext 環(huán)境; - global session:這種作用域類似于標準的 HTTP Session 作用域,不過僅僅在基于 portlet 的 web 應(yīng)用中才有意義。
請談一下Spring中bean對象的生命周期?
Spring Bean 的生命周期主要分為四個階段,也就是:Bean 的實例化、Bean 屬性賦值、初始化和 Bean 的銷毀
其中前三個階段主要實現(xiàn)在 AbstractAutowireCapableBeanFactory 類中 doCreateBean()方法中;
而"Bean 的銷毀"則是容器關(guān)閉時;
- Spring 啟動,查找并加載需要被 Spring 管理的 bean,進行 Bean 的實例化
- Bean 實例化后對將 Bean 的引入和值注入到 Bean 的屬性中
- 如果 Bean 實現(xiàn)了 BeanNameAware 接口的話,Spring 將 Bean 的 Id 傳遞給 setBeanName()方法
- 如果 Bean 實現(xiàn)了 BeanFactoryAware 接口的話,Spring 將調(diào)用 setBeanFactory()方法,將 BeanFactory 容器實例傳
入 - 如果 Bean 實現(xiàn)了 ApplicationContextAware 接口的話,Spring 將調(diào)用 Bean 的 setApplicationContext()方法,將
bean 所在應(yīng)用上下文引用傳入進來。 - 如果 Bean 實現(xiàn)了 BeanPostProcessor 接口,Spring 就將調(diào)用他們的 postProcessBeforeInitialization()方法。
- 如果 Bean 實現(xiàn)了 InitializingBean 接口,Spring 將調(diào)用他們的 afterPropertiesSet()方法。類似的,如果 bean 使
用 init-method 聲明了初始化方法,該方法也會被調(diào)用 - 如果 Bean 實現(xiàn)了 BeanPostProcessor 接口,Spring 就將調(diào)用他們的 postProcessAfterInitialization()方法。
- 此時,Bean 已經(jīng)準備就緒,可以被應(yīng)用程序使用了。他們將一直駐留在應(yīng)用上下文中,直到應(yīng)用上下文被銷毀。
- 如果 bean 實現(xiàn)了 DisposableBean 接口,Spring 將調(diào)用它的 destory()接口方法,同樣,如果 bean 使用了 destory-
method 聲明銷毀方法,該方法也會被調(diào)用。
Spring中的事務(wù)是如何實現(xiàn)的 ?
- Spring事務(wù)底層是基于數(shù)據(jù)庫事務(wù)和AOP機制的
- ?先對于使?了@Transactional注解的Bean,Spring會創(chuàng)建?個代理對象作為Bean
- 當調(diào)?代理對象的?法時,會先判斷該?法上是否加了@Transactional注解
- 如果加了,那么則利?事務(wù)管理器創(chuàng)建?個數(shù)據(jù)庫連接
- 并且修改數(shù)據(jù)庫連接的autocommit屬性為false,禁?此連接的?動提交,這是實現(xiàn)Spring事務(wù)?
常重要的?步 - 然后執(zhí)?當前?法,?法中會執(zhí)?sql
- 執(zhí)?完當前?法后,如果沒有出現(xiàn)異常就直接提交事務(wù)
- 如果出現(xiàn)了異常,并且這個異常是需要回滾的就會回滾事務(wù),否則仍然提交事務(wù)
- Spring事務(wù)的隔離級別對應(yīng)的就是數(shù)據(jù)庫的隔離級別
- Spring事務(wù)的傳播機制是Spring事務(wù)??實現(xiàn)的,也是Spring事務(wù)中最復雜的
- Spring事務(wù)的傳播機制是基于數(shù)據(jù)庫連接來做的,?個數(shù)據(jù)庫連接?個事務(wù),如果傳播機制配置為
需要新開?個事務(wù),那么實際上就是先建??個數(shù)據(jù)庫連接,在此新數(shù)據(jù)庫連接上執(zhí)?sql
請談一下Spring的兩種事務(wù)形式?
1.Spring 提供了 “編程式事務(wù)” 和 “基于 AOP 方式的聲明式事務(wù)”
2.Spring 編程式事務(wù)管理高層的抽象主要包括三個接口
PlatformTransactionManager:事務(wù)管理器
TransactionDefinition:事務(wù)定義信息(包括事務(wù)的隔離、傳播機制等);
TransactionStatus:事務(wù)具體運行狀態(tài);
其中 Spring 為不同的持久化框架提供了不同事務(wù)管理器 PlatformTransactionManager 的接口實現(xiàn);
比如
使用 Spring JDBC 或 Mybatis 進行持久化數(shù)據(jù)時的 DataSourceTransactionManager;
使用 Hibernate 進行持久化數(shù)據(jù)時的 HibernateTransactionManager;
使用 JPA 進行持久化數(shù)據(jù)時的 JpaTransactionManager;
同時,Spring 可以使用 TransactionTemplate 進行編程式的事務(wù)控制;
Spring 基于 AOP 的聲明式事務(wù)又有三種方式
- 基于 TransactionProxyFactoryBean 的方式
- 基于基于 AspectJ 的方式
- 基于注解方式
Spring容器啟動流程是怎樣的?
- 在創(chuàng)建Spring容器,也就是啟動Spring時:
- ?先會進?掃描,掃描得到所有的BeanDefinition對象,并存在?個Map中
Spring中什么時候@Transactional會失效
Spring容器啟動流程是怎樣的
25 - 然后篩選出?懶加載的單例BeanDefinition進?創(chuàng)建Bean,對于多例Bean不需要在啟動過程中去進
?創(chuàng)建,對于多例Bean會在每次獲取Bean時利?BeanDefinition去創(chuàng)建 - 利?BeanDefinition創(chuàng)建Bean就是Bean的創(chuàng)建?命周期,這期間包括了合并BeanDefinition、推斷
構(gòu)造?法、實例化、屬性填充、初始化前、初始化、初始化后等步驟,其中AOP就是發(fā)?在初始化
后這?步驟中 - 單例Bean創(chuàng)建完了之后,Spring會發(fā)布?個容器啟動事件
- Spring啟動結(jié)束
- 在源碼中會更復雜,?如源碼中會提供?些模板?法,讓?類來實現(xiàn),?如源碼中還涉及到?些
BeanFactoryPostProcessor和BeanPostProcessor的注冊,Spring的掃描就是通過
BenaFactoryPostProcessor來實現(xiàn)的,依賴注?就是通過BeanPostProcessor來實現(xiàn)的 - 在Spring啟動過程中還會去處理@Import等注解
Spring事務(wù)什么時候會失效?
Spring事務(wù)的原理是Aop,進行了切面的增強,那么失效的根本原因是這個AOP不起作用了!
常見的情況有如下幾種
1.發(fā)生自調(diào)用,類里面使用this調(diào)用本類的方法(this通常省略),此時這個this對象不是
代理類,而是UserService對象本身!
解決方法很簡單,讓那個this變成UserService的代理類即可。
2.方法不是public的,@Transaction只能用于public的方法上,否則事務(wù)不會生效,如果用在public的方法上,可以開啟AspectJ代理模式。
3.數(shù)據(jù)庫不支持事務(wù)
4.沒有被spring管理
5.異常被吃掉,事務(wù)不會回滾(或者拋出的異常沒有被定義,默認為RuntimeException)
BeanFactory 和 ApplicationContext有什么區(qū)別?
BeanFactory和ApplicationContext是Spring的兩大核心接口,都可以當做Spring的容器。其中
ApplicationContext是BeanFactory的子接口。
依賴關(guān)系
BeanFactory:是Spring里面最底層的接口,包含了各種Bean的定義,讀取bean配置文檔,管理bean
的加載、實例化,控制bean的生命周期,維護bean之間的依賴關(guān)系。
ApplicationContext接口作為BeanFactory的派生,除了提供BeanFactory所具有的功能外,還提供了
更完整的框架功能:
繼承MessageSource,因此支持國際化。
統(tǒng)一的資源文件訪問方式。
提供在監(jiān)聽器中注冊bean的事件。
同時加載多個配置文件。
載入多個(有繼承關(guān)系)上下文 ,使得每一個上下文都專注于一個特定的層次,比如應(yīng)用的web
層。
加載方式
BeanFactroy采用的是延遲加載形式來注入Bean的,即只有在使用到某個Bean時(調(diào)用getBean()),才
對該Bean進行加載實例化。這樣,我們就不能發(fā)現(xiàn)一些存在的Spring的配置問題。如果Bean的某一個
屬性沒有注入,BeanFacotry加載后,直至第一次使用調(diào)用getBean方法才會拋出異常。
ApplicationContext,它是在容器啟動時,一次性創(chuàng)建了所有的Bean。這樣,在容器啟動時,我們就可
以發(fā)現(xiàn)Spring中存在的配置錯誤,這樣有利于檢查所依賴屬性是否注入。 ApplicationContext啟動后預
載入所有的單實例Bean,通過預載入單實例bean ,確保當你需要的時候,你就不用等待,因為它們已經(jīng)
創(chuàng)建好了。
相對于基本的BeanFactory,ApplicationContext 唯一的不足是占用內(nèi)存空間。當應(yīng)用程序配置Bean較
多時,程序啟動較慢。
創(chuàng)建方式
BeanFactory通常以編程的方式被創(chuàng)建,ApplicationContext還能以聲明的方式創(chuàng)建,如使用
ContextLoader。
注冊方式
BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,
但兩者之間的區(qū)別是:BeanFactory需要手動注冊,而ApplicationContext則是自動注冊。
Spring 事務(wù)的傳播行為了解嗎?Spring 提供了幾種事務(wù)的傳播行為?
- REQUIRED:表示如果當前存在一個事務(wù),則加入該事務(wù),否則將新建一個事務(wù);
- REQUIRES_NEW:表示不管是否存在事務(wù),都創(chuàng)建一個新的事務(wù),原來的掛起,新的執(zhí)行完畢,繼續(xù)執(zhí)行老的事務(wù);
- SUPPORTS:表示如果當前存在事務(wù),就加入該事務(wù);如果當前沒有事務(wù),那就不使用事務(wù);
- NOT_SUPPORTED: 表示不使用事務(wù);如果當前存在事務(wù),就把當前事務(wù)暫停,以非事務(wù)方式執(zhí)行;
- MANDATORY:表示必須在一個已有的事務(wù)中執(zhí)行,如果當前沒有事務(wù),則拋出異常;
- NEVER:表示以非事務(wù)方式執(zhí)行,如果當前存在事務(wù),則拋出異常;
- NESTED:這個是嵌套事務(wù);如果當前存在事務(wù),則在嵌套事務(wù)內(nèi)執(zhí)行;如果當前不存在事務(wù),則創(chuàng)建一個新的事務(wù);
嵌套事務(wù)使用數(shù)據(jù)庫中的保存點來實現(xiàn),即嵌套事務(wù)回滾不影響外部事務(wù),但外部事務(wù)回滾將導致嵌套事務(wù)回滾;
Spring事務(wù)的隔離級別?
隔離級別是指若干個并發(fā)的事務(wù)之間的隔離程度。TransactionDefinition 接口中定義了五個表示隔離級別的常量:
- ISOLATION_DEFAULT:默認的
這是默認值,表示使用底層數(shù)據(jù)庫的默認隔離級別。對大部分數(shù)據(jù)庫而言,通常這值就是 ISOLATION_READ_COMMITTED。 - ISOLATION_READ_UNCOMMITTED:未提交讀
該隔離級別表示一個事務(wù)可以讀取另一個事務(wù)修改但還沒有提交的數(shù)據(jù)。
該級別不能防止臟讀、不可重復讀和幻讀,因此很少使用該隔離級別。 - ISOLATION_READ_COMMITTED:已提交讀
該隔離級別表示一個事務(wù)只能讀取另一個事務(wù)已經(jīng)提交的數(shù)據(jù)。
該級別可以防止臟讀,這也是大多數(shù)情況下的推薦值。 - ISOLATION_REPEATABLE_READ:可重復讀
該隔離級別表示一個事務(wù)在整個過程中可以多次重復執(zhí)行某個查詢,并且每次返回的記錄都相同。
該級別可以防止臟讀、不可重復讀。 - ISOLATION_SERIALIZABLE:序列化
所有的事務(wù)依次逐個執(zhí)行,這樣事務(wù)之間就完全不可能產(chǎn)生干擾;
也就是說,該級別可以防止臟讀、不可重復讀以及幻讀。
但是這將嚴重影響程序的性能。通常情況下也不會用到該級別。
請談一下 Spring 事務(wù)回滾機制 ?
默認情況下,Spring 只有在拋出的異常是運行時異常(“非檢查型”)時才回滾該事務(wù);
也就是拋出的異常為 RuntimeException 的子類(Errors 也會導致事務(wù)回滾);
而拋出非運行時異常(檢查型)則不會導致事務(wù)回滾;
但是,我們可以明確的配置拋出哪些異常時回滾事務(wù),包括 checked 異常。也可以定義哪些異常拋出時不回滾事務(wù)。
說一下過濾器和 Spring 攔截器的區(qū)別 ?
攔截器和過濾器都是 AOP 編程思想的體現(xiàn),都能實現(xiàn)權(quán)限檢查、日志記錄等。
攔截器是基于反射實現(xiàn),更準確的說是通過 jdk 的動態(tài)代理實現(xiàn); 過濾器是基于函數(shù)回調(diào)。
攔截器不依賴于 Servlet 容器,過濾器依賴于 Servlet 容器,它屬于 Servlet 規(guī)范規(guī)定的。
攔截器只能對 Controller 請求起作用,過濾器則可以對幾乎所有的請求起作用。
攔截器可以訪問 controller 上下文的對象(如 service 對象、數(shù)據(jù)源等),過濾器則不可以訪問.
攔截器可以深入的方法前后、異常拋出前后等,并且可以重復調(diào)用; 過濾器只在 Servlet 前后起作用,并且只在初始化
時被調(diào)用一次.
Java 中的攔截器是基于 Java 反射機制實現(xiàn)的,更準確的劃分,應(yīng)該是基于 JDK 實現(xiàn)的動態(tài)代理;
它依賴于具體的接口,在運行期間動態(tài)生成字節(jié)碼。
使用場景:日志記錄、權(quán)限檢查、性能監(jiān)控、通用行為
攔截器的實現(xiàn)原理是什么?簡單說一下攔截器用場景 ?
Java 中的攔截器是基于 Java 反射機制實現(xiàn)的,更準確的劃分,應(yīng)該是基于 JDK 實現(xiàn)的動態(tài)代理;
它依賴于具體的接口,在運行期間動態(tài)生成字節(jié)碼。
使用場景:
1、日志記錄:記錄請求信息的日志,以便進行信息監(jiān)控、信息統(tǒng)計、計算 PV(Page View)等。
2、權(quán)限檢查:比如登錄檢查,進入處理器之前檢查是否登錄,如果沒有直接返回到登錄頁面;
3、性能監(jiān)控:有時候系統(tǒng)在某段時間莫名其妙的慢,可以通過攔截器在進入處理器之前記錄開始時間,
在處理完后記錄結(jié)束時間,從而得到該請求的處理時間(如果有反向代理,如 apache 可以自動記錄);
4、通用行為:讀取 cookie 得到用戶信息并將用戶對象放入請求,從而方便后續(xù)流程使用;
反射機制了解嗎?知道 spring 中哪些用的反射嗎 ?
- 反射是 JAVA 語言提供一套在運行期動態(tài)獲得類中信息的 API。
- 通過反射,可以在運行期動態(tài)的獲得類中的屬性和方法,對于任意一個對象,都能夠調(diào)用它的任意一個方法和屬性(包括私
有的方法和屬性)
通過反射,可以在運行期動態(tài)的創(chuàng)建類的對象。
通過反射,可以在運行期動態(tài)的執(zhí)行類中的方法。
Spring 通過反射創(chuàng)建對象,并將對象放到 spring ioc 容器中。
Spring 的攔截器也是基于反射實現(xiàn)的。
使用@Autowired注解自動裝配的過程是怎樣的 ?
使用@Autowired注解來自動裝配指定的bean。在使用@Autowired注解之前需要在Spring配置文件進
行配置,<context:annotation-config />。
在啟動spring IoC時,容器自動裝載了一個AutowiredAnnotationBeanPostProcessor后置處理器,當
容器掃描到@Autowied、@Resource或@Inject時,就會在IoC容器自動查找需要的bean,并裝配給該
對象的屬性。在使用@Autowired時,首先在容器中查詢對應(yīng)類型的bean:
如果查詢結(jié)果剛好為一個,就將該bean裝配給@Autowired指定的數(shù)據(jù);
如果查詢的結(jié)果不止一個,那么@Autowired會根據(jù)名稱來查找;
如果上述查找的結(jié)果為空,那么會拋出異常。解決方法時,使用required=false。