最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

Spring:現(xiàn)代Java開發(fā)的必備框架

2023-03-15 10:28 作者:吳小敏63  | 我要投稿

Spring:現(xiàn)代Java開發(fā)的必備框架

Spring是一個輕量級的Java框架,它提供了各種企業(yè)級應用程序開發(fā)的工具和技術。Spring框架的核心是IoC容器和AOP框架。IoC容器使得Java應用程序的組件化變得更加容易,AOP框架使得Java應用程序的切面編程變得更加容易。Spring框架還提供了許多其他的功能,例如數(shù)據(jù)訪問、Web開發(fā)、安全性、事務管理等。

Spring創(chuàng)建bean的生命周期以及對應的接口和注解

Spring創(chuàng)建bean的生命周期包含以下步驟:

  1. 實例化Bean:Spring通過構(gòu)造器或工廠方法來創(chuàng)建Bean實例。

  2. 設置Bean屬性:Spring通過setter方法或直接訪問字段來設置Bean的屬性值。

  3. BeanNameAware接口:如果Bean實現(xiàn)了BeanNameAware接口,Spring將Bean的ID傳遞給setBeanName()方法。

  4. BeanFactoryAware接口:如果Bean實現(xiàn)了BeanFactoryAware接口,Spring將BeanFactory實例傳遞給setBeanFactory()方法。

  5. ApplicationContextAware接口:如果Bean實現(xiàn)了ApplicationContextAware接口,Spring將ApplicationContext實例傳遞給setApplicationContext()方法。

  6. Pre-Initialization BeanPostProcessor:在Bean初始化之前,Spring通過調(diào)用PostProcessBeforeInitialization()方法提供了一個擴展點,可以在Bean初始化之前對Bean進行定制。

  7. InitializingBean接口:如果Bean實現(xiàn)了InitializingBean接口,Spring將調(diào)用afterPropertiesSet()方法。

  8. 自定義初始化方法:Bean可以自定義初始化方法,只需要在Bean定義中指定該方法的名稱。

  9. Post-Initialization BeanPostProcessor:在Bean初始化之后,Spring通過調(diào)用PostProcessAfterInitialization()方法提供了一個擴展點,可以在Bean初始化之后對Bean進行定制。

  10. DisposableBean接口:如果Bean實現(xiàn)了DisposableBean接口,Spring將調(diào)用destroy()方法。

  11. 自定義銷毀方法:Bean可以自定義銷毀方法,只需要在Bean定義中指定該方法的名稱。

在Spring中,可以使用以下注解來控制Bean的生命周期:

  • @PostConstruct:指定初始化方法,相當于InitializingBean接口的afterPropertiesSet()方法。

  • @PreDestroy:指定銷毀方法,相當于DisposableBean接口的destroy()方法。

  • @Bean(initMethod = "initMethod", destroyMethod = "destroyMethod"):指定初始化方法和銷毀方法。

Spring使用三級緩存解決循環(huán)依賴的原理

  1. singletonObjects:保存已經(jīng)完全創(chuàng)建好的單例Bean。

  2. earlySingletonObjects:保存已經(jīng)實例化、但是還未填充屬性的單例Bean。

  3. singletonFactories:保存Bean的工廠方法。

當兩個Bean相互依賴時,Spring會先使用工廠方法創(chuàng)建一個Bean的代理對象,然后將代理對象放入到singletonFactories緩存中。接著,Spring會繼續(xù)創(chuàng)建被依賴的Bean。如果創(chuàng)建被依賴的Bean時,需要引用到代理對象,Spring會先到singletonFactories緩存中查找代理對象,如果找到了,就使用代理對象,否則就繼續(xù)創(chuàng)建代理對象。當被依賴的Bean創(chuàng)建完成后,Spring會將被依賴的Bean放入到singletonObjects緩存中。接著,Spring會回到代理對象,填充代理對象的屬性,然后將代理對象放入到earlySingletonObjects緩存中。當代理對象的屬性填充完成后,Spring會將代理對象替換成真正的Bean對象,然后將真正的Bean對象放入到singletonObjects緩存中,并清除earlySingletonObjects緩存和singletonFactories緩存中的代理對象。

Spring使用三級緩存創(chuàng)建bean的過程

Spring使用三級緩存創(chuàng)建Bean的詳細過程如下:

  1. 首先,Spring會檢查該Bean是否已經(jīng)創(chuàng)建并存儲在singletonObjects緩存中。如果Bean已經(jīng)存在,則直接返回該Bean實例。這是最快的情況。

  2. 如果Bean不存在于singletonObjects緩存中,Spring會檢查該Bean是否正在創(chuàng)建中。如果正在創(chuàng)建中,則返回一個代理對象,該代理對象會在真正的Bean創(chuàng)建完成后被替換成真正的Bean對象。這是為了防止循環(huán)依賴的情況。

  3. 如果該Bean既不存在于singletonObjects緩存中,也沒有正在創(chuàng)建中,則Spring會創(chuàng)建一個ObjectFactory,該ObjectFactory負責創(chuàng)建該Bean實例。ObjectFactory是一個工廠方法,它負責創(chuàng)建和返回Bean實例。

  4. 然后,Spring會將該ObjectFactory存儲到singletonFactories緩存中,以便下次獲取該Bean實例時使用。這是為了提高創(chuàng)建Bean實例的效率。

  5. 接著,Spring會檢查該Bean是否依賴于其他Bean。如果依賴于其他Bean,則會先創(chuàng)建依賴的Bean實例。依賴項可以是其他Bean,也可以是基本類型或集合。

  6. 如果依賴的Bean實例還不存在,則Spring會遞歸地創(chuàng)建依賴的Bean實例,直到所有依賴的Bean實例都已經(jīng)創(chuàng)建完成。這是為了保證依賴關系正確。

  7. 如果所有依賴的Bean實例都已經(jīng)創(chuàng)建完成,則Spring會從singletonFactories緩存中獲取該Bean的ObjectFactory,并使用該ObjectFactory創(chuàng)建該Bean實例。這是Bean實例的創(chuàng)建過程。

  8. 創(chuàng)建該Bean實例后,Spring會將該Bean實例存儲到earlySingletonObjects緩存中,以便后續(xù)填充該Bean的屬性。earlySingletonObjects緩存包含已經(jīng)創(chuàng)建的單例Bean實例,但是還沒有填充屬性。

  9. 接著,Spring會遞歸地填充該Bean的屬性。如果該Bean的屬性依賴于其他Bean,則會先創(chuàng)建依賴的Bean實例。填充屬性之前,Spring會調(diào)用所有實現(xiàn)了BeanPostProcessor接口的類的postProcessBeforeInitialization()方法做一些預處理工作。這是為了提供一個擴展點,可以在Bean初始化之前對Bean進行定制。

  10. 如果所有依賴的Bean實例都已經(jīng)創(chuàng)建完成,則Spring會從singletonObjects緩存中獲取依賴的Bean實例,并將依賴的Bean實例填充到該Bean的屬性中。填充屬性之后,Spring會再次調(diào)用所有實現(xiàn)了BeanPostProcessor接口的類的postProcessAfterInitialization()方法做一些后處理工作。這是為了提供一個擴展點,可以在Bean初始化之后對Bean進行定制。

  11. 填充該Bean的屬性后,Spring會將該Bean實例存儲到singletonObjects緩存中,并從earlySingletonObjects緩存中移除該Bean實例。singletonObjects緩存包含已經(jīng)創(chuàng)建的單例Bean實例,并已經(jīng)填充了屬性。

  12. 最后,Spring會遞歸地處理該Bean的后置處理器,然后返回該Bean實例。如果Bean實現(xiàn)了InitializingBean接口,Spring會調(diào)用其afterPropertiesSet()方法,這是Bean初始化之后的最后一步。如果Bean實現(xiàn)了DisposableBean接口,Spring會在Bean銷毀之前調(diào)用其destroy()方法。

Spring使用AOP

基本過程如下:

  1. 在配置類上添加@EnableAspectJAutoProxy注解,啟用AspectJ自動代理。

  2. 創(chuàng)建一個切面類,并且在該類上使用@Aspect注解來標識該類為切面類。

  3. 在切面類中定義一個或多個切點,用來匹配需要攔截的方法。

  4. 在切面類中定義一個或多個通知,用來在方法執(zhí)行前、執(zhí)行后或拋出異常時執(zhí)行一些額外的邏輯。

  5. 將切面類添加到Spring的容器中。

以下是一個使用注解方式實現(xiàn)AOP的示例:

@Aspect@Componentpublic class LoggingAspect { ? ?@Pointcut("execution(* com.example.demo.service.*.*(..))") ? ?public void serviceLayer(){} ? ?@Before("serviceLayer()") ? ?public void logBefore(JoinPoint joinPoint) { ? ? ? ?System.out.println("Before " + joinPoint.getSignature().getName()); ? ?} ? ?@After("serviceLayer()") ? ?public void logAfter(JoinPoint joinPoint) { ? ? ? ?System.out.println("After " + joinPoint.getSignature().getName()); ? ?} }@Servicepublic class DemoService { ? ?public void doSomething() { ? ? ? ?System.out.println("Doing something..."); ? ?} }@Configuration@EnableAspectJAutoProxy@ComponentScan("com.example.demo")public class AppConfig { }

在上面的示例中,LoggingAspect是一個切面類,它定義了一個切點serviceLayer()和兩個通知logBefore()和logAfter()。serviceLayer()用來匹配com.example.demo.service包中所有方法,logBefore()和logAfter()分別在方法執(zhí)行前和執(zhí)行后輸出一條日志。DemoService是一個普通的服務類,它的doSomething()方法會被LoggingAspect攔截。最后,AppConfig是一個配置類,它啟用了AspectJ自動代理,并將LoggingAspect和DemoService添加到Spring的容器中。

當調(diào)用DemoService的doSomething()方法時,LoggingAspect會攔截該方法,并在方法執(zhí)行前輸出一條日志,同時在方法執(zhí)行后輸出一條日志。

SpringAOP的實現(xiàn)原理

Spring AOP的實現(xiàn)原理是使用動態(tài)代理技術。動態(tài)代理是在運行時創(chuàng)建代理對象,代理對象實現(xiàn)了目標對象的接口,并且攔截所有方法調(diào)用。Spring AOP使用了兩種類型的代理:JDK動態(tài)代理和CGLIB動態(tài)代理。如果目標對象實現(xiàn)了接口,則使用JDK動態(tài)代理;否則,使用CGLIB動態(tài)代理。

Spring使用事務管理

Spring的事務管理可以通過如下方式來使用:

  1. 配置事務管理器:Spring提供了多種事務管理器,如DataSourceTransactionManager、HibernateTransactionManager等。可以通過配置事務管理器來選擇適合的事務管理器。

  2. 配置事務屬性:可以通過配置事務屬性來指定事務的傳播行為、隔離級別、超時時間、只讀等特性。

  3. 使用@Transactional注解:可以在需要事務管理的方法上添加@Transactional注解,Spring會自動管理該方法的事務。@Transactional注解可以指定事務的傳播行為、隔離級別、超時時間、只讀等特性。

Spring事務的傳播行為指的是當一個事務方法調(diào)用另外一個事務方法時,如何管理事務。Spring定義了七種傳播行為,包括:

  • REQUIRED:如果當前存在事務,則加入該事務,否則創(chuàng)建一個新的事務。

  • SUPPORTS:如果當前存在事務,則加入該事務,否則以非事務的方式執(zhí)行。

  • MANDATORY:必須在一個已有的事務中執(zhí)行,否則拋出異常。

  • REQUIRES_NEW:創(chuàng)建一個新的事務,并且暫停當前事務(如果存在)。

  • NOT_SUPPORTED:以非事務方式執(zhí)行操作,如果當前存在事務,則暫停該事務。

  • NEVER:以非事務方式執(zhí)行操作,如果當前存在事務,則拋出異常。

  • NESTED:如果當前存在事務,則在嵌套事務內(nèi)執(zhí)行。如果當前沒有事務,則執(zhí)行REQUIRED類似的操作。

Spring事務的隔離級別指的是多個事務之間的隔離程度。Spring定義了五種隔離級別,包括:

  • DEFAULT:使用底層數(shù)據(jù)庫的默認隔離級別。

  • READ_UNCOMMITTED:允許臟讀、不可重復讀和幻讀。

  • READ_COMMITTED:禁止臟讀,但允許不可重復讀和幻讀。

  • REPEATABLE_READ:禁止臟讀和不可重復讀,但允許幻讀。

  • SERIALIZABLE:禁止臟讀、不可重復讀和幻讀,最嚴格的隔離級別。

Spring事務的超時時間指的是事務的執(zhí)行時間超過該時間時,事務將被回滾。Spring默認的事務超時時間為-1,表示事務沒有超時限制。只讀事務指的是事務中只讀取數(shù)據(jù),不修改數(shù)據(jù)。只讀事務可以提高數(shù)據(jù)庫的并發(fā)性能。

可以使用@Transactional注解來指定事務的傳播行為、隔離級別、超時時間、只讀等特性。例如:

@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 3600, readOnly = false)public void doSomething() { ? ?// some code}

在這個例子中,@Transactional注解指定了事務的傳播行為為REQUIRED、隔離級別為DEFAULT、超時時間為3600秒、只讀為false。

使用Spring事務管理可以提高應用程序的性能和可靠性。它可以確保在事務范圍內(nèi)的所有操作要么全部成功,要么全部失敗,從而保持數(shù)據(jù)的完整性和一致性。

Spring事務的原理

Spring事務的實現(xiàn)原理是使用AOP技術。在Spring中,事務管理是通過將事務管理器和事務通知應用到目標方法上來實現(xiàn)的。事務管理器是負責管理事務的對象,事務通知是負責在目標方法執(zhí)行前后開啟、提交或回滾事務的對象。在Spring中,事務通知是使用AspectJ的@Aspect注解來實現(xiàn)的。

當一個方法被標記為@Transactional時,Spring會創(chuàng)建一個代理對象來代理該方法。該代理對象會將目標方法的調(diào)用轉(zhuǎn)發(fā)給事務通知。在事務通知中,會根據(jù)事務管理器的配置來開啟、提交或回滾事務。如果方法執(zhí)行過程中發(fā)生了異常,則會回滾事務。如果方法執(zhí)行成功,則會提交事務。事務管理器會將事務的狀態(tài)存儲在ThreadLocal中,以便在同一線程中的其他方法也可以訪問該事務。

Spring事務的實現(xiàn)依賴于底層的數(shù)據(jù)庫事務。Spring提供了多種事務管理器,如DataSourceTransactionManager、HibernateTransactionManager等。事務管理器可以配置事務的傳播行為、隔離級別、超時時間、只讀等特性。

DataSourceTransactionManager的實現(xiàn)

DataSourceTransactionManager的實現(xiàn)主要包括以下內(nèi)容:

  1. 實現(xiàn)了PlatformTransactionManager接口,用于管理事務的生命周期。PlatformTransactionManager接口是Spring事務管理器的核心接口,它定義了事務的生命周期和狀態(tài)轉(zhuǎn)換規(guī)則。DataSourceTransactionManager實現(xiàn)了PlatformTransactionManager接口,用于管理基于DataSource的事務。PlatformTransactionManager接口包括以下方法:

    • getTransaction(TransactionDefinition definition):獲取一個新的事務或?qū)斍熬€程中的事務加入到當前方法的事務中。

    • commit(TransactionStatus status):提交當前事務。

    • rollback(TransactionStatus status):回滾當前事務。

  2. 實現(xiàn)了TransactionDefinition接口,用于定義事務的傳播行為、隔離級別、超時時間、只讀等特性。TransactionDefinition接口定義了事務的屬性,包括傳播行為、隔離級別、超時時間、只讀等。DataSourceTransactionManager實現(xiàn)了TransactionDefinition接口,用于指定基于DataSource的事務的屬性。

  3. 實現(xiàn)了TransactionStatus接口,用于跟蹤事務的狀態(tài)。TransactionStatus接口定義了事務的狀態(tài),包括未提交、已提交和已回滾。DataSourceTransactionManager實現(xiàn)了TransactionStatus接口,用于跟蹤基于DataSource的事務的狀態(tài)。

  4. 實現(xiàn)了TransactionSynchronizationManager類,用于管理事務的同步狀態(tài)。TransactionSynchronizationManager類用于管理事務的同步狀態(tài),包括事務的開始、結(jié)束和回滾等操作。DataSourceTransactionManager使用TransactionSynchronizationManager類來管理基于DataSource的事務的同步狀態(tài)。

  5. 實現(xiàn)了TransactionAspectSupport類,用于支持基于AspectJ的事務通知。TransactionAspectSupport類是Spring事務管理的核心類,它實現(xiàn)了基于AspectJ的事務通知邏輯。DataSourceTransactionManager使用TransactionAspectSupport類來支持基于AspectJ的事務通知。

DataSourceTransactionManager的工作流程

  1. 當一個方法被標記為@Transactional時,Spring會創(chuàng)建一個代理對象來代理該方法。

  2. 代理對象會調(diào)用TransactionAspectSupport類的invokeWithinTransaction()方法,該方法會在事務的上下文中執(zhí)行目標方法。

  3. 在invokeWithinTransaction()方法中,會調(diào)用DataSourceTransactionManager的doBegin()方法來開啟事務。

  4. 在doBegin()方法中,會獲取當前線程中的Connection對象,并將其設置為事務的連接。

  5. 如果當前線程中沒有Connection對象,則會從DataSource中獲取一個新的Connection對象,并將其設置為事務的連接。

  6. 如果事務的隔離級別不是默認值,則會將事務的隔離級別設置到Connection對象上。

  7. 如果事務的超時時間不是默認值,則會將事務的超時時間設置到Connection對象上。

  8. 在目標方法執(zhí)行完畢后,會調(diào)用TransactionAspectSupport類的invokeWithinTransaction()方法的afterCompletion()方法來提交或回滾事務。

  9. 在afterCompletion()方法中,會調(diào)用DataSourceTransactionManager的doCleanupAfterCompletion()方法來清理事務狀態(tài)。

  10. 在doCleanupAfterCompletion()方法中,會將事務的連接關閉,并將其從當前線程中移除。

Spring不太常用的注解

  • @Lazy:指定Bean是否延遲初始化。默認情況下,Spring會在容器啟動時創(chuàng)建所有的單例Bean,通過設置@Lazy注解可以將Bean的創(chuàng)建推遲到第一次使用時。這對于那些啟動時間較長的應用程序來說非常有用,可以提高應用程序的啟動速度。

  • @DependsOn:指定Bean依賴的其他Bean。如果被依賴的Bean未被創(chuàng)建,則會先創(chuàng)建該Bean。@DependsOn注解可以用來控制Bean的創(chuàng)建順序,確保依賴的Bean在當前Bean之前被創(chuàng)建。

  • @Primary:在多個Bean實現(xiàn)某個接口時,指定默認使用哪個Bean。當一個接口有多個實現(xiàn)類時,可以使用@Primary注解來指定默認使用哪個實現(xiàn)類。如果沒有指定@Primary注解,則需要使用@Qualifier注解來指定使用哪個實現(xiàn)類。

  • @Qualifier:指定使用哪個Bean實現(xiàn)某個接口。當有多個Bean實現(xiàn)同一個接口時,可以使用@Qualifier注解來指定使用哪個Bean。@Qualifier注解需要與@Autowired注解一起使用,在注入Bean時指定使用哪個實現(xiàn)類。

  • @Profile:指定Bean在特定的環(huán)境中才會被創(chuàng)建??梢允褂聾Profile注解來指定Bean在哪些環(huán)境下被創(chuàng)建,例如開發(fā)環(huán)境、測試環(huán)境或生產(chǎn)環(huán)境。

  • @Value:從屬性文件中獲取Bean的屬性值??梢允褂聾Value注解來指定Bean的屬性值。@Value注解可以用來注入簡單類型的值,例如字符串、數(shù)字或布爾值。

  • @RestController:將一個類聲明為RESTful Web服務的控制器??梢允褂聾RestController注解來將一個類聲明為RESTful Web服務的控制器,使其能夠處理HTTP請求并返回JSON或XML格式的數(shù)據(jù)。

  • @ExceptionHandler:處理異常。可以使用@ExceptionHandler注解來處理Controller中的異常,當Controller中拋出異常時,會自動調(diào)用@ExceptionHandler注解中指定的方法來處理異常。

成功是一個長期的過程,需要不斷地努力和堅持。

  • “成功的秘訣在于堅持,堅持,再堅持?!薄獜埖路?/p>

  • “成功不是將來才有的,而是從決定去做的那一刻起,持續(xù)累積而成?!薄⑺诡D·馬丁

  • “只有在經(jīng)歷了漫長跋涉之后,才能登上理想的山巔。”——菲茨杰拉德

  • “成功的關鍵在于我們是否真正熱愛我們所做的事情,是否做到了最好?!薄R綠汀

  • “成功者不是從不失敗,而是能夠從失敗中振作起來?!薄獑讨巍鄣氯A·伯納德·肖

  • “不要害怕失敗,失敗是通向成功的必經(jīng)之路。”——邁克爾·喬丹

成功不是一蹴而就的,它需要我們一步一個腳印地向前走,不斷地嘗試和學習,不斷地改進和完善。在這個過程中,我們可能會遇到挫折和困難,但是只要我們保持信心和勇氣,堅持不懈地努力,最終我們一定會迎來成功的喜悅。


Spring:現(xiàn)代Java開發(fā)的必備框架的評論 (共 條)

分享到微博請遵守國家法律
泗水县| 雷州市| 辉南县| 九龙坡区| 建始县| 绵竹市| 绥棱县| 湘潭县| 蕲春县| 高碑店市| 怀来县| 佛学| 安岳县| 洛宁县| 和林格尔县| 北流市| 安岳县| 大厂| 大方县| 阜南县| 芦溪县| 安陆市| 扎赉特旗| 山丹县| 福建省| 龙海市| 资溪县| 瑞安市| 达拉特旗| 安多县| 抚顺县| 鲁甸县| 上蔡县| 黎城县| 新田县| 新竹县| 新乡县| 井陉县| 云和县| 沙湾县| 石景山区|