@PostConstruct注解


@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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM