Spring有哪些特色?前端
使用Spring有什麼好處?java
1 應用解耦mysql
2 依賴注入git
3 AOPweb
4 事務管理spring
5 MVCsql
6 集成開發數據庫
Spring應用程序看起來像什麼?apache
一些接口及其實現編程
一些POJO類
一些xml配置文件
Spring核心容器模塊是什麼?
Spring core/IOC/BeanFactory
核心容器(Spring Core)
核心容器提供Spring框架的基本功能。Spring以bean的方式組織和管理Java應用中的各個組件及其關係。Spring使用BeanFactory來產生和管理Bean,它是工廠模式的實現。BeanFactory使用控制反轉(IoC)模式將應用的配置和依賴性規範與實際的應用程序代碼分開。
爲了下降Java開發的複雜性, Spring採起了哪幾種策略
POJO/IOC/AOP/Template
基於POJO的輕量性和最小侵入性編程
經過依賴注入和麪向接口實現鬆耦合
基於切面和慣例進行聲明式編程
經過切面和模板減小樣板式代碼
談談Spring框架幾個主要部分組成
Spring core/beans/context/aop/jdbc/tx/web mvc/orm
說一下Spring中支持的bean做用域
Singleton/prototype/request/session
singleton:單例模式,在整個Spring IoC容器中,使用singleton定義的Bean將只有一個實例。
prototype:原型模式,每次經過容器的getBean方法獲取prototype定義的Bean時,都將產生一個新的Bean實例。
request:對於每次HTTP請求,使用request定義的Bean都將產生一個新實例,即每次HTTP請求將會產生不一樣的Bean實例。只有在Web應用中使用Spring時該做用域纔有效。
session:對於每次HTTP Session,使用session定義的Bean都將產生一個新實例。一樣只有在Web應用中使用Spring時該做用域纔有效。
Spring框架中單例beans是線程安全的嗎?爲何?
不是線程安全(默認singleton)
當多個線程併發執行該請求對應的業務邏輯(成員方法),若是該處理邏輯中有對單例狀態的修改(單例的成員屬性),則必須考慮線程同步問題。
解釋Spring框架中bean的生命週期
哪些是最重要的bean生命週期方法?能重寫它們嗎?
Setup/teardown
Xml中對應Init-method/destory-method
@PostConstruct @PreDestory
bean標籤有兩個重要的屬性(init-method 和 destroy-method),能夠經過這兩個屬性定義本身的初始化方法和析構方法。Spring也有相應的註解:@PostConstruct 和 @PreDestroy。
Spring容器實例化Bean有多少種方法?分別是什麼?
使用類構造器
使用靜態工廠方法
Xml配置文件factory-method
如何減小Spring XML的配置數量
使用Java配置文件,使xml中的bean轉爲Javaconfig文件方式
註解的方式
什麼是bean自動裝配?並解釋自動裝配的各類模式?
Spring容器能夠自動配置相互協做beans之間的關聯關係。這意味着Spring能夠自動配置一個bean和其餘協做bean之間的關係,經過檢查BeanFactory 的內容裏沒有使用和< property>元素。
一個類就是一個Bean,Spring框架是一個Bean容器,替咱們管理這些Bean,Spring就是來組織各個角色之間的關係,而後對這些角色進行調動。
自動裝配:
自動裝配有哪些好處和壞處?
自動裝配的優勢以下:
雖然自動裝配具備上面這些優勢,但不是說何時均可以使用它,由於它還有以下一些缺點:
是否是全部類型都能自動裝配?若是不是請舉例
不是。原生類型/字符串類型不能夠自動裝配
什麼是循環依賴?
循環依賴就是N個類中循環嵌套引用,若是在平常開發中咱們用new 對象的方式發生這種循環依賴的話程序會在運行時一直循環調用,直至內存溢出報錯。
public class PersonA { private PersonB personB; public PersonA(PersonB personB) { this.personB = personB; } } public class PersonB { private PersonC personC; public PersonB(PersonC personC) { this.personC = personC; } } public class PersonC { private PersonA personA; public PersonC(PersonA personA) { this.personA = personA; } }
Spring如何解決循環依賴?
DefaultSingletonBeanRegistry.getSingleton源碼中有3個cache:
getSingleton()的整個過程,Spring首先從一級緩存singletonObjects中獲取。若是獲取不到,而且對象正在建立中,就再從二級緩存earlySingletonObjects中獲取。若是仍是獲取不到且容許singletonFactories經過getObject()獲取,就從三級緩存singletonFactory.getObject()(三級緩存)獲取。
解析:
PersonA的setter依賴了PersonB的實例對象,同時PersonB的setter依賴了PersonA的實例對象」這種循環依賴的狀況。
PersonA首先完成了初始化的第一步,而且將本身提早曝光到singletonFactories中,此時進行初始化的第二步,發現本身依賴對象PersonB,此時就嘗試去get(PersonB),發現PersonB尚未被create,因此執行create流程,PersonB在初始化第一步的時候發現本身依賴了對象PersonA,因而嘗試get(PersonA),嘗試一級緩存singletonObjects(確定沒有,由於A還沒初始化徹底),嘗試二級緩存earlySingletonObjects(也沒有),嘗試三級緩存singletonFactories,因爲PersonA經過ObjectFactory將本身提早曝光了,因此PersonB可以經過ObjectFactory.getObject拿到PersonA對象(雖然PersonA尚未初始化徹底),PersonB拿到PersonA對象後順利完成了初始化階段一、二、3,徹底初始化以後將本身放入到一級緩存singletonObjects中。此時返回PersonA中,PersonA此時能拿到PersonB的對象順利完成本身的初始化階段二、3,最終A也完成了初始化,進去了一級緩存singletonObjects中。並且,因爲PersonB拿到了PersonA的對象引用,因此PersonB如今中的PersonA對象完成了初始化。
SpringMVC的工做流程和原理是什麼?
SpringMVC與Struts2的主要區別?
區別1:
Struts2 的核心是基於一個Filter即StrutsPreparedAndExcuteFilter
SpringMvc的核心是基於一個Servlet即DispatcherServlet(前端控制器)
區別2:
Struts2是基於類開發的,傳遞的參數是經過類的屬性傳遞(屬性驅動和模型驅動),因此只能設計成多例prototype
SpringMvc是基於類中的方法開發的,也就是一個url對應一個方法,傳遞參數是傳到方法的形參上面,因此既能夠是單例模式也能夠是多例模式singiton
區別3:
Struts2採用的是值棧存儲請求以及響應數據,OGNL存取數據
SpringMvc採用request來解析請求內容,而後由其內部的getParameter給方法中形參賦值,再把後臺處理過的數據經過ModelAndView對象存儲,Model存儲數據,View存儲返回的頁面,再把對象經過request傳輸到頁面去。
SpringMVC的控制器是否是單例模式,若是是有什麼問題,怎麼解決
是。單例若是有非靜態成員變量保存狀態會有線程安全問題。
解決辦法1:不要有成員變量,都是方法。
解決辦法2:@Scope(「prototype」)
Spring註解的基本概念和原理
註解(Annotation),也叫元數據。一種代碼級別的說明。
Spring註解分爲:
1.類級別的註解:如@Component、@Repository、@Controller、@Service以及JavaEE6的@ManagedBean和@Named註解,都是添加在類上面的類級別註解。
Spring容器根據註解的過濾規則掃描讀取註解Bean定義類,並將其註冊到Spring IoC容器中。
2.類內部的註解:如@Autowire、@Value、@Resource以及EJB和WebService相關的註解等,都是添加在類內部的字段或者方法上的類內部註解。
SpringIoC容器經過Bean後置註解處理器解析Bean內部的註解。
舉例說明什麼是Spring基於Java的配置?
Spring3.0以前都是基於XML配置的,Spring3.0開始能夠幾乎不使用XML而使用純粹的java代碼來配置Spring應用。
@Configuration @EnableTransactionManagement public class AppConfig implements TransactionManagementConfigurer { @Bean public DruidDataSource dataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setUrl("jdbc:mysql://localhost:3306/sqoop"); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUsername("root"); dataSource.setPassword("abcd_123"); return dataSource; } @Bean public JdbcTemplate jdbcTemplate(DruidDataSource dataSource) { return new JdbcTemplate(dataSource); } @Bean public PlatformTransactionManager txManager() { return new DataSourceTransactionManager(dataSource()); } @Override public PlatformTransactionManager annotationDrivenTransactionManager() { return txManager(); } }
什麼是基於註解的容器配置?
XML解耦了配置和原代碼,而註解則精簡了配置。spring框架基於註解的容器配置:
@Qualifier
@Autowired
@Resource
@PostContuct
@PreDestory
@Autowired @Resource @Inject 的區別
@Resource
一、@Resource是JSR250規範的實現,須要導入javax.annotation實現注入。
二、@Resource是根據名稱進行自動裝配的,通常會指定一個name屬性
三、@Resource能夠做用在變量、setter方法上。
@Autowired
一、@Autowired是spring自帶的,@Inject是JSR330規範實現的,@Resource是JSR250規範實現的,須要導入不一樣的包
二、@Autowired、@Inject用法基本同樣,不一樣的是@Autowired有一個request屬性
三、@Autowired、@Inject是默認按照類型匹配的,@Resource是按照名稱匹配的
四、@Autowired若是須要按照名稱匹配須要和@Qualifier一塊兒使用,@Inject和@Name一塊兒使用
什麼是AOP,有什麼做用,能應用在什麼場景?
面向切面編程。
AOP主要做用
將日誌記錄,性能統計,安全控制,事務處理,異常處理等代碼從業務邏輯代碼中劃分出來,經過對這些行爲的分離,咱們但願能夠將它們獨立到非指導業務邏輯的方法中,進而改變這些行爲的時候不影響業務邏輯的代碼。
總之,面向切面的目標與面向對象的目標沒有不一樣。一是減小重複,二是專一業務。
AOP應用場景
日誌記錄,性能統計,安全控制,事務處理,異常處理等問題及擴展
什麼是織入,織入的時機是什麼
把切面(aspect)鏈接到其它的應用程序類型或者對象上,並建立一個被通知(advised)的對象,這樣的行爲叫作織入。
織入操做能夠發生在以下幾個階段。
編譯期織入是指在Java編譯期,將切面織入到Java類中;而類加載期織入則指經過特殊的類加載器,在類字節碼加載到JVM時,織入切面;運行期織入則是採用CGLib工具或JDK動態代理進行切面的織入
什麼是切入點,關注點,鏈接點
鏈接點(JoinPoint) spring容許你是通知(Advice)的地方,基本每一個方法的前、後、環繞或拋出異常時均可以是鏈接點,spring只支持方法鏈接點。其餘如AspectJ還可讓你在構造器或屬性注入時都行。
切入點(Pointcut) 一個類裏,有N個方法就有N個鏈接點,可是你並不想在全部方法上都使用通知,只想讓其中幾個方法執行前、後或者拋出異常完成其餘功能(如日誌,性能分析),那麼就用切入點來篩選到那幾個你想要的方法。
public class BusinessLogic { public void doSomething() { // 驗證安全性;Securtity關注點 // 執行前記錄日誌;Logging關注點 doit(); // 保存邏輯運算後的數據;Persistence關注點 // 執行結束記錄日誌;Logging關注點 } }
Business Logic屬於核心關注點,它會調用到Security,Logging,Persistence等橫切關注點。
Spring提供了幾種AOP支持?
方式一:經典的基於代理的AOP
方式二:@AspectJ註解的切面
方式三:純POJO切面
AOP經常使用的實現方式有兩種,一種是採用聲明的方式來實現(基於XML),一種是採用註解的方式來實現(基於AspectJ)。
舉例說明什麼是事物以及其特色
事務是爲了保證對同一數據表操做的一致性。
Java EE事務類型有哪些?應用場景是什麼?Spring是如何實現的?
通常J2EE服務器支持三種類型的事務管理。即:JDBC事務,JTA事務,容器管理事務。
JDBC事物接口:PlatformTransactionManager、AbstractPlatformTransactionManager、DataSourceTransactionManager
JTA具備三個主要的接口:UserTransaction、JTATransactionManager、Transaction接口
容器級事務主要是由容器提供的事務管理,如:WebLogic/Websphere
Spring有幾個事物隔離級別,分別詳述
事務隔離級別(5種)
DEFAULT 這是一個PlatfromTransactionManager默認的隔離級別,使用數據庫默認的事務隔離級別。
未提交讀(read uncommited) :髒讀,不可重複讀,虛讀都有可能發生。
已提交讀 (read commited):避免髒讀。可是不可重複讀和虛讀有可能發生。
可重複讀 (repeatable read) :避免髒讀和不可重複讀.可是虛讀有可能發生。
串行化的 (serializable) :避免以上全部讀問題。
Mysql 默認:可重複讀
Oracle 默認:讀已提交
read uncommited:是最低的事務隔離級別,它容許另一個事務能夠看到這個事務未提交的數據。
read commited:保證一個事物提交後才能被另一個事務讀取。另一個事務不能讀取該事物未提交的數據。
repeatable read:這種事務隔離級別能夠防止髒讀,不可重複讀。可是可能會出現幻象讀。它除了保證一個事務不能被另一個事務讀取未提交的數據以外還避免瞭如下狀況產生(不可重複讀)。
serializable:這是花費最高代價但最可靠的事務隔離級別。事務被處理爲順序執行。除了防止髒讀,不可重複讀以外,還避免了幻象讀(避免三種)。
描述下SpringJDBC的架構
Spring JDBC提供了一套JDBC抽象框架,用於簡化JDBC開發。
Spring主要提供JDBC模板方式、關係數據庫對象化方式、SimpleJdbc方式、事務管理來簡化JDBC編程。
support包:提供將JDBC異常轉換爲DAO非檢查異常轉換類、一些工具類如JdbcUtils等。
datasource包:提供簡化訪問JDBC 數據源(javax.sql.DataSource實現)工具類,並提供了一些DataSource簡單實現類從而能使從這些DataSource獲取的鏈接能自動獲得Spring管理事務支持。
core包:提供JDBC模板類實現及可變部分的回調接口,還提供SimpleJdbcInsert等簡單輔助類。
object包:提供關係數據庫的對象表示形式,如MappingSqlQuery、SqlUpdate、SqlCall
描述下Spring事務處理類及其做用
Spring框架支持事務管理的核心是事務管理器抽象,對於不一樣的數據訪問框架(如Hibernate)經過實現策略接口PlatformTransactionManager。該接口由3個方法組成:
getTransaction():返回一個已經激活的事務或建立一個新的事務(根據給定的TransactionDefinition類型參數定義的事務屬性),返回的是TransactionStatus對象表明了當前事務的狀態,該方法拋出TransactionException(未檢查異常)表示事務因爲某種緣由失敗。
commit():用於提交TransactionStatus參數表明的事務
rollback():用於回滾TransactionStatus參數表明的事務
編程式事務
一、直接使用PlatformTransactionManager實現
二、使用TransactionTemplate模板類,用於支持邏輯事務管理。
聲明式事務
一、AOP代理方式實現
二、@Transactional實現事務管理
<tx:annotation-driven transaction-manager="transactionManager"
Spring提供幾種事物實現?分別是什麼?各有什麼優缺點?
一種編程式和三種聲明式
一種編程式(基於底層 API txManager.getTransaction方式或基於TransactionTemplate)
三種聲明式:AOP(TransactionProxyFactoryBean),基於AspectJ的聲明式事務<tx:advice>,基於註解方式的聲明式事務(@Transactional)編程式事務侵入性比較強,但處理粒度更細。
JdbcTemplate有哪些主要方法
CRUD操做所有包含在JdbcTemplate
ResultSetExtractor/RowMapper/RowCallbackHandler
JdbcTemplate支持哪些回調類
一、RowMapper是一個精簡版的ResultSetExtractor,RowMapper可以直接處理一條結果集內容,而ResultSetExtractor須要咱們本身去ResultSet中去取結果集的內容,可是ResultSetExtractor擁有更多的控制權,在使用上能夠更靈活;
二、與RowCallbackHandler相比,ResultSetExtractor是無狀態的,他不可以用來處理有狀態的資源。
什麼是MyBatis?簡述MyBatis的體系結構
Mybatis的功能架構分爲三層:
列舉MyBatis的經常使用API及方法
org.apache.ibatis.session.SqlSession
MyBatis工做的主要頂層API,表示和數據庫交互的會話。完畢必要數據庫增刪改查功能。
org.apache.ibatis.executor.Executor
MyBatis執行器,是MyBatis 調度的核心,負責SQL語句的生成和查詢緩存的維護。
org.apache.ibatis.executor.statement.StatementHandler
封裝了JDBC Statement操做。負責對JDBC statement 的操做。如設置參數、將Statement結果集轉換成List集合。
org.apache.ibatis.executor.parameter.ParameterHandler
負責對用戶傳遞的參數轉換成JDBC Statement 所需要的參數。
org.apache.ibatis.executor.resultset.ResultSetHandler
負責將JDBC返回的ResultSet結果集對象轉換成List類型的集合
org.apache.ibatis.type.TypeHandler
負責java數據類型和jdbc數據類型之間的映射和轉換
org.apache.ibatis.mapping.MappedStatement
MappedStatement維護了一條<select|update|delete|insert>節點的封裝
org.apache.ibatis.mapping.SqlSource
負責依據用戶傳遞的parameterObject,動態地生成SQL語句,將信息封裝到BoundSql對象中,並返回
org.apache.ibatis.mapping.BoundSql
表示動態生成的SQL語句以及對應的參數信息
org.apache.ibatis.session.Configuration
MyBatis所有的配置信息都維持在Configuration對象之中
對於Hibernate和MyBatis的區別與利弊,談談你的見解
一、hibernate真正掌握要比mybatis難,由於hibernate的功能和特性很是多,還不適合多表關聯查詢。
二、hibernate查詢會將全部關聯表的字段所有查詢出來,會致使性能消耗,固然hibernate也能夠本身寫sql指定字段,但這就破壞了hibernate的簡潔性。mybatis的sql是本身手動編寫的,因此能夠指定查詢字段。
三、hibernate與數據庫管聯只需在xml文件中配置便可,全部的HQL語句都與具體使用的數據庫無關,移植性很好;mybatis全部的sql都是依賴所用數據庫的,因此移植性差。
四、hibernate是在jdbc上進行一次封裝,mybatis是基於原生的jdbc,運行速度較快。
五、若是有上千萬的表或者單次查詢或提交百萬數據以上不建議使用hibernate。若是統計功能、多表關聯查詢較多較複雜建議使用mybatis。
#{}和${}的區別是什麼?
select * from location where id = ${id} => Select * from location where id = xxx;
Select * from location where id = #{} => Select * from location where id="xxxx";
${}方式沒法防止sql注入;
Order by動態參數時,使用${}而不用#{}
模糊查詢的時候使用${}
select * from location where name like '${}%';
Mybatis是如何進行分頁的?分頁插件的原理是什麼?
RowBounds針對ResultSet結果集執行分頁
<select id="selectById" parameterType="int" resultType="com.dongnao.demo.dao.Location"> select * from location where id = #{id} </select>
插件分頁
@Intercepts
分頁插件的基本原理是使用Mybatis提供的插件接口,實現自定義插件,在插件的攔截方法內攔截待執行的sql,而後重寫sql,根據dialect方言,添加對應的物理分頁語句和物理分頁參數。
簡述Mybatis的插件運行原理,以及如何編寫一個插件
Mybatis僅能夠編寫針對ParameterHandler、ResultSetHandler、StatementHandler、Executor這4種接口的插件。
Mybatis使用JDK的動態代理,爲須要攔截的接口生成代理對象以實現接口方法攔截功能,每當執行這4種接口對象的方法時,就會進入攔截方法,具體就是InvocationHandler的invoke()方法。固然,只會攔截那些你指定須要攔截的方法。
實現Mybatis的Interceptor接口並複寫intercept()方法,而後在給插件編寫註解,指定要攔截哪個接口的哪些方法便可。記住,別忘了在配置文件中配置你編寫的插件。
Mybatis動態sql是作什麼的?都有哪些動態sql?簡述一下動態sql的執行原理
Mybatis動態sql可讓咱們在Xml映射文件內,以標籤的形式編寫動態sql,完成邏輯判斷和動態拼接sql的功能。
Mybatis提供了9種動態sql標籤trim|where|set|foreach|if|choose|when|otherwise|bind
原理爲,使用OGNL從sql參數對象中計算表達式的值,根據表達式的值動態拼接sql,以此來完成動態sql的功能。
動態SQL,主要用於解決查詢條件不肯定的狀況:在程序運行期間,根據提交的查詢條件進行查詢。
動態SQL,即經過MyBatis提供的各類標籤對條件做出判斷以實現動態拼接SQL語句。
Mybatis是否支持延遲加載?若是支持,它的實現原理是什麼?
Mybatis僅支持association關聯對象和collection關聯集合對象的延遲加載,association指的就是一對一,collection指的就是一對多查詢。在Mybatis配置文件中,能夠配置是否啓用延遲加載lazyLoadingEnabled=true|false。
它的原理是,使用CGLIB建立目標對象的代理對象。當調用目標方法時,進入攔截器方法,如:調用a.getB().getName(),攔截器invoke()方法發現a.getB()是null值,那麼就會單獨發送事先保存好的查詢關聯B對象的sql,把B查詢上來,而後調用a.setB(b),因而a的對象b屬性就有值了,接着完成a.getB().getName()方法的調用。這就是延遲加載的基本原理。
Mybatis的Xml映射文件中,不一樣的Xml映射文件,id是否能夠重複?
能夠。Mybatis namespace+id
Mybatis都有哪些Executor執行器?它們之間的區別是什麼?
SimpleExecutor執行一次sql,開始建立一個statement,用完關閉statement
ReuseExector 相似數據庫鏈接池,statement用完後返回,statement能夠複用
BatchExecutor主要用於批處理執行
Mybatis是否能夠映射Enum枚舉類?
能夠。Mybatis能夠映射枚舉類,不單能夠映射枚舉類,Mybatis能夠映射任何對象到表的一列上。
Mybatis可否執行一對1、一對多關聯查詢?都有哪些實現方式,它們之間有什麼區別
能,Mybatis不只能夠執行一對1、一對多的關聯查詢,還能夠執行多對一,多對多的關聯查詢。
什麼是MyBatis的接口綁定,有什麼好處
接口映射就是在IBatis中任意定義接口,而後把接口裏邊的方法和SQL語句綁定,咱們能夠直接調用接口方法,比起SqlSession提供的方法咱們能夠有更加靈活的選擇和設置。
iBatis和MyBatis在細節上的不一樣有哪些
區別太多,篇幅太長,你們能夠自行百度下。
講下MyBatis的緩存
MyBatis 提供了查詢緩存來緩存數據,以提升查詢的性能。MyBatis 的緩存分爲一級緩存和二級緩存。
一級緩存是 SqlSession 級別的緩存
二級緩存是 mapper 級別的緩存,多個 SqlSession 共享
一級緩存
一級緩存是SqlSession級別的緩存,是基於HashMap的本地緩存。不一樣的 SqlSession之間的緩存數據區域互不影響。
一級緩存的做用域是SqlSession範圍,當同一個SqlSession執行兩次相同的 sql語句時,第一次執行完後會將數據庫中查詢的數據寫到緩存,第二次查詢時直接從緩存獲取不用去數據庫查詢。當SqlSession執行insert、update、delete 操作並提交到數據庫時,會清空緩存,保證緩存中的信息是最新的。
MyBatis默認開啓一級緩存。
二級緩存
二級緩存是mapper級別的緩存,一樣是基於HashMap進行存儲,多個SqlSession能夠共用二級緩存,其做用域是mapper的同一個namespace。不一樣的SqlSession兩次執行相同的namespace下的sql語句,會執行相同的sql,第二次查詢只會查詢第一次查詢時讀取數據庫後寫到緩存的數據,不會再去數據庫查詢。
MyBatis 默認沒有開啓二級緩存,開啓只需在配置文件中寫入以下代碼:
<settings> <setting name="cacheEnabled" value="true"/> </settings>