1.1. 不一樣版本的 Spring Framework 有哪些主要功能?前端
Spring 是一個開源應用框架,旨在下降應用程序開發的複雜度。java
它是輕量級、鬆散耦合的。git
它具備分層體系結構,容許用戶選擇組件,同時還爲 J2EE 應用程序開發提供了一個有凝聚力的框架。github
它能夠集成其餘框架,如 Structs、Hibernate、EJB 等,因此又稱爲框架的框架。web
因爲 Spring Frameworks 的分層架構,用戶能夠自由選擇本身須要的組件。面試
Spring Framework 支持 POJO(Plain Old Java Object) 編程,從而具有持續集成和可測試性。正則表達式
因爲依賴注入和控制反轉,JDBC 得以簡化。spring
它是開源免費的。數據庫
輕量級 - Spring 在代碼量和透明度方面都很輕便。編程
IOC - 控制反轉
AOP - 面向切面編程能夠將應用業務邏輯和系統服務分離,以實現高內聚。
容器 - Spring 負責建立和管理對象(Bean)的生命週期和配置。
MVC - 對 web 應用提供了高度可配置性,其餘框架的集成也十分方便。
事務管理 - 提供了用於事務管理的通用抽象層。Spring 的事務支持也可用於容器較少的環境。
JDBC 異常 - Spring 的 JDBC 抽象層提供了一個異常層次結構,簡化了錯誤處理策略。
Spring 核心容器 – 該層基本上是 Spring Framework 的核心。**它包含如下模塊:**
Spring Core
Spring Bean
SpEL (Spring Expression Language)
數據訪問/集成 – 該層提供與數據庫交互的支持。它包含如下模塊:
JDBC (Java DataBase Connectivity)
ORM (Object Relational Mapping)
OXM (Object XML Mappers)
JMS (Java Messaging Service)
Web – 該層提供了建立 Web 應用程序的支持。它包含如下模塊:
Web
Web – Servlet
Web – Socket
AOP – 該層支持面向切面編程
Instrumentation – 該層爲類檢測和類加載器實現提供支持。
Test – 該層爲使用 JUnit 和 TestNG 進行測試提供支持。
幾個雜項模塊:
Messaging – 該模塊爲 STOMP 提供支持。它還支持註解編程模型,該模型用於從 WebSocket 客戶端路由和處理 STOMP 消息
Spring 配置文件是 XML 文件。該文件主要包含類信息。它描述了這些類是如何配置以及相互引入的。可是,XML 配置文件冗長且更加乾淨。若是沒有正確規劃和編寫,那麼在大項目中管理變得很是困難。
Spring 應用通常有如下組件:
接口 - 定義功能。
Bean 類 - 它包含屬性,setter 和 getter 方法,函數等。
Spring 面向切面編程(AOP) - 提供面向切面編程的功能。
Bean 配置文件 - 包含類的信息以及如何配置它們。
用戶程序 - 它使用接口。
使用 Spring 有如下方式:
做爲一個成熟的 Spring Web 應用程序。
做爲第三方 Web 框架,使用 Spring Frameworks 中間層。
用於遠程使用。
Spring 框架的核心是 Spring 容器。容器建立對象,將它們裝配在一塊兒,配置它們並管理它們的完整生命週期。Spring 容器使用依賴注入來管理組成應用程序的組件。
容器經過讀取提供的配置元數據來接收對象進行實例化,配置和組裝的指令。該元數據能夠經過 XML,Java 註解或 Java 代碼提供。
在依賴注入中,您沒必要建立對象,但必須描述如何建立它們。您不是直接在代碼中將組件和服務鏈接在一塊兒,而是描述配置文件中哪些組件須要哪些服務。由 IoC 容器將它們裝配在一塊兒。
一般,依賴注入能夠經過三種方式完成,即:
*構造函數注入
*setter 注
在 Spring Framework 中,僅使用構造函數和 setter 注入。
BeanFactory | ApplicationContext |
---|---|
它使用懶加載 | 它使用即時加載 |
它使用語法顯式提供資源對象 | 它本身建立和管理資源對象 |
不支持國際化 | 支持國際化 |
不支持基於依賴的註解 | 支持基於依賴的註解 |
IoC 的一些好處是:
它將最小化應用程序中的代碼量。
它將使您的應用程序易於測試,由於它不須要單元測試用例中的任何單例或 JNDI 查找機制。
它以最小的影響和最少的侵入機制促進鬆耦合。
Spring 中的 IoC 的實現原理就是工廠模式加反射機制。
示例:
interface Fruit { public abstract void eat(); } class Apple implements Fruit { public void eat(){ System.out.println("Apple"); } } class Orange implements Fruit { public void eat(){ System.out.println("Orange"); } } class Factory { public static Fruit getInstance(String ClassName) { Fruit f=null; try { f=(Fruit)Class.forName(ClassName).newInstance(); } catch (Exception e) { e.printStackTrace(); } return f; } } class Client { public static void main(String[] a) { Fruit f=Factory.getInstance("io.github.dunwu.spring.Apple"); if(f!=null){ f.eat(); } } }
它們是構成用戶應用程序主幹的對象。
Bean 由 Spring IoC 容器管理。
它們由 Spring IoC 容器實例化,配置,裝配和管理。
bean 所需的依賴項和服務在 XML 格式的配置文件中指定。這些配置文件一般包含許多 bean 定義和特定於應用程序的配置選項。它們一般以 bean 標籤開頭。例如:
<bean id="studentbean" class="org.edureka.firstSpring.StudentBean"> <property name="name" value="Edureka"></property> </bean>
您能夠經過在相關的類,方法或字段聲明上使用註解,將 bean 配置爲組件類自己,而不是使用 XML 來描述 bean 裝配。默認狀況下,Spring 容器中未打開註解裝配。所以,您須要在使用它以前在 Spring 配置文件中啓用它。例如:
<beans> <context:annotation-config/> <!-- bean definitions go here --> </beans>
Spring 的 Java 配置是經過使用 @Bean 和 @Configuration 來實現。
@Bean 註解扮演與 元素相同的角色。
例如:
@Configuration public class StudentConfig { @Bean public StudentBean myStudent() { return new StudentBean(); } }
Spring bean 支持 5 種 scope:
Singleton - 每一個 Spring IoC 容器僅有一個單實例。
Prototype - 每次請求都會產生一個新的實例。
Request - 每一次 HTTP 請求都會產生一個新的實例,而且該 bean 僅在當前 HTTP 請求內有效。
Session - 每一次 HTTP 請求都會產生一個新的 bean,同時該 bean 僅在當前 HTTP session 內有效。
僅當用戶使用支持 Web 的 ApplicationContext 時,最後三個纔可用。更多spring內容
spring bean 容器的生命週期流程以下:
Spring 容器根據配置中的 bean 定義中實例化 bean
Spring 使用依賴注入填充全部屬性,如 bean 中所定義的配置。
若是 bean 實現 BeanNameAware 接口,則工廠經過傳遞 bean 的 ID 來調用 setBeanName()。
若是 bean 實現 BeanFactoryAware 接口,工廠經過傳遞自身的實例來調用 setBeanFactory()。
若是存在與 bean 關聯的任何 BeanPostProcessors,則調用 preProcessBeforeInitialization() 方法。
若是爲 bean 指定了 init 方法( 的 init-method 屬性),那麼將調用它。
最後,若是存在與 bean 關聯的任何 BeanPostProcessors,則將調用 postProcessAfterInitialization() 方法。
若是 bean 實現 DisposableBean 接口,當 spring 容器關閉時,會調用 destory()。
只有將 bean 用做另外一個 bean 的屬性時,才能將 bean 聲明爲內部 bean。爲了定義 bean,Spring 的基於 XML 的配置元數據在 <property> 或 <constructor-arg> 中提供了 <bean> 元素的使用。內部 bean 老是匿名的,它們老是做爲原型。
例如,假設咱們有一個 Student 類,其中引用了 Person 類。這裏咱們將只建立一個 Person 類實例並在 Student 中使用它。
Student.java
public class Student { private Person person; //Setters and Getters } public class Person { private String name; private String address; //Setters and Getters }
bean.xml
<bean id=「StudentBean" class="com.edureka.Student"> <property name="person"> <!--This is inner bean --> <bean class="com.edureka.Person"> <property name="name" value=「Scott"></property> <property name="address" value=「Bangalore"></property> </bean> </property> </bean>
當 bean 在 Spring 容器中組合在一塊兒時,它被稱爲裝配或 bean 裝配。Spring 容器須要知道須要什麼 bean 以及容器應該如何使用依賴注入來將 bean 綁定在一塊兒,同時裝配 bean。
Spring 容器可以自動裝配 bean。也就是說,能夠經過檢查 BeanFactory 的內容讓 Spring 自動解析 bean 的協做者。
自動裝配的不一樣模式:
no - 這是默認設置,表示沒有自動裝配。應使用顯式 bean 引用進行裝配。
byName - 它根據 bean 的名稱注入對象依賴項。它匹配並裝配其屬性與 XML 文件中由相同名稱定義的 bean。
byType - 它根據類型注入對象依賴項。若是屬性的類型與 XML 文件中的一個 bean 名稱匹配,則匹配並裝配屬性。
構造函數 - 它經過調用類的構造函數來注入依賴項。它有大量的參數。
覆蓋的可能性 - 您始終可使用 和 設置指定依賴項,這將覆蓋自動裝配。
基本元數據類型 - 簡單屬性(如原數據類型,字符串和類)沒法自動裝配。
@Controller - 用於 Spring MVC 項目中的控制器類。
@Service - 用於服務類。
@RequestMapping - 用於在控制器處理程序方法中配置 URI 映射。
@ResponseBody - 用於發送 Object 做爲響應,一般用於發送 XML 或 JSON 數據做爲響應。
@PathVariable - 用於將動態值從 URI 映射處處理程序方法參數。
@Autowired - 用於在 spring bean 中自動裝配依賴項。
@Qualifier - 使用 @Autowired 註解,以免在存在多個 bean 類型實例時出現混淆。
@Scope - 用於配置 spring bean 的範圍。
@Configuration,@ComponentScan 和 @Bean - 用於基於 java 的配置。
默認狀況下,Spring 容器中未打開註解裝配。所以,要使用基於註解裝配,咱們必須經過配置<context:annotation-config /> 元素在 Spring 配置文件中啓用它。
@Component:這將 java 類標記爲 bean。它是任何 Spring 管理組件的通用構造型。spring 的組件掃描機制如今能夠將其拾取並將其拉入應用程序環境中。
@Controller:這將一個類標記爲 Spring Web MVC 控制器。標有它的 Bean 會自動導入到 IoC 容器中。
@Service:此註解是組件註解的特化。它不會對 @Component 註解提供任何其餘行爲。您能夠在服務層類中使用 @Service 而不是 @Component,由於它以更好的方式指定了意圖。
@Required 應用於 bean 屬性 setter 方法。此註解僅指示必須在配置時使用 bean 定義中的顯式屬性值或使用自動裝配填充受影響的 bean 屬性。若是還沒有填充受影響的 bean 屬性,則容器將拋出 BeanInitializationException。
示例:
public class Employee { private String name; @Required public void setName(String name){ this.name=name; } public string getName(){ return name; } }
4.5. @Autowired 註解有什麼用?
@Autowired 能夠更準確地控制應該在何處以及如何進行自動裝配。此註解用於在 setter 方法,構造函數,具備任意名稱或多個參數的屬性或方法上自動裝配 bean。默認狀況下,它是類型驅動的注入。
public class Employee { private String name; @Autowired public void setName(String name) { this.name=name; } public string getName(){ return name; } }
當您建立多個相同類型的 bean 並但願僅使用屬性裝配其中一個 bean 時,您可使用@Qualifier 註解和 @Autowired 經過指定應該裝配哪一個確切的 bean 來消除歧義。
例如,這裏咱們分別有兩個類,Employee 和 EmpAccount。在 EmpAccount 中,使用@Qualifier 指定了必須裝配 id 爲 emp1 的 bean。
public class Employee { private String name; @Autowired public void setName(String name) { this.name=name; } public string getName() { return name; } }
EmpAccount.java
public class EmpAccount { private Employee emp; @Autowired @Qualifier(emp1) public void showName() { System.out.println(「Employee name : 」+emp.getName); } }
@RequestMapping 註解用於將特定 HTTP 請求方法映射到將處理相應請求的控制器中的特定類/方法。此註解可應用於兩個級別:
類級別:映射請求的 URL
Spring DAO 使得 JDBC,Hibernate 或 JDO 這樣的數據訪問技術更容易以一種統一的方式工做。這使得用戶容易在持久性技術之間切換。它還容許您在編寫代碼時,無需考慮捕獲每種技術不一樣的異常。
JdbcTemplate
SimpleJdbcTemplate
NamedParameterJdbcTemplate
SimpleJdbcInsert
咱們能夠經過兩種方式使用 Spring 訪問 Hibernate:
使用 Hibernate 模板和回調進行控制反轉
Spring 支持兩種類型的事務管理:
程序化事務管理:在此過程當中,在編程的幫助下管理事務。它爲您提供極大的靈活性,但維護起來很是困難。
Hibernate
iBatis
JPA
JDO
AOP(Aspect-Oriented Programming), 即 面向切面編程, 它與 OOP( Object-Oriented Programming, 面向對象編程) 相輔相成, 提供了與 OOP 不一樣的抽象軟件結構的視角.
在 OOP 中, 咱們以類(class)做爲咱們的基本單元, 而 AOP 中的基本單元是 Aspect(切面)
Aspect - Aspect 是一個實現交叉問題的類,例如事務管理。方面能夠是配置的普通類,而後在 Spring Bean 配置文件中配置,或者咱們可使用 Spring AspectJ 支持使用 @Aspect 註解將類聲明爲 Aspect。
Advice - Advice 是針對特定 JoinPoint 採起的操做。在編程方面,它們是在應用程序中達到具備匹配切入點的特定 JoinPoint 時執行的方法。您能夠將 Advice 視爲 Spring 攔截器(Interceptor)或 Servlet 過濾器(filter)。
Advice Arguments - 咱們能夠在 advice 方法中傳遞參數。咱們能夠在切入點中使用 args() 表達式來應用於與參數模式匹配的任何方法。若是咱們使用它,那麼咱們須要在肯定參數類型的 advice 方法中使用相同的名稱。
Pointcut - Pointcut 是與 JoinPoint 匹配的正則表達式,用於肯定是否須要執行 Advice。Pointcut 使用與 JoinPoint 匹配的不一樣類型的表達式。Spring 框架使用 AspectJ Pointcut 表達式語言來肯定將應用通知方法的 JoinPoint。
特定 JoinPoint 處的 Aspect 所採起的動做稱爲 Advice。Spring AOP 使用一個 Advice 做爲攔截器,在 JoinPoint 「周圍」維護一系列的攔截器。
Before - 這些類型的 Advice 在 joinpoint 方法以前執行,並使用 @Before 註解標記進行配置。
After Returning - 這些類型的 Advice 在鏈接點方法正常執行後執行,並使用@AfterReturning 註解標記進行配置。
After Throwing - 這些類型的 Advice 僅在 joinpoint 方法經過拋出異常退出並使用 @AfterThrowing 註解標記配置時執行。
After (finally) - 這些類型的 Advice 在鏈接點方法以後執行,不管方法退出是正常仍是異常返回,並使用 @After 註解標記進行配置。
concern 是咱們想要在應用程序的特定模塊中定義的行爲。它能夠定義爲咱們想要實現的功能。
cross-cutting concern 是一個適用於整個應用的行爲,這會影響整個應用程序。例如,日誌記錄,安全性和數據傳輸是應用程序幾乎每一個模塊都須要關注的問題,所以它們是跨領域的問題。
實現 AOP 的技術,主要分爲兩大類:
靜態代理 - 指使用 AOP 框架提供的命令進行編譯,從而在編譯階段就可生成 AOP 代理類,所以也稱爲編譯時加強;
編譯時編織(特殊編譯器實現)
類加載時編織(特殊的類加載器實現)。
動態代理 - 在運行時在內存中「臨時」生成 AOP 動態代理類,所以也被稱爲運行時加強。
JDK 動態代理
Spring AOP 基於動態代理方式實現;AspectJ 基於靜態代理方式實現。
Spring AOP 僅支持方法級別的 PointCut;提供了徹底的 AOP 支持,它還支持屬性級別的 PointCut。
將 Advice 應用於目標對象後建立的對象稱爲代理。在客戶端對象的狀況下,目標對象和代理對象是相同的。
Advice + Target Object = Proxy
爲了建立一個 advice 對象而連接一個 aspect 和其它應用類型或對象,稱爲編織(Weaving)。在 Spring AOP 中,編織在運行時執行。請參考下圖:
Spring Web MVC 框架提供 模型-視圖-控制器 架構和隨時可用的組件,用於開發靈活且鬆散耦合的 Web 應用程序。MVC 模式有助於分離應用程序的不一樣方面,如輸入邏輯,業務邏輯和 UI 邏輯,同時在全部這些元素之間提供鬆散耦合。
DispatcherServlet 的工做流程能夠用一幅圖來講明:
向服務器發送 HTTP 請求,請求被前端控制器 DispatcherServlet 捕獲。
DispatcherServlet 根據 -servlet.xml 中的配置對請求的 URL 進行解析,獲得請求資源標識符(URI)。而後根據該 URI,調用 HandlerMapping 得到該 Handler 配置的全部相關的對象(包括 Handler 對象以及 Handler 對象對應的攔截器),最後以HandlerExecutionChain 對象的形式返回。
DispatcherServlet 根據得到的Handler,選擇一個合適的 HandlerAdapter。(附註:若是成功得到HandlerAdapter後,此時將開始執行攔截器的 preHandler(…)方法)。
HttpMessageConveter:將請求消息(如 Json、xml 等數據)轉換成一個對象,將對象轉換爲指定的響應信息。
數據轉換:對請求消息進行數據轉換。如String
轉換成Integer
、Double
等。
數據根式化:對請求消息進行數據格式化。如將字符串轉換成格式化數字或格式化日期等。
BindingResult
或Error
中。5.Handler(Controller)執行完成後,向 DispatcherServlet 返回一個 ModelAndView 對象;
6.根據返回的ModelAndView,選擇一個適合的 ViewResolver(必須是已經註冊到 Spring 容器中的ViewResolver)返回給DispatcherServlet。
7.ViewResolver 結合Model和View,來渲染視圖。
8.視圖負責將渲染結果返回給客戶端。
WebApplicationContext 是 ApplicationContext 的擴展。它具備 Web 應用程序所需的一些額外功能。它與普通的 ApplicationContext 在解析主題和決定與哪一個 servlet 關聯的能力方面有所不一樣。