@PostConstruct及跳坑記錄


@PostConstruct及跳坑記錄

@PostConstruct的一個控制方法加載順序的一個注解,如果使用恰當,可以方便解決很多問題,如果使用不當,也會出現一些認為莫名其妙的問題。

這里說一下@PostConstruct和@Autowired 一起使用的一些問題。

首先@PostConstruct是javax.annotation包下的注解,並不是Spring提供的。看一下servlet中的加載順序。

graph TB 服務器加載Sevlet-->Servlet-Construct Servlet-Construct-->PostConstruct PostConstruct-->init init-->service service-->destroy destroy-->PreDestroy PreDestroy-->服務器卸載sevlet完畢

再來看一下Spring中的加載順序:

graph LR Construct-->Autowired Autowired-->PostConstruct
  • @Autowired是在構造方法執行之后開始執行的
  • @PostConstruct是在依賴注入完成后開始執行

舉一個跳坑的例子

場景

兩個service:Aservice和Bservice,一個bean:Cbean;
在Bservice中的@PostConstruct方法中動態注入一個對象Cbean,Aservice中需要依賴Cbean。

跳坑演示

public class Cbean {
    private int id;
    private String name;
}

Bservie中的一個PostConstruct方法動態注冊Cbean到spring中

@Component
public class Bservie {
    @Autowired
    private ApplicationContext context;

    @PostConstruct
    public void init() {
        Cbean c = new Cbean();
        c.setId(1);
        c.setName("name");
        //獲取BeanFactory
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) context.getAutowireCapableBeanFactory();
        //動態注冊bean.
        defaultListableBeanFactory.registerSingleton("cbean",c);
    }
}

Aservice中需要注入Cbean

@Component
public class Asevice {
    @Autowired
    private Cbean cbean;
    
    @Autowired
    private Bservie bservie;
}

這里的AService的加載順序為:構造器-->Autowired Cbean;

此時Bservice中的PostConstruct還沒有觸發執行,所以spring池中沒有Cbean,自然拋出異常:

Field cbean in com.xplan.testpostconstruct.Asevice required a bean of type 'com.xplan.testpostconstruct.Cbean' that could not be found.

當然,如Aservice中有多個Autowired,加載順序是從上到下的。

這個困局的解法只需要把Aservice中的兩個屬性調整下順序即可,這樣就先加載Bservie,在創建Bservie的過程中會觸發PostConstruct的方法,自然此局就解了。

@Component
public class Asevice {

    @Autowired
    private Bservie bservie;

    @Autowired
    private Cbean cbean;

}

通過這個示例,可以體會一下這些注解之間的微妙關系。

源碼鏈接:https://gitee.com/chengluchao/graphql-clc/tree/master/test-post-construct/src/main/java/com/xplan/testpostconstruct

世界上所有的坑都是自己的無知造成的,想要避坑,就得不斷提高自己的道行。

CLC


免責聲明!

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



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