用戶發(fā)送請求至前端控制器DispatcherServlet;
DispatcherServlet收到請求調用HandlerMapping處理器映射器;
處理器映射器根據(jù)請求URL找到具體的處理器,生成處理器對象及處理器攔截器(如果有則生成)一并返回給DispatcherServlet;
DispatcherServlet通過HandlerAdapter處理器適配器調用處理器;
執(zhí)行處理器(Controller,也叫后端控制器);
Controller執(zhí)行完成返回ModelAndView;
HandlerAdapter將Controller執(zhí)行結果ModelAndView返回給DispatcherServlet;
DispatcherServlet將ModelAndView傳給ViewReslover視圖解析器;
ViewReslover解析后返回具體View;
DispatcherServlet對View進行渲染視圖(即將模型數(shù)據(jù)填充至視圖中);
DispatcherServlet響應用戶。
Bean Factory負責讀取bean配置文檔,管理bean的加載,實例化,維護bean之間的依賴關系,負責bean的生命周期;
ApplicationContext除了提供上述Bean Factory所能提供的功能之外,還提供了更完整的框架功能。
根據(jù)注入依賴對象的類型分類:
基本類型對象的注入;
注入其他Bean。
注入依賴對象的方式:
構造器注入;
屬性Setter方法注入;
工廠注入(不常用)。
注入依賴對象的編程方式:
手動裝配
XML方式;
注解方式。
自動裝配
Filter基于Filter接口中的doFilter回調函數(shù),Interceptor則基于Java本身的反射機制;
Filter是依賴于Servlet的,沒有Servlet就無法回調doFilter方法,而Interceptor與Servlet無關;
Filter的過濾范圍比Interceptor大,F(xiàn)ilter除了過濾請求外通過通配符可以保護頁面、圖片、文件等,而Interceptor只能過濾Handler;
Filter是在請求進入Tomcat等容器后,Servlet處理之前進行調用的;Interceptor是在請求進入Servlet后,執(zhí)行Handler之前進行調用的;
Filter是隨著Tomcat等Web容器啟動時而進行初始化;Interceptor時隨著Spring啟動而進行初始化。
實現(xiàn)AOP的技術,主要分為兩大類:
靜態(tài)代理:指使用AOP框架提供的命令進行編譯,從而在編譯階段就可生成AOP代理類,因此也稱為編譯時增強;
編譯時編織(特殊編譯器實現(xiàn));
類加載時編織(特殊的類加載器實現(xiàn))。
動態(tài)代理- 在運行時在內存中“臨時”生成AOP動態(tài)代理類,因此也被稱為運行時增強。
JDK動態(tài)代理、CGLIB。
簡化開發(fā)、解耦、集成其它框架;
低侵入式設計,代碼污染級別低;
Spring的IOC機制降低了業(yè)務對象替換的復雜性,提高了軟件之間的解耦性;
Spring AOP支持將一些通用的任務進行集中式的管理,例如:安全、事務、日志等,從而使代碼能更好的復用。
當通過Spring 容器創(chuàng)建一個Bean實例的時候,不僅可以完成Bean實例的實例化,還可以為Bean指定作用域。Spring Bean元素的支持以下5 種作用域:
Singleton:單例模式,在整個Spring IOC容器中,使用Singleton定義的Bean將只有一個實例。
Prototype:多例模式,每次通過容器中的getBean方法獲取prototype定義的Beans時,都會產生一個新的Bean的實例。
Request:對于每次Http請求,使用Request定義的Bean都會產生一個新的實例,只有在Web應用時候,該作用域才會有效。
Session:對于每次Http Session,使用Session定義的Bean都將產生一個新的實例。
Globalsession:每個全局的Http Sesisonn,使用Session定義的Bean都將產生一個新的實例。
Set集合的注入:
<bean id="testBean" class="com.spring.domain.TestBean">
<property name="sets">
<set>
<value>set1</value>
<value>set2</value>
</set>
</property>
</bean>
?List集合的注入:
<bean id="testBean" class="com.spring.domain.TestBean">
<property name="lists">
<list>
<value>list1</value>
<value>list2</value>
</list>
</property>
</bean>
?Map集合的注入:
<bean id="testBean" class="com.spring.domain.TestBean">
<property name="maps">
<map>
<entry key="map1" value="map1"/>
<entry key="map2" value="map2"/>
</map>
</property>
</bean>
?Properties集合的注入:
<bean id="testBean" class="com.spring.domain.TestBean">
<property name="props">
<props>
<prop key="prop1">prop1</prop>
<prop key="prop2">prop2</prop>
</props>
</property>
</bean>
它們是構成用戶應用程序主干的對象;
Bean由Spring IoC容器管理;
它們由Spring IoC容器實例化,配置,裝配和管理;
Bean是基于用戶提供給容器的元數(shù)據(jù)創(chuàng)建。
就是將一個Bean 注入到其它的Bean的Property中,默認情況下,容器不會自動裝配,需要我們手動設定。
Spring可以通過向Bean Factory中注入的方式來搞定Bean之間的依賴關系,達到自動裝配的目的。
自動裝配建議少用,如果要使用建議使用ByName。
示例代碼:<bean id="…" class="…" autowire="…">,autowire屬性的取值如下:
byType:按類型裝配,可以根據(jù)屬性的類型,在容器中尋找跟該類型匹配的bean,如果發(fā)現(xiàn)多個,那么將會拋出異常。如果沒有找到,即屬性值為null;
byName:按名稱裝配,可以根據(jù)屬性的名稱,在容器中尋找跟該屬性名稱相同的bean,如果沒有找到,即屬性值為null;
constructor:與buType類似,不同之處在于它應用與構造器注入,如果在容器中沒有找到與構造器參數(shù)類型一致的bean,那么會拋出異常;
no:不自動裝配。
default:默認值,同no配置。
覆蓋的可能性:您始終可以使用<constructor-arg>和<property>設置指定依賴項,這將覆蓋自動裝配;
基本元數(shù)據(jù)類型:簡單屬性(如原數(shù)據(jù)類型,字符串和類)無法自動裝配;
令人困惑的性質:總是喜歡使用明確的裝配,因為自動裝配不太精確。
@Controller:用于Spring MVC 項目中的控制器類。
@Service:用于服務類。
@RequestMapping:用于在控制器處理程序方法中配置URI 映射。
@ResponseBody:用于發(fā)送Object 作為響應,通常用于發(fā)送XML 或JSON 數(shù)據(jù)作為響應。
@RequestBody:用于接收JSON 格式數(shù)據(jù)參數(shù)。
@PathVariable:用于將動態(tài)值從URI 映射到處理程序方法參數(shù)。
@Autowired:用于在Spring Bean中自動裝配依賴項。
@Qualifier:使用@Autowired 注解,以避免在存在多個bean 類型實例時出現(xiàn)混淆。
@Scope:用于配置spring bean 的范圍。
@Configuration、@ComponentScan和@Bean:用于基于Java的配置。
@Aspect、@Before、@After、@AfterTrowing、@AfterReturning、@Around、@Pointcut:用于切面編程。
@Controller:寫在控制器上作用和@component一樣。
@RequestMapping:用于處理請求URL映射的注解,可用于類或方法上。用于類上,則表示類中的所有響應請求的方法都是以該地址作為父路徑。
@RequestBody:注解實現(xiàn)接收http請求的Json數(shù)據(jù),將Json轉換為Java對象。
@ResponseBody:注解實現(xiàn)將conreoller方法返回對象轉化為Json對象響應給客戶。
@RestController:相當于@Controller+@ResponseBody
@PathVariable:用于將動態(tài)值從URL映射到處理程序方法參數(shù)。
@RequestParam:用于設置Hanlder的參數(shù)映射。
@Autowired與@Resource都可以用來裝配Bean,都可以寫在字段上,或寫在setter方法上;
@Autowired默認按類型注入,按名稱注入需要與@Qualifier("對象名")連用;
@Resource同時支持按類型和按名稱注入,默認按名稱注入,如果找不到就按類型注入;
@Autowired是Spring提供的注解,@Resource是Java EE提供的。
@Component:這將Java類標記為bean,它是任何Spring管理組件的通用構造型,Spring的組件掃描機制現(xiàn)在可以將其拾取并將其拉入應用程序環(huán)境中。
@Controller:這將一個類標記為Spring Web MVC 控制器。標有它的Bean會自動導入到IOC容器中。
@Service:此注解是組件注解的特化,它不會對@Component注解提供任何其他行為,您可以在服務層類中使用@Service而不是@Component,因為它以更好的方式指定了意圖。
@Repository:這個注解是具有類似用途和功能的@Component注解的特化,它為DAO提供了額外的好處,它將DAO導入IOC容器,并使未經檢查的異常有資格轉換為SpringDataAccessException。
Spring 支持兩種類型的事務管理:
程序化事務管理:在此過程中,在編程的幫助下管理事務。它為您提供極大的靈活性,但維護起來非常困難。
聲明式事務管理:在此,事務管理與業(yè)務代碼分離。僅使用注解或基于XML的配置來管理事務。
它為不同的事務API(如JTA、JDBC、Hibernate、JPA和JDO)提供了統(tǒng)一的編程模型。
它為編程式事務管理提供了一個簡單的API而非一系列復雜的事務API(如JTA)。
它支持聲明式事務管理。
它可以和Spring的多種數(shù)據(jù)訪問技術很好的融合。
AOP面向切面編程,它是一種思想。它就是針對業(yè)務處理過程中的切面進行提取,以達到優(yōu)化代碼的目的,減少重復代碼的目的。就比如,在編寫業(yè)務邏輯代碼的時候,我們習慣性的都要寫:日志記錄,事務控制,以及權限控制等,每一個子模塊都要寫這些代碼,代碼明顯存在重復。這時候,我們運用面向切面的編程思想,采用橫切技術,將代碼中重復的部分,不影響主業(yè)務邏輯的部分抽取出來,放在某個地方進行集中式的管理,調用。形成日志切面,事務控制切面,權限控制切面。這樣,我們就只需要關心業(yè)務的邏輯處理,即提高了工作的效率,又使得代碼變的簡潔優(yōu)雅。這就是面向切面的編程思想,它是面向對象編程思想的一種擴展。
AOP的使用場景: 緩存、權限管理、內容傳遞、錯誤處理、懶加載、記錄跟蹤、優(yōu)化、校準、調試、持久化、資源池、同步管理、事務控制等。
AOP的相關概念: 切面(Aspect)、連接點(JoinPoint) 、通知(Advice) 、切入點(Pointcut) 代理(Proxy): 織入(Weaving)。
Spring AOP的編程原理? 代理機制JDK的動態(tài)代理:只能用于實現(xiàn)了接口的類產生代理。Cglib代理:針對沒有實現(xiàn)接口的類產生代理,應用的是底層的字節(jié)碼增強技術,生成當前類的子類對象。
Spring Web MVC框架提供模型-視圖-控制器架構和隨時可用的組件,用于開發(fā)靈活且松散耦合的Web 應用程序。MVC模式有助于分離應用程序的不同方面,如輸入邏輯,業(yè)務邏輯和UI邏輯,同時在所有這些元素之間提供松散耦合。
IOC:就是對象之間的依賴關系由容器來創(chuàng)建,對象之間的關系本來是由我們開發(fā)者自己創(chuàng)建和維護的,在我們使用Spring框架后,對象之間的關系由容器來創(chuàng)建和維護,將開發(fā)者做的事讓容器做,這就是控制反轉。BeanFactory接口是Spring IOC容器的核心接口。
DI:我們在使用Spring容器的時候,容器通過調用set方法或者是構造器來建立對象之間的依賴關系??刂品崔D是目標,依賴注入是我們實現(xiàn)控制反轉的一種手段。
內部最核心的就是IOC,之前是使用new關鍵字創(chuàng)建對象,現(xiàn)在可以直接從容器中獲取,動態(tài)注入,這其實就是利用Java里的反射。反射其實就是在運行時動態(tài)的去創(chuàng)建、調用對象,Spring就是在運行時,根據(jù)Spring核心配置文件(XML)來動態(tài)的創(chuàng)建對象,和調用對象里的方法。
Spring另一個核心就是AOP面向切面編程,可以為某一類對象進行監(jiān)督和控制(也就是在調用這類對象的具體方法的前后去調用你指定的模塊)從而達到對一個模塊擴充的功能。這些都是通過配置類達到的。
Spring目的:就是讓對象與對象(模塊與模塊)之間的關系沒有通過代碼來關聯(lián),都是通過配置類說明管理的(Spring根據(jù)這些配置內部通過反射去動態(tài)的組裝對象);要記住,Spring是一個容器,凡是在容器里的對象才會有Spring所提供的這些服務和功能。
Spring里用的最經典設計模式:模板方法模式;核心容器組件是BeanFactory,它是工廠模式的實現(xiàn)。BeanFactory使用控制反轉(IOC)模式將應用程序的配置和依賴性規(guī)范與實際的應用程序代碼分開。
REQUIRED:業(yè)務方法需要在一個事務中運行。如果方法運行時,已經處在一個事務中,那么加入到該事務,否則為自己創(chuàng)建一個新的事務。
NOT_SUPPORTED:聲明方法不需要事務。如果方法沒有關聯(lián)到一個事務,容器不會為它開啟事務,如果方法在一個事務中被調用,該事務會被掛起,在方法調用結束后,原先的事務便會恢復執(zhí)行。
REQUEIRESNEW:不管是否存在事務,業(yè)務方法總會為自己發(fā)起一個新的事務。如果方法已經運行在一個事務中,則原有的事務會被掛起,新的事務會被創(chuàng)建,直到方法執(zhí)行結束,新的事務才算結束,原先的事務才會被恢復執(zhí)行。
NANDATORY:業(yè)務方法只能在一個已經存在的事務中執(zhí)行,業(yè)務方法不能自己發(fā)起事務,如果業(yè)務方法沒有在事務環(huán)境下被調用,容器會拋出例外。
SUPPORTS:如果業(yè)務方法在某個事務范圍中被調用,則方法稱為該事務的一部分,如果業(yè)務方法在事務范圍外被調用,則方法在沒有事務環(huán)境下執(zhí)行。
Never:業(yè)務方法絕對不會在事務范圍內執(zhí)行,如果業(yè)務方法在某一個事務中執(zhí)行,容器會拋出例外,只有業(yè)務方法沒有關聯(lián)到任何事務,才能正常執(zhí)行。
NESTED:如果一個活動的事務存在,則運行在一個嵌套事務中,如果沒有活動事務,則按REQUIRED屬性執(zhí)行,它使用了一個單獨的事務,這個事務擁有多個可回滾的保存點。內部事務的回滾不會影響到外部事務。它只對DataSourceTransactionManager事務管理器生效。
轉發(fā):在返回值前面加“forward:”前綴,比如:forward:/user?name=1。
重定向:在返回值前面加“redirect:”前綴,比如:redirect:/user。
Spring MVC屬于SpringFrameWork的后續(xù)產品,已經融合在Spring Web Flow里面,是一個強大靈活的Web框架。
Spring MVC提供了一個DispatcherServlet作為前端控制器來分配請求。通過策略接口,Spring框架是高度可配置的。
Spring MVC通過一套注解,讓JavaBean成為處理請求的控制器,而無需實現(xiàn)任何接口。
Spring MVC還包含多種視圖技術,如 Java Server Pages(JSP)、Velocity、Tiles、iText和POI等。
Spring MVC支持Rest風格的URL請求。
Spring MVC分離了控制器、模型對象、分派器以及處理程序對象的角色,這種分離讓它們更容易進行定制。
Spring MVC框架主要由DispatcherServlet、處理器映射器、處理器適配器、處理器、視圖解析器、視圖組成。
前端控制器(DispatcherServlet)作用:接收請求、響應結果,相當于轉發(fā)器,有了DispatcherServlet就減少了其它組件之間的耦合度。
處理器映射器(HandlerMapping)作用:根據(jù)請求的URL來查找Handler(控制器)。
處理器適配器(HandlerAdapter)作用:在編寫Handler的時候要按照HandlerAdapter要求的規(guī)則去編寫,這樣適配器才可以正確的去執(zhí)行Handler。
處理器(Handler)作用:處理請求、調用業(yè)務代碼、返回ModelAndView對象。
視圖解析器(ViewResolver)作用:進行視圖的解析,根據(jù)視圖邏輯名解析成真正的視圖(view)。
視圖(View)作用:View是一個接口,它的實現(xiàn)類支持不同的視圖類型(JSP、Freemarke等)。
直接在形參里面聲明參數(shù),必須名字和傳過來的參數(shù)一樣。
使用@RequestParam注解的方式獲取,注意設置的別名需要與表單元素的名稱一致。
使用POJO對象綁定請求參數(shù)值,注意對象中屬性與表單元素的名稱一致。
使用@PathVariable注解與URL路徑中“{占位符}”進行綁定。
使用Servlet原生API進行獲取QueryString中指定名稱的參數(shù)。
使用Controller中方法聲明形式參數(shù):
@Controller 使用Controller中的成員屬性依賴注入: |
修改web.xml,配置Spring主控Servlet:
<!-- 配置SpringMVC的前端控制器(即:主控Servlet) -->
<servlet>
<servlet-name>spring-mvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 配置SpringMVC的地址映射,“/”代表所有請求都由DispatcherServlet來處理 -->
<servlet-mapping>
<servlet-name>spring-mvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
?編寫Spring_mvc配置文件:
<!--
注意:本配置文件名稱必須與web.xml中配置的servlet名稱一致
另外必須放在WEB-INF文件夾下
-->
<!—
掃描包,將標注Spring注解的類自動轉化為Bean,同時完成Bean的注入
-->
<context:component-scan base-package="org.spring.controller"/>
<!—
配置視圖解析器:如何把handler方法返回值解析成實際物理視圖
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 添加Springmvc對注解的支持 -->
<mvc:annotation-driven/>
value:指定請求的實際地址,指定的地址可以是URI Template模式;
method:指定請求的method類型(GET、POST、PUT、DELETE等);
consumes:指定處理請求的提交內容類型(Content-Type),例如application/json、 text/html;
produces: 指定返回的內容類型,僅當request請求頭中的Accept類型中包含該指定類型才返回;
params:指定request中必須包含某些參數(shù)值是,才讓該方法處理;
headers:指定request中必須包含某些指定的header值,才能讓該方法處理請求。
切入時機即AOP中的五種通知(或增強):
前置通知、后置通知、環(huán)繞通知、例外通知、最終通知。
Aop切點格式示例:execution(* com.service.impl..*.*(..))
第一個*:代表匹配任意返回值類型;
第一個..:代表匹配指定包下及子包);
第二個*:代表匹配包中的任意類;
第三個*:代表匹配類中的任意方法;
最后一個..:代表匹配方法的任意參數(shù)。
MVC(Model-View-Controller)模式,即模型-視圖-控制器模式,其核心思想是將整個程序代碼分成相對獨立而又能協(xié)同工作的3個組成部分,具體的功能如下:
模型(Model):業(yè)務層,實現(xiàn)具體的業(yè)務邏輯、狀態(tài)管理的功能。
視圖(View):表示層,就是與用戶實現(xiàn)交互的頁面,通常實現(xiàn)數(shù)據(jù)的輸入和輸出功能。
控制器(Controller):控制層,處理請求并作出響應作用,實現(xiàn)View層跟Model層的協(xié)同工作。
Spring MVC框架主要處理用戶請求和響應處理后的結果,如:提供處理用戶提交的數(shù)據(jù)和數(shù)據(jù)類型轉換以及在視圖中顯示用戶數(shù)據(jù);
Spring框架主要提供依賴注入,是各層的對象之間關聯(lián)關系的解耦,提供切面編程思想的實現(xiàn)AOP,并且提供更強大的事務支持。
Mybatis框架提供對象的持久化操作,簡化持久層編碼,實現(xiàn)SQL與Java代碼的分離,便于SQL優(yōu)化。
Spring容器根據(jù)配置中的Bean定義實例化Bean。
Spring使用依賴注入填充所有屬性,如Bean中所定義的配置。
如果為Bean指定了init方法(<bean>的init-method屬性),那么將調用它。
如果Bean實現(xiàn)DisposableBean接口,當Spring容器關閉時,會調用destory()方法。
如果為Bean指定了destroy()方法(<bean>的destroy-method屬性),那么將調用它。
工廠設計模式:Spring使用工廠模式通過 BeanFactory、ApplicationContext 創(chuàng)建Bean對象。
代理設計模式:Spring AOP功能的實現(xiàn)。
單例設計模式:Spring中的Bean默認都是單例的。
模板方法模式:Spring中 jdbcTemplate、hibernateTemplate 等以Template結尾的對數(shù)據(jù)庫操作的類,它們就使用到了模板方法模式。
包裝器設計模式:我們的項目需要連接多個數(shù)據(jù)庫,而且不同的客戶在每次訪問中根據(jù)需要會去訪問不同的數(shù)據(jù)庫。這種模式讓我們可以根據(jù)客戶的需求能夠動態(tài)切換不同的數(shù)據(jù)源。
觀察者模式:Spring事件驅動模型就是觀察者模式很經典的一個應用。
適配器模式:Spring AOP的增強或通知(Advice)使用到了適配器模式、Spring MVC中也是用到了適配器模式適配Controller。
ModelAndView:最常見的返回值類型,可以在ModelAndView對象中指定視圖名稱,綁定數(shù)據(jù)。
void:返回值為void時,可能是真的沒有值要返回,也可能是有其他辦法返回數(shù)據(jù),有如下二種情況:
沒有值:確實沒有返回值,使用request與response對象實現(xiàn)請求轉發(fā)與重定向。
返回字符串:利用response.getWriter()方法向響應中打印字符串數(shù)據(jù)。
String:當方法的返回值為 String類型時,也有幾種不同情況:
邏輯視圖名:返回String最常見的是邏輯視圖名。
重定向:使用“redirect:”前綴實現(xiàn)重定向。
轉發(fā):使用“forward:”前綴實現(xiàn)轉發(fā)。
真的是String:方法上加上@ResponseBody注解即可,或者Controller上本身添加的是組合注解 @RestController。
JSON:返回JSON是常見的方式,常見的List集合、Map集合、實體類等都可以返回。