Spring框架必知,滿滿干貨!

1、認識Spring框架 1.1 Spring框架定義 定義:Spring是 輕量級的開源框架 。以 IOC(控制反轉)和AOP(面向切面編程)為內核 ,使用 最基本的JavaBean 完成工作。 1.2 Spring框架的優點 控制反轉(IOC)和

1、認識Spring框架


1.1 Spring框架定義

  • 定義:Spring是輕量級的開源框架。以IOC(控制反轉)和AOP(面向切面編程)為內核,使用最基本的JavaBean完成工作。

1.2 Spring框架的優點

  1. 控制反轉(IOC)和依賴注入(DI)實現松耦合,簡化開發。
  2. 支持AOP(面向切面編程),并且把應用業務與系統服務分開。
  3. 支持聲明式事務處理。通過配置就可以完成對事務的處理,提高開發效率。
  4. 方便程序的測試。Spring支持JUnit4的支持,添加注解便可以測試Spring。
  5. 方便集成各種優秀框架。內部提供了對一些框架的直接支持。
  6. 降低了Java EE API的使用難度。對JDBC、Mail等模塊進行了封裝

1.3 Spring框架體系結構和模塊組成

  1. 體系結構:分層架構
  2. 主要模塊
  1. Core Container(核心容器層):是其他模塊建立的基礎,主要模塊組成:
  1. Beans模塊提供了BeanFactory(工廠模式),Spring將管理對象稱為Bean。
  2. Core模塊:提供了Spring框架的基本組成部分,包括IOC(控制反轉)和DI(依賴注入)功能。
  3. Context模塊:建立在Beans和Core基礎之上,訪問定義和配置的任何對象的媒介。ApplicationContext接口是Context模塊的焦點。
  4. Context-support模塊:提供了第三方庫嵌入Spring應用的集成支持。
  1. DataAccess/Integration(數據訪問/集成層)
  1. JDBC模塊:提供了JDBC的抽象層,大幅度地減少了在開發過程中對數據庫操作的編碼。
  2. ORM模塊:對流行的對象關系映射API,包括JPA、JDO、Hibernate提供了集成層面支持。
  3. OMX模塊:提供了一個支持對象/XML映射的抽象層實現,如JAXB、Castor、XStream等。
  4. JMS模塊:Java消息傳遞,使用和傳遞信息的特性。
  5. Transactions事務模塊:支持對實現特殊接口以及所有實體類的編程和注解式的事務管理
  1. Web層
  1. WebSocket模塊:提供了WebSocket和SockJS的實現。
  2. Servlet模塊:Spring-MVC模塊,包含了Spring模型-視圖-控制器(MVC)。
  1. 其他模塊
  1. AOP模塊:提供了面向切面編程的實現,允許定義方法攔截器和切入點,將代碼按照功能進行分離,降低耦合性。
  2. Aspects模塊:提供了AspectJ一個強大且成熟的AOP框架。
  3. Test模塊:提供了單元測試和集成測試的支持。
  1. 體系結構圖

Spring框架必知,滿滿干貨!_AOP

1.4 Spring框架的兩種核心容器

  1. BeanFactory:基礎類型的IOC容器,提供了完整的IOC服務支持。BeanFactory就是一個管理Bean的工廠,它主要負責初始化各種Bean,并調用它們的生命周期方法。
  2. ApplicationContext:它是BeanFactory的子接口,除了提供BeanFactory的所有功能外,還添加了對國際化、資源訪問、事件傳播等方面的支持。
  3. 創建ApplicationContext的三種方式:
  1. ClassPathXmlApplicationContext(從類路徑中讀取配置文件)創建:
  1. ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml")
  1. FileSystemXmlApplicationContext(參數指定的配置文件位置)創建:
  1. ApplicationContext applicationContext = new FileSystemXmlApplicationContext("applicationContext.xml")
  1. Web服務器實例化ApplicationContext,基于ContextLoaderListener實現。

1.5 獲取Spring中的Bean

  1. Object getBean(String name):根據Bean的id或者name來獲取指定的Bean,需要強轉。
  2. <T> T getBean(Class<T> requiredType):根據類的類型來獲取Bean實例,有泛型不需要強轉。

1.6 BeanFactory和ApplicationContext的區別

  1. 功能上的區別。
  1. BeanFactory是Spring里面最底層的接口,包含了各種Bean的定義,讀取bean配置文檔,管理bean的加載、實例化,控制bean的生命周期,維護bean之間的依賴關系。
  2. ApplicationContext接口作為BeanFactory的派生,除了提供BeanFactory所具有的功能外,還提供了更完整的框架功能,如繼承MessageSource、支持國際化、統一的資源文件訪問方式、同時加載多個配置文件等功能。
  1. 加載方式的區別
  1. BeanFactory采用的是延遲加載的形式來注入Bean,即只有在使用到某個Bean時(調用getBean()),才對該Bean進行加載實例化。如果Bean的某一個屬性沒有注入,BeanFacotry加載后,直至第一次使用調用getBean方法才會拋出異常。
  2. ApplicationContext在容器啟動時,一次性創建了所有的Bean。在容器啟動時就可以檢查所依賴的屬性是否注入。
  1. 創建方式的區別
  1. BeanFactory通常以編程的方式被創建。
  2. ApplicationContext除了使用編程方式創建(new 實例),還能以聲明的方式創建,例如使用ContextLoader。
  1. 注冊方式的區別:BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用。
  1. BeanFactory需要手動注冊。
  2. ApplicationContext是自動注冊的

1.7 控制反轉(IOC)和依賴注入(DI)

  1. 控制反轉
  1. 概念:IOC也稱控制反轉,由Spring容器管理Bean的整個生命周期,通過反射實現對其他對象的控制,對象的實例不再由調用者來創建,而是由Spring容器來創建有效的降低類之間的耦合度
  2. IOC的好處
  1. 資源集中管理,實現資源的可配置和易管理。
  2. 降低了使用資源雙方的依賴程度,耦合度。
  1. 依賴注入
  1. 概念:DI也稱依賴注入,在Spring創建對象過程中,把對象依賴的屬性注入到對象中
  2. 主要的兩種方式:屬性setter方法注入構造器注入。


2、Spring中的Bean


2.1 Bean的三種實例化方式

  1. 構造器實例化:Spring容器通過Bean對應類中默認的無參構造器來實現實例化Bean。
  2. 靜態工廠方式實例化:配置factory-method屬性。
  3. 實例工廠方式實例化:配置factory-bean、factory-method屬性。

2.2 Bean的作用域

  1. singleton(單例)Spring容器中的默認作用域,該作用域表示使用singleton定義的Bean在Spring容器中將只有一個實例。無論有多少個Bean引用它,始終將指向同一個對象。
  2. prototype(原型)每次通過Spring容器獲取prototype定義的Bean時,容器都將創建一個新的Bean實例
  3. request:對不同的Http請求每次請求都會產生一個新的Bean,僅在當前Http request內有效。
  4. session:對不同的Http請求每次請求都會產生一個新的Bean,僅在當前Http session內有效。
  5. globalSession:在一個全局的Http Session中,容器會返回該Bean的同一個實例。僅在使用portlet上下文時有效。

2.3 Bean的生命周期

注意:Spring可以管理Singleton單例作用域的Bean完整的生命周期,對于Prototype多例作用域的Bean,Spring只負責創建,創建實例后,Bean的實例就交由客戶端代碼管理,Spring不再跟蹤其生命周期。生命周期圖示:

Spring框架必知,滿滿干貨!_AOP_02

  1. 調用bean的構造方法創建Bean。
  2. 通過反射調用setter方法進行屬性的依賴注入。
  3. 如果Bean實現了BeanNameAware接口,Spring將調用setBeanName(),設置Bean的name(xml文件中bean標簽的id)。
  4. 如果Bean實現了BeanFactoryAware接口,Spring將調用setBeanFactory() 把beanfactory設置給Bean。
  5. 如果存在BeanPostProcessor ,Spring將調用它們的postProcessBeforeInitialization (預初始化)方法,在Bean初始化前對其進行處理。
  6. 如果Bean實現了InitializingBean接口,Spring將調用它的afterPropertiesSet方法,然后調用xml定義的 init-method方法,兩個方法作用類似,都是在初始化bean的時候執行。
  7. 如果存在BeanPostProcessor ,Spring將調用它們的postProcessAfterInitialization (后初始化)方法,在Bean初始化后對其進行處理。
  8. Bean初始化完成,供應用使用,這里分兩種情況:
  1. 如果Bean為單例的話,那么容器會返回Bean給用戶,并存入緩存池。如果Bean實現了DisposableBean接口,Spring將調用它的destory方法,然后調用在xml中定義的destory-method方法,這兩個方法作用類似,都是在Bean實例銷毀前執行。
  2. 如果Bean是多例的話,容器將Bean返回給用戶,剩下的生命周期由用戶控制。

2.4 Bean的裝配方式(依賴注入)

  1. 基于XML裝配:setter注入構造器注入
  2. 注解方式裝配
  1. @Configuration+@Bean注解:@configuration聲明該類是一個配置類,并將該類交由Spring管理,@Bean一般加在該類的方法上,表示該方法會返回一個Bean。
  2. 通過包掃描特定注解方式:@ConponentScan放在配置類上,然后指定一個路徑,進行掃描帶有特定注解的Bean,然后加到Spring容器中。特定注解包括@Controller、@Service、@Repository、@Component等。
  1. 自動裝配:通過設置Autowrited屬性值實現自動裝配。
  2. 根據類型自動裝配:byType,必須存在setter方法。
  3. 根據名稱自動裝配:byName。
  4. 根據構造方法自動裝配。
  5. 存在單例的Bean優先按照類型進行參數匹配,當存在多個類型相同實例時,按照名稱優先匹配,沒有找到則匹配失敗。

2.5 @Autowrited和@Resource注解

  1. 兩個注解都可以實現Bean的自動裝配。
  2. @Autowrited默認按照類型進行裝配(byType)。
  3. @Resource默認按照Bean的名稱進行裝配(byName)。
  1. @Resource有name和type兩個屬性,指定誰就按照誰來裝配,若都不指定,默認byName,若都沒有匹配到,拋異常。
  1. @Qualifier與@Autowrited注解配合使用,會將默認按照Bean類型裝配改為按照Bean的名稱進行裝配
  2. 對于配置文件中獲取值以及一些簡單類型(int、long、String等)進行依賴注入,可以直接使用@Value注解。
// 詳細使用Spring Boot中說明
@Value("${jdbc.url}")
private String url;

2.6 @Component和@Bean注解的區別

  1. @Bean是Java代碼裝配Bean,@Component是自動裝配Bean。
  2. @Component注解用在類上,表示一個類會作為組件類,并告知Spring要為這個類創建Bean,每個類對應一個Bean。
  3. @Bean注解用在方法上,表示這個方法會返回一個Bean,一般@Bean使用在配置類中,類上需要使用@Configuration注解。

2.7 常用的特定注解

  1. @Component:最普通的組件,可以被注入到Spring容器中管理,以下注解也可被注入到Spring中管理。
  2. @Controller:將類標記為Spring web mvc的控制器。
  3. @Service:將類標記為業務層組件。
  4. @Repository:將類標記為數據訪問層組件。

2.8 Spring Bean如何保證并發安全

  1. 單例模式變原型模式
  2. 盡量避免使用成員變量。
  3. 使用并發安全的類,CurrentHashMap等。
  4. 分布式或微服務的并發安全:使用Redis等中間件。


3、Spring AOP


3.1 初識AOP

  1. 概念:AOP也稱為面向切面編程,它是OOP(面向對象編程)的一種補充。
  1. AOP將公共邏輯(事務管理、日志、緩存等)封裝成切面。與業務代碼進行分離,可以減少系統的重復代碼和降低模塊之間的耦合度。
  2. 切面就是那些與業務無關,但所有業務模塊都會調用的公共邏輯。
  1. AOP框架
  1. Spring AOP:使用純Java實現,不需要專門的編譯過程和類加載器,在運行期間通過代理的方式向目標類織入增強的代碼。
  2. AspectJ:一個基于Java語言的AOP框架,它擴展了Java語言,提供了一個專門的編譯器,在編譯時提供橫向代碼的織入

3.2 使用AOP的好處

  1. 有效的減少了系統的重復代碼降低了模塊間的耦合度。
  2. 提高代碼的復用性
  3. 更好的分離關注點,提高代碼的可讀性和可維護性。

3.3 AOP的專業術語

  1. 切面(Aspect):封裝的用于橫向插入系統功能(事務、日志等)的類
  2. 連接點(JoinPoint):在程序執行過程中的某個階段點,它實際上是對象的一個操作。在Spring AOP框架中,指的就是方法的調用。
  3. 切入點(Pointcut):切面與流程的交叉點,即那些需要處理的連接點。通常在程序中,切入點指的是具體的類或方法名,又或者是正則表達式所匹配到的一些類或方法名
  4. 通知/增強處理(Advice):在定義好的切入點處所要執行的代碼,理解為切面類中的方法,切面的具體實現。
  5. 目標對象(Target Object):所有被通知的對象,通常是一個代理對象。
  6. 代理(Proxy):將通知應用到目標對象之后,被動態創建的對象。
  7. 織入(Weaving):將切面代碼插入到目標對象上,從而生成代理對象的過程

3.4 AOP中織入的時機

*應對的是目標對象的生命周期

  1. 編譯期:切面在目標類編譯時被織入AspectJ框架就是這樣實現的。
  2. 加載期:切面在目標類加載到JVM時織入,需要特殊的類加載器。
  3. 運行期:切面在應用運行的某個時刻被織入,一般情況下,在織入切面時,AOP容器會為目標對象動態的創建一個代理對象,Spring AOP框架就是以這種方式織入的切面。

3.5 AOP的實現方式(代理方式)

  1. 靜態代理
  1. 實現機制:代理類在編譯階段生成,在編譯階段將通知織入Java字節碼中,編譯期增強。AspectJ框架使用的是靜態代理。
  2. 缺陷:代理對象需要與目標對象實現一樣的接口,并且實現接口的方法存在一定的冗余代碼,其次,一旦接口增加方法,目標對象與代理對象都需要進行維護。
  1. 動態代理
  1. 實現機制:代理類在程序運行時創建,Spring AOP框架不會去修改字節碼,而是在內存中臨時生成一個代理對象,在運行期間對業務方法進行增強。

3.6 Spring AOP的實現原理

通過動態代理實現的。如果我們為Spring的某個Bean配置了切面,那么Spring在創建這個Bean的時候,實際上創建的是這個Bean的一個代理對象,后續對目標類Bean的方法調用,實際上調用的是代理類重寫的代理方法

3.7 Spring AOP主要的兩種動態代理

  1. JDK動態代理
  1. 實現機制:如果目標類實現了接口,Spring AOP會選擇使用JDK動態代理目標類。代理類根據目標類實現的接口動態生成,不需要自己編寫,生成的動態代理類和目標類都實現相同的接口。
  2. 核心:實現InvocationHandler接口和Proxy類
  3. 局限性:目標類必須實現一個或多個接口,如果類沒有實現接口,就不能使用JDK動態代理該目標類。
  1. CGLIB動態代理
  1. 實現機制:CGLIB動態代理是通過繼承實現的。如果目標類沒有實現一個或多個接口,Spring AOP框架會選擇使用CGLIB動態代理目標類。CGLIB動態代理可以在運行時動態生成目標類的字節碼動態創建目標類的子類對象,在子類對象中增強目標類。
  2. 特別注意:由于CGLIB動態代理是通過繼承實現的,如果某個類使用了final關鍵字修飾,該類將無法被繼承,所以就無法使用CGLIB動態代理目標類。
  3. 相比于JDK動態代理的優勢:目標類不需要實現接口,更加靈活。
  1. Spring AOP框架對兩種動態代理的使用場景
  1. 如果目標類實現了接口,Spring AOP框架默認使用JDK動態代理,也可強制使用CGLIB動態代理。
  2. 如果目標類沒有實現接口,必須使用CGLIB動態代理。

3.8 JDK動態代理和CGLIB動態代理的區別

  1. JDK動態代理使用JDK中的Proxy類來創建代理對象,它使用反射技術來實現,不需要導入其他依賴;CGLIB需要引入相關依賴-asm.jar使用字節碼增強技術來實現。
  2. 當目標類實現了接口的時候,Spring AOP框架默認使用的是JDK動態代理增強方法,目標類沒有實現接口的時候,使用CGLIB動態代理。

3.9 Spring的通知類型

  1. 環繞通知(Around):在目標方法執行前后實施增強,可以應用于日志、事務管理等功能。
  2. 前置通知(Before):在目標方法執行前實施增強,可以應用于權限管理等功能。
  3. 后置通知(After-running):在目標方法執行后實施增強,可以應用于關閉流、上傳/刪除臨時文件等功能。
  4. 異常通知(After-throwing):在方法拋出異常后實施增強,可以應用于處理異常、記錄日志等功能。
  5. 引介通知(IntroductionInterceptor):在目標類中添加一些新的屬性和方法,通常用于老版本程序的修改

3.10 基于注解使用AspectJ

  1. @Aspect:注解用在類上,標注該類是一個切面類。
  2. @Pointcut:定義切入點表達式,需要指定一個包含和任意參數的方法簽名來表示切入點名稱。通常為返回值為viod的空方法。
  3. @通知類型(Before/After等):標注在方法上,value值傳入切入點的空方法名。@After最終通知,不管是否異常,該通知都會執行
  4. 使用前需要先導入AOP和AspectJ的依賴(Spring Boot)
<!-- 復制粘貼下載即可 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
</dependency>
/**
 * 定義切面類
 */
@Aspect
@Component
public class MyAspect {
    // 切點
    @Pointcut("execution(* com.lz.learning.*.*(..))")
    public void myPointCut() {
    }
    // 前置通知
    @Before("myPointCut()")
    public void myBefore(JoinPoint joinPoint) {
        System.out.println("前置通知,目標類:" + joinPoint.getTarget() + ",增強的目標方法:"
                + joinPoint.getSignature().getName());
    }
    // 后置通知
    @AfterReturning("myPointCut()")
    public void myAfterRunning(JoinPoint joinPoint) {
        System.out.println("后置通知,目標類:" + joinPoint.getTarget() + ",增強的目標方法:"
                + joinPoint.getSignature().getName());
    }
    // 環繞通知
    @Around("myPointCut()")
    public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("模擬環繞開始...");
        // 執行當前目標方法
        Object obj = proceedingJoinPoint.proceed();
        System.out.println("模擬環繞結束...");
        return obj;
    }
    // 異常通知
    @AfterThrowing(value = "myPointCut()", throwing = "e")
    public void myAfterThrowing(JoinPoint joinPoint, Throwable e) {
        System.out.println("異常通知:" + e.getMessage());
    }
    // 最終通知,不管是否異常,該通知都會執行
    @After("myPointCut()")
    public void myAfter() {
        System.out.println("最終通知...");
    }
}


4、Spring的事務管理


4.1 認識Spring事務

  1. 概念:多個操作單元組成的集合,多個單元操作是整體不可分割的。
  2. 基本特性:原子性、一致性、隔離性、持久性
  3. Spring事務的實現方式
  1. 編程式事務:通過編程式的方式進行管理事務,靈活性強,但很難維護。
  2. 聲明式事務:將事務管理代碼從業務方法中分離出來,通過AOP進行封裝,無需處理關閉連接、提交/回滾等操作。

4.2 Spring事務管理的核心接口

  1. PlatformTransactionManager接口:Spring提供的平臺事務管理器來管理事務。主要實現方法:
  1. TransactionStatus getTransaction(TransactionDefinition td):獲取事務的狀態信息。
  2. void commit(TransactionStatus status):事務提交。
  3. void rollback(TransactionStatus status):事務回滾。
  1. TransactionDefinition接口:事務描述的對象,定義了事務的規則。
  1. String getName():獲取事務對象的名稱。
  2. int getlsolationLevel():獲取事務的隔離級別。
  3. int getPropagationBehavior():獲取事務的傳播行為。
  4. int getTimeout():獲取事務的超時時間。
  5. boolean isReadOnly():是否是只讀事務。
  1. TransactionStatus接口:事務的狀態,某一時間點上事務的狀態信息。
  1. void flush():刷新事務。
  2. boolean hasSavepoint():獲取事務是否存在保存點。
  3. boolean isCompleted():獲取事務是否完成。
  4. void setRollbackOnly():設置事務回滾。

4.3 @Transactional注解

  1. 作用域
  1. 聲明在上:表示整個類的所有方法都起作用。
  2. 聲明在方法上:表示只對當前方法有效。
  1. 可配置的相關參數
  1. value:指定需要使用的事務管理器。默認為"",其別名為transactionManager。
  2. isolation:指定事務的隔離級別,默認為DEFAULT。
  3. noRollbackFor:指定遇到特定異常時強制不回滾事務。noRollbackFor=RuntimeException.class
  4. rollbackFor:指定遇到特定異常強制回滾事務。不指定默認為對RuntimeException異常進行回滾,一般可以指定Exception,rollbackFor=Exception.class
  5. noRollbackForClassName:指定遇到特定的多個異常強制不回滾事務,可以指定多個異常類名。
  6. rollbackForClassName:指定遇到特定的多個異常強制回滾事務,可以指定多個異常類名。
  7. read-only指定事務是否為只讀,默認false。
  8. propagation:指定事務的傳播行為,默認為REQUIRED。
  9. timeout:指定事務的超時時間,默認為TIMEOUT_DEFAULT(底層事務系統的默認時間)。

4.4 @Transactional注解失效的情況

  1. 訪問權限的問題
  1. 權限大?。?code style="background-color: rgb(231, 243, 237); padding: 1px 3px; border-radius: 4px; overflow-wrap: break-word; text-indent: 0px; display: inline-block;">private < default < protected < public
  2. 如果所注解的方法的訪問權限不是public,會導致事務失效,Spring要求被代理方法必須是public。
  1. 目標方法使用了final關鍵字
  1. 如果目標方法使用了final關鍵字修飾,事務會失效。
  2. 原因:Spring事務底層使用了AOP,通過JDK的動態代理或者CGLIB動態代理的方式生成了代理類,在代理類中實現了事務的功能,使用final修飾有悖于兩種動態代理的底層機制。
  1. 對象沒有被Spring管理
  1. 使用Spring事務的前提是對象要被Spring容器管理,需要創建Bean的實例,如果類沒有加@Component、@Service、@Controller等特定注解,該類也就沒有交由Spring去管理,事務不會生效。
  1. 表的存儲引擎不支持事務
  1. 如果MySQL使用的存儲引擎是myisam,它是不支持事務的。
  1. 異常被捕獲后沒有拋出[實際開發中常遇到]
  1. 目標方法中使用了try{}catch(){}手動捕獲了異常,并對異常做了處理,沒有繼續拋出異?;虍惓1煌痰袅?/span>,此時Spring事務機制認為異常已經被處理,沒有了異常,自然也不會觸發回滾
  2. 若需要事務能夠回滾生效,手動捕獲后可以再手動的拋出它所接收的異常。
@Transactional(rollbackFor = Exception.class)
public int test() {
    int y = 12;
    int x = 0;
    int result = 0;
    try {
        // 算術異常
        result = y / x;
    } catch (Exception e) {
        result = -1;
        System.out.println(e.getMessage());
        // 捕獲異常處理之后不再拋出,事務失效
        // 捕獲處理之后需將異常拋出,此時事務才會生效
        throw new RuntimeException(e.getMessage(), e);
    }
    return result;
}
  1. 一個類的方法的內部調用
  1. 同一類中,某個方法方法調用了加了事務注解的目標方法,此時事務注解不會生效。
  2. 原因:這實際上是在同一個對象中調用了方法,并沒有經過Spring的代理類,所以事務會失效。
@Component
public class MyTransaction {
    @Transactional(rollbackFor = Exception.class)
    public void printA() {
        System.out.println("A");
    }
    public void printB() {
        // 內部直接調用事務方法,此時A方法事務不生效
        printA();
    }
}
  1. 未開啟事務
  1. 如果是Spring項目,需要在配置中手動配置開啟事務的相關參數。
  2. 如果是Spring Boot項目,不需要手動配置,因為在DataSourceTransactionManagerAutoConfiguration類中已經開啟了事務。


5、Spring MVC

5.1 MVC模式

  1. 定義:MVC(model模型-view視圖-controller控制器)是一種軟件設計規范,是將業務邏輯、數據、顯示分離的方法來組織代碼。MVC不是一種設計模式,而是一種架構模式。
  2. 主要作用:降低了視圖與業務邏輯的雙向耦合,代碼的重用性高,易于維護和擴展。
  3. 分層解讀
  1. model層:用于處理應用程序中數據邏輯的部分。
  2. view層:負責進行模型的展示,一般是用戶界面。
  3. controller層:接收用戶輸入并返回數據的部分,數據交互。

5.2 認識Spring MVC

  1. 定義:Spring提供的一個實現了Web MVC模式的輕量級web框架,屬于Spring框架的一個模塊
  2. 實現機制:Spring MVC通過一套注解讓一個簡單的Java類成為處理請求的控制器,而無需實現任何接口,同時它還支持REST風格的請求。
  3. 特點:
  1. 它是Spring框架的一部分,可以方便使用Spring框架提供的其他功能。
  2. 靈活性強,易于和其他框架集成。
  3. 自動綁定用戶輸入,正確轉換數據類型。
  4. 支持國際化,根據用戶區域顯示多國語言。
  5. 支持多種視圖技術,JSP、Velocity等。
  6. 支持REST風格請求。
  7. 提供了一個前端控制器DispatcherServlet,無需額外開發控制器對象。
  8. 內置常見的校驗器,可以校驗用戶輸入。校驗不通過會重定向到原表單。

5.3 Spring MVC的主要組件

  1. 前端控制器(DispatcherServlet):接收用戶請求,給用戶返回結果。
  2. 處理器映射器(HandlerMapping):根據請求的URL路徑,通過XML配置或者注解來尋找匹配的處理器
  3. 處理器適配器(HandlerAdapter):Handler處理器的適配器,調用Handler中的方法處理請求。
  4. 處理器(Handler):執行相關的請求處理邏輯,并返回相應的數據和視圖信息,將其封裝到ModelAndView對象中。
  5. 視圖解析器(ViewResolver):將視圖邏輯解析成真正的View視圖。
  6. 視圖(View):View接口,實現類可支持不同的View類型(JSP等)。

5.4 Spring MVC內部的工作流程

Spring框架必知,滿滿干貨!_@Transactional_03

  1. 用戶通過客戶端向服務器發送請求,請求會被Spring MVC的前端控制器DispatcherServlet攔截。
  2. DispatcherServlet攔截到請求后,會調用HandlerMapping處理器映射器。
  3. 處理器映射器根據請求的URL找到具體的處理器,生成處理器對象以及處理器攔截器,一并返回給前端控制器。
  4. 前端控制器會通過返回的信息選擇合適的HandlerAdapter處理器適配器。
  5. 處理器適配器會調用并執行Handler處理器,這里的處理器指的就是程序中的Controller類,也被稱為后端控制器。
  6. Controller執行完之后,會返回一個ModelAndView對象,包含模型和視圖名。
  7. 處理適配器將ModelAndView對象返回給前端控制器
  8. 前端控制器會根據ModelAndView對象選擇一個合適的ViewResolver視圖解析器。
  9. ViewResolver解析之后,會向前端控制器中返回具體的View視圖。
  10. 前端控制器對View視圖進行渲染。
  11. 渲染結果會返回給客戶端瀏覽器進行顯示。

5.5 Spring MVC常用注解

  1. @Controller:標識此類的實例是一個控制器。
  1. 機制:Spring容器會掃描該類,然后掃描該類下面的帶有@RequestMapping注解的方法,為這個方法生成一個對應的處理器對象。
  1. @RequestMapping:映射一個請求或映射一個方法。
  1. 標注在方法上:該方法成為一個請求處理的方法,它會在接收到對應的URL請求時被調用。
  2. 標注在類上:該類所有的方法都將映射為相對于類級別的請求,該控制器所處理的所有請求都被映射到value屬性所指定的路徑下(常用在類上)。
  1. @Get/Post/Put/Delete/PatchMapping:匹配GET/POST等方式的請求。
  2. @RequestBody接收Http請求的JSON數據,將JSON數據轉換為Java對象,標注在方法的形參上
  3. @ResponseBody返回JSON格式的數據,標注在方法上。
  4. @PathVariable:獲得URL路徑中的變量的值,常與REST風格請求適配,標注在方法的形參上。
  1. 若請求參數中的變量名與形參的名稱相同,注解后可以省略標注
@GetMapping("user/{id}")
// 注解里面的id可以省略
public User getUserById(@PathVariable("id") int id)
  1. @RestController:組合注解,@Controller + @ResponseBody
  2. @ExceptionHandle:標識一個方法為全局異常處理的方法。

5.6 Spring MVC的異常處理

可以將異常拋給Spring框架,由Spring框架來處理;只需要配置簡單的異常處理器,在異常處理器中添視圖頁面即可。

  1. 使用系統定義好的異常處理器 SimpleMappingExceptionResolver
  2. 使用自定義異常處理器
  3. 使用異常處理注解

5.7 Spring MVC用什么對象從后臺向前臺傳遞數據

  1. 將數據綁定到request中。
  2. 返回ModelAndView。
  3. 通過ModelMap對象,可以在這個對象里面調用put方法,把對象加到里面,前端就可以通過el表達式拿到。
  4. 綁定數據到 Session中。

5.8 @RequestParam和@PathVariable的區別

兩個注解都作用于方法的形參上,它們獲取參數值的方式不同。@RequestParam注解的參數值從請求攜帶的參數中獲取,而@PathVariable從請求的URL中獲取。

5.9 @RequestBody和@RequestParam的區別

處理的請求數據類型不同

  1. @RequestBody一般處理的是ajax請求中contentType:application/json類型的數據,也就是JSON或XML格式數據。
  2. @RequestParam:一般處理沒有聲明contentType格式的數據。

5.10 REST風格

  1. 定義:一種軟件架構的風格或設計風格,而不是一個標準。
  1. Representational:某種表現形式,例如:JSON、XML等
  2. states Transfer:狀態變化,通過Http method實現。
  1. 表現形式:把請求參數變為請求路徑的一種風格。例
  2. 原:http://.../queryItems?id=6;REST:http://.../items/6
  3. REST風格中URL不存在動詞形式的路徑,在HTTP請求中,put(添加)、delete(刪除)、post(修改)、get(查詢)
  4. 通常配合@PathVariable注解使用。
  5. 使用REST的優勢
  1. 風格統一
  2. 面向資源,具有自解釋性
  3. 充分利用http本身語義

5.11 Spring MVC攔截器

  1. 概述:主要用于攔截用戶請求并作相應的處理,用于權限驗證、記錄請求、判斷登錄等功能。
  2. 實現方式:通過實現HandlerInterceptor接口中的方法(常用的一種)
  1. preHandler():該方法會在Controller控制器的方法執行前執行,其返回值表示是否中斷后續操作。返回true,繼續向下執行,返回false將中斷后續所有操作
  2. postHandler():控制器方法執行之后再執行,且解析視圖之前執行??梢詫φ埱笥蛑械哪P秃鸵晥D做出進一步的修改。
  3. afterCompletion():該方法會在整個請求完成,即視圖渲染結束之后執行。實現一些資源清理、記錄日志等功能。
  1. 三個方法的執行順序
  1. preHandler -> controller中的方法 -> postHandler -> 前端控制器 -> afterCompletion
  1. Spring MVC攔截器的XML配置
<!-- 配置Spring Mvc攔截器 -->
<mvc:interceptors>
    <bean id="myInterceptor" class="com.dabin.MyHandlerInterceptor">
    </bean>
    
    <!-- 只攔截部分請求 -->
    <mvc:interceptor>
       <mvc:mapping path="/xxx.do" />
       <bean class="com.dabin.MyHandlerInterceptorAdapter" />
    </mvc:interceptor>
</mvc:interceptors>

5.12 Spring MVC攔截器和Filter過濾器的區別

  1. 功能相同:都可以實現相同的功能。
  2. 容器不同:攔截器構建在Spring MVC體系中,Filter構建在servlet容器之上。
  3. 使用的便利性不同:前者實現了三個方法,分別在不同的時機執行,Filter過濾器僅提供了一個方法。
聲明:所有內容來自互聯網搜索結果,不保證100%準確性,僅供參考。如若本站內容侵犯了原著者的合法權益,可聯系我們進行處理。
發表評論
更多 網友評論0 條評論)
暫無評論

返回頂部

主站蜘蛛池模板: 无码国产精品一区二区免费式芒果| 亚洲一区在线视频观看| 国产极品美女高潮抽搐免费网站 | 一本一道精品欧美中文字幕| 人妻少妇偷人精品无码| 中文字幕aⅴ人妻一区二区| 精品丝袜国产自在线拍亚洲| 婷婷色香五月综合激激情| 亚洲精品人成无码中文毛片| 怡红院色视频在线| 日韩三级电影在线播放| 国产va在线观看免费| jizzjizz之xxxx18| 欧美国产成人精品一区二区三区| 国产在线高清视频无码| 中文字幕一区二区三区人妻少妇| 狂野欧美激情性xxxx在线观看| 国产精品成人免费综合| 久久国产精品无码一区二区三区 | 免费无码国产V片在线观看| 91精品国产91久久久久久最新| 最近免费韩国电影hd免费观看| 国产亚洲欧美精品久久久| 一个人看的www免费高清| 欧美巨大黑人hd| 日韩欧美国产视频| 又大又硬又黄的免费视频| 91制片厂制作果冻传媒168| 日韩免费一区二区三区| 免费人成在线观看视频高潮| 18美女腿打开无遮挡| 无码A级毛片免费视频内谢| 亚洲综合亚洲国产尤物| 黄色福利视频网站| 女人被男人躁的女爽免费视频| 亚洲人成色777777在线观看| 老司机福利在线观看| 国产综合久久久久| 久久er99热精品一区二区| 波多野结衣在线观看3人| 国产免费直播在线观看视频|