前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。
?
1. 關于注解?PostConstruct?
public @interface PostConstructPostConstruct 注釋用于在依賴關系注入完成之后需要執行的方法上,以執行任何初始化。
應用 PostConstruct 注釋的方法必須遵守以下標準:1)該方法不得有參數,除非是在 EJB 攔截器 (interceptor) 的情況下。
根據 EJB 規范的定義,在這種情況下它將帶有一個 InvocationContext 對象 ;2)該方法的返回類型必須為 void;3)該方法不得拋出已檢查異常;4)應用 PostConstruct 的方法可以是 public、protected、package private 或 private;5)除了應用程序客戶端之外,該方法不能是 static;6)該方法可以是 final;7)如果該方法拋出未檢查異常,那么不得將類放入服務中,除非是能夠處理異常并可從中恢復的 EJB。
2.? @PostConstruct 和 @PreConstruct
從Java EE5規范開始,Servlet增加了兩個影響Servlet生命周期的注解(Annotation):@PostConstruct和@PreConstruct。
這兩個注解被用來修飾一個非靜態的void()方法.? 而且這個方法不能有拋出異常聲明。
@PostContruct是spring框架的注解,在方法上加該注解會在項目啟動的時候執行該方法,也可以理解為在spring容器初始化的時候執行該方法。
?1)@PostConstruct修飾的方法會在服務器加載Servlet的時候運行,且只會被服務器調用一次,類似于Serclet的inti()方法。? ?被@PostConstruct修飾的方法會在構造函數之后,init()方法之前運行。
?2) @PreConstruct修飾的方法會在服務器卸載Servlet的時候運行,且只會被服務器調用一次,類似Servlet的destroy()方法。被@PreConstruct修飾的方法會在destroy()方法之后運行,在Servlet被徹底卸載之前。
?3)用法:
@PostConstructpublic void someMethod(){}或者public @PostConstruct void someMethod(){}
4)作用:
1.spring項目加載數據字典@PostConstruct 注解的方法在項目啟動的時候執行這個方法,也可以理解為在spring容器啟動的時候執行,可作為一些數據的常規化加載,比如數據字典之類的。2.spring項目的定時任務spring 自帶的 @schedule 無開關,項目啟動總會啟動一個線程;Java 的 timer 可設置開關,自由控制,關閉時不會啟動線程;但 timer 也需要一個啟動類,如放到main函數里啟動,這樣代碼的耦合性高。?綜上:使用 PostConstruct? 干凈、方便。
3.? 啟動速度
?注解多少會影響服務器的啟動速度。服務器在啟動的時候,會遍歷Web應用的WEB-INF/classes下的所有class文件與WEB-INF/lib下的所有jar文件,以檢查哪些類使用了注解。如果程序中沒有使用任何注解,可以在web.xml中設置<web-app>的metadatacomplete屬性為true來關掉服務器啟動時的例行檢查。
4.? 執行順序
思路 1)
被@PostConstruct 修飾的方法會在服務器加載Servlet的時候運行,并且只會被服務器執行一次。PostConstruct在構造函數之后執行,init()方法之前執行。PreDestroy()方法在destroy()方法執行后執行。
執行順序
另外,spring中Constructor、@Autowired、@PostConstruct的順序
從依賴注入的字面意思可知,要將對象p注入到對象a,那么首先就必須得生成對象p與對象a,才能執行注入。所以,如果一個類A中有個成員變量p被@Autowired注解,那么@Autowired注入是發生在A的構造方法執行完之后的。
如果想在生成對象時候完成某些初始化操作,而偏偏這些初始化操作又依賴于依賴注入,那么就無法在構造函數中實現。為此,可以使用@PostConstruct注解一個方法來完成初始化,@PostConstruct注解的方法將會在依賴注入完成后被自動調用。
Constructor >> @Autowired >> @PostConstruct
思路 2)
從 jvm 類加載時機來看?
JVM 在加載階段通過類的全路徑找到該類并把類的信息加載到JVM的方法區,
--> 在堆區實例化有關 java.lang.Class 對象,作為方法區中這個類的信息的入口;
--> 在連接階段,為類的靜態變量 logClinet 分配內存并賦予 JVM 默認初始值 null;
因為注解@PostConstruct的緣故,在類初始化之前會先加載該使用該注解的方法,而后再執行類的初始化。
即加載順序為:
? ? 構造方法? ——> @Autowired —— > @PostConstruct ——> 靜態方法?
?
轉自:https://www.cnblogs.com/YuyuanNo1/p/8184003.html
https://www.jianshu.com/p/98cf7d8b9ec3
https://blog.csdn.net/u014515854/article/details/78832790
https://blog.csdn.net/qq_37636695/article/details/84791468
https://www.jianshu.com/p/aba99a49a459