AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

探索Spring Boot中@PostConstruct的魔法

來源: 責編: 時間:2023-12-08 09:14:28 307觀看
導讀前言@postContruct全限定類名是javax.annotation.PostConstruct,可以看出來其本身不是Spring定義的注解,但是Spring提供了具體的實現,所以這篇文章主要分析的是@PostConstruct在Spring項目開發中的功能特性、實現方式和

前言

@postContruct全限定類名是javax.annotation.PostConstruct,可以看出來其本身不是Spring定義的注解,但是Spring提供了具體的實現,所以這篇文章主要分析的是@PostConstruct在Spring項目開發中的功能特性、實現方式和基本工作原理。ZQM28資訊網——每日最新資訊28at.com

功能特性

從@PostConstruct注解的注釋上看,可以了解到以下內容:ZQM28資訊網——每日最新資訊28at.com

1、要在依賴加載后,對象佤用前執行,并且只執行一次;ZQM28資訊網——每日最新資訊28at.com

2、所有支持依賴注入的類都需要支持此方法。即使類沒有請求注入任何的資源,也必須調用被@PostConstruct注解標記的方法;ZQM28資訊網——每日最新資訊28at.com

3、一個類中在一個方法上使用@PostConstruct注解;ZQM28資訊網——每日最新資訊28at.com

4、使用@PostConstruct注解標記的方法不能有參數,除非是攔截器,可以采用攔截器規范定義的InvocationContext對象。ZQM28資訊網——每日最新資訊28at.com

5、使用@PostConstruct注解標記的方法不能有返回值,實際上如果有返回值,也不會報錯,但是會忽略掉;ZQM28資訊網——每日最新資訊28at.com

6、使用@PostConstruct注解標記的方法的權限,public、private、protected都可以;ZQM28資訊網——每日最新資訊28at.com

7、使用@PostConstruct注解標記的方法不能被static修飾,但是final是可以的;ZQM28資訊網——每日最新資訊28at.com

package javax.annotation;import java.lang.annotation.*;import static java.lang.annotation.ElementType.*;import static java.lang.annotation.RetentionPolicy.*;@Documented@Retention (RUNTIME)@Target(METHOD)public @interface PostConstruct {}

但是在在實際的Spring項目中Bean的生命周期里,其執行的時機是:1、Bean的實例化;2、Bean內依賴屬性的注入 ;3、Bean里被@PostConstruct標記的方法;ZQM28資訊網——每日最新資訊28at.com

下面在實現方式里,用一個小例子來驗證一下這個過程;ZQM28資訊網——每日最新資訊28at.com

實現方式

1、定義一個ExampleController類,采用setter的依賴注入的方式,注入exampleService屬性,另外在定義一個myPostConstruct方法用@PostConstruct注解標記;ZQM28資訊網——每日最新資訊28at.com

@RestController@Slf4jpublic class ExampleController {    private ExampleService exampleService;    public ExampleController() {        log.info("----ExampleController無參數構造方法被執行");    }    @Autowired    public void setExampleService(ExampleService exampleService) {        this.exampleService = exampleService;        log.info("----ExampleController類的setExampleService方法被調用");    }    @PostConstruct    public void myPostConstruct(){        log.info("----ExampleController類的myPostConstruct方法被調用");    }}

2、定義ExampleService類ZQM28資訊網——每日最新資訊28at.com

@Service@Slf4jpublic class ExampleService {    public ExampleService() {        log.info("----ExampleService的無參數構造方法被調用");    }}

3、定義一個單元測試,在單元測試中啟動Spring容器;ZQM28資訊網——每日最新資訊28at.com

@Testpublic void test4(){    log.info("----單元測試執行開始");    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.fanfu");    log.info("----單元測試執行完畢");}

單元測試驗證結果:ZQM28資訊網——每日最新資訊28at.com

圖片圖片ZQM28資訊網——每日最新資訊28at.com

從單元測試的執行結果來看,首先,ExampleConstroller被實例化,接著是ExampleService被實例化,然后通過setter依賴注入的方式把ExampleService對象注入到了ExampleConstroller對象中,之后才開始了被@PostConstruct注解標記的myPostConstruct方法的執行。下面就單元測試的結果分析一個@PostConstruct注解的工作原理。ZQM28資訊網——每日最新資訊28at.com

工作原理

@PostConstruct的工作原理的關鍵問題就是:在Spring容器啟動的過程,被@PostConstruct標記的方法是怎么被執行的?ZQM28資訊網——每日最新資訊28at.com

在被@PostConstruct標記的方法上打上斷點,待程序執行的斷點的時候觀察一下方法調用棧信息,這時會發現:ZQM28資訊網——每日最新資訊28at.com

1、Spring容器啟動過程的最后一步,即把需要提前注冊的一些非懶加載的單例Bean時,如ExampleController,注意這時exampleController對象實例化完成,需要注入的exampleService的屬性已經被實例化,且已經注入到exampleController對象中,在BeanPostProcessor接口的擴展方法中,被@PostConstruct標記的方法開始觸發執行,入口位置在AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization。ZQM28資訊網——每日最新資訊28at.com

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)      throws BeansException {   Object result = existingBean;   for (BeanPostProcessor processor : getBeanPostProcessors()) {      Object current = processor.postProcessBeforeInitialization(result, beanName);      if (current == null) {         return result;      }      result = current;   }   return result;}

圖片圖片ZQM28資訊網——每日最新資訊28at.com

那么觸發被@PostConstruct注解標記的方法執行的BeanPostProcessor接口的具體是實現是哪個類呢?通過debug分析,是CommonAnnotationBeanPostProcessor類。ZQM28資訊網——每日最新資訊28at.com

圖片圖片ZQM28資訊網——每日最新資訊28at.com

2、CommonAnnotationBeanPostProcessor類繼承于InitDestroyAnnotationBeanPostProcessor,實際的觸發@PostConstruct標記方法執行的入口是在InitDestroyAnnotationBeanPostProcessor的postProcessBeforeInitialization()ZQM28資訊網——每日最新資訊28at.com

3、InitDestroyAnnotationBeanPostProcessor的postProcessBeforeInitialization()內,邏輯相對比較簡潔,先查詢bean中被@PostConstruct標記的方法,然后再使用java反射來執行這個方法;ZQM28資訊網——每日最新資訊28at.com

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {    //查詢bean中被@PostConstruct標記的方法,相關的信息封在LifecycleMetadata對象的    LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());   try {    //使用java反射執行被@PostConstruct標記的方法      metadata.invokeInitMethods(bean, beanName);   }   catch (InvocationTargetException ex) {      throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());   }   catch (Throwable ex) {      throw new BeanCreationException(beanName, "Failed to invoke init method", ex);   }   return bean;}

圖片圖片ZQM28資訊網——每日最新資訊28at.com

總結

從以上幾步的分析來看,被@PostConstruct標記的方法是怎么被執行的,這個問題回答清楚了。如果面試官問你,你了解@PostContruct注解是怎么工作的嗎?你就可以這么回答他:在Bean實例化、屬性注入后,被@PostConstruct標記的方法是在BeanPostProcessor的擴展方法postProcessBeforeInitialization()觸發執行的,具體實現類是InitDestroyAnnotationBeanPostProcessor,具體的邏輯是:先查詢被@PostConstruct標記的方法,然后使用java反射去執行這個方法。回答完后,如果他不換一個問題的話,把Springboot的擴展點都給他盤一遍。ZQM28資訊網——每日最新資訊28at.com

ZQM28資訊網——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-39509-0.html探索Spring Boot中@PostConstruct的魔法

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 設計之魅:高質量面向對象設計的秘密

下一篇: NUMA架構:CPU和內存性能瓶頸的終結者!

標簽:
  • 熱門焦點
Top