@PostConstruct注解好多人以為是Spring提供的。其實是Java自己的注解。
Java中該注解的說明:@PostConstruct該注解被用來修飾一個非靜態的void()方法。被@PostConstruct修飾的方法會在服務器加載Servlet的時候運行,並且只會被服務器執行一次。PostConstruct在構造函數之后執行,init()方法之前執行。
通常我們會是在Spring框架中使用到@PostConstruct注解 該注解的方法在整個Bean初始化中的執行順序:
Constructor(構造方法) -> @Autowired(依賴注入) -> @PostConstruct(注釋的方法)
實戰:在靜態方法中調用依賴注入的Bean中的方法。
如果想在生成對象時完成某些初始化操作,而偏偏這些初始化操作又依賴於依賴注入,那么久無法在構造函數中實現。為此,可以使用@PostConstruct注解一個方法來完成初始化,@PostConstruct注解的方法將會在依賴注入完成后被自動調用。
@PostConstruct注解的方法將會在依賴注入完成后被自動調用。
-
因為當調用構造函數時,bean還沒有初始化-即沒有注入依賴項。在
@PostConstruct
方法完全初始化bean,您可以使用依賴項。 -
因為這是保證在bean生命周期中只調用一次此方法的契約。一個bean可能會在其內部工作過程中被容器多次實例化(雖然不太可能),但它保證
@PostConstruct
只會被調用一次。
package com.example.studySpringBoot.util; import com.example.studySpringBoot.service.MyMethorClassService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; @Component public class MyUtils { private static MyUtils staticInstance = new MyUtils(); @Autowired private MyMethorClassService myService; @PostConstruct public void init(){ staticInstance.myService = myService; } public static Integer invokeBean(){ return staticInstance.myService.add(10,20); }
考慮以下情況:
public class Car { @Inject private Engine engine; public Car() { engine.initialize(); } ...}
由於CAR必須在字段注入之前實例化,因此在構造函數執行期間注入點引擎仍然為空,從而導致NullPointerException。
這個問題可以通過以下兩種方法來解決Java的JSR-330依賴注入Java@PostConstruct方法注釋的構造函數注入或JSR 250公共注釋。
@PostConstruct
JSR-250定義了一組常見的注釋,這些注釋已經包含在JavaSE 6中。
PostConstruct注釋用於在執行任何初始化時執行依賴注入后需要執行的方法。必須在類投入服務之前調用此方法。所有支持依賴注入的類都必須支持此注釋。
JSR-250章。2.5 javax.notation.PostConstruct
@PostConstruct注釋允許在實例化並執行所有注入之后執行方法的定義。
public class Car { @Inject private Engine engine; @PostConstruct public void postConstruct() { engine.initialize(); } ...}
代碼被移到帶有@PostConstruct注釋的方法中,而不是在構造函數中執行初始化。
后構造方法的處理是一個簡單的問題,即查找所有帶有@PostConstruct注釋的方法,然后依次調用它們。
private void processPostConstruct(Class type, T targetInstance) { Method[] declaredMethods = type.getDeclaredMethods(); Arrays.stream(declaredMethods) .filter(method -> method.getAnnotation(PostConstruct.class) != null) .forEach(postConstructMethod -> { try { postConstructMethod.setAccessible(true); postConstructMethod.invoke(targetInstance, new Object[]{}); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { throw new RuntimeException(ex); } });}
后構造方法的處理必須在實例化和注入完成后執行。
轉載:https://blog.csdn.net/qq360694660/article/details/82877222