天天看點

【了解】PostConstruct注解

@PostConstruct注解好多人以為是Spring提供的。其實是Java自己的注解。

Java中該注解的說明:@PostConstruct該注解被用來修飾一個非靜态的void()方法。被@PostConstruct修飾的方法會在伺服器加載Servlet的時候運作,并且隻會被伺服器執行一次。PostConstruct在構造函數之後執行,init()方法之前執行。

通常我們會是在Spring架構中使用到@PostConstruct注解 該注解的方法在整個Bean初始化中的執行順序: 

Constructor(構造方法) -> @Autowired(依賴注入) -> @PostConstruct(注釋的方法)

 通過@PostConstruct注解能夠通過一種更友好的方式将配置進行導入,代碼如下:

/**
 * 引導類
 */
@Configuration
public class BootstrapConsts {
    
    @Value("${file.client.type}")
    private String fileClientType;
       
    @Value("${file.oss.endPoint}")
    private String endPoint;
 
    @Value("${file.oss.accessKeyId}")
    private String accessKeyId;
    
    @Value("${file.oss.accessKeySecret}")
    private String accessKeySecret;
 
    @Value("${file.oss.bucketName}")
    private String bucketName;
 
    @Value("${file.oss.rootDir}")
    private String rootDir;
    
    /**
     * 檔案用戶端類型
     */
    public static String file_client_type;
    /**
     * OSS位址(不同伺服器,位址不同)
     */
    public static String end_point;
    /**
     * OSS鍵id(去OSS控制台擷取)
     */
    public static String access_key_id;
    /**
     * OSS秘鑰(去OSS控制台擷取)
     */
    public static String access_key_secret;
    /**
     * OSS桶名稱(這個是自己建立bucket時候的命名)
     */
    public static String bucket_name;
    /**
     * OSS根目錄
     */
    public static String root_dir;
    
    @PostConstruct
    private void initial() {
        file_client_type = fileClientType;
        end_point = endPoint;
        access_key_id = accessKeyId;
        access_key_secret = accessKeySecret;
        bucket_name = bucketName;
        root_dir = rootDir;
    }
}      

寫法有如下兩種方式:

@PostConstruct
public void method(){}
 
public @PostConstruct void method(){}      

被@PostConstruct修飾的方法會在伺服器加載Servlet的時候運作,并且隻會被伺服器調用一次,類似于Serclet的init()方法。被@PostConstruct修飾的方法會在構造函數之後,init()方法之前運作。

被@PreDestroy修飾的方法會在伺服器解除安裝Servlet的時候運作,并且隻會被伺服器調用一次,類似于Servlet的destroy()方法。被@PreDestroy修飾的方法會在destroy()方法之後運作,在Servlet被徹底解除安裝之前。

【了解】PostConstruct注解

伺服器加載Servlet過程:

另外,spring中Constructor、@Autowired、@PostConstruct的順序:

其實從依賴注入的字面意思就可以知道,要将對象B注入到對象A,那麼首先就必須得生成對象A和對象B,才能執行注入。是以,如果一個類A中有個成員變量b被@Autowried注解,那麼@Autowired注入是發生在A的構造方法執行完之後的。

如果想在生成對象時完成某些初始化操作,而偏偏這些初始化操作又依賴于依賴注入,那麼久無法在構造函數中實作。為此,可以使用@PostConstruct注解一個方法來完成初始化,@PostConstruct注解的方法将會在依賴注入完成後被自動調用。

Constructor >> @Autowired >> @PostConstruct

@Component
public class A {
 
    @Autowired
    private B b;
 
    public A() {
        System.out.println("執行A的構造方法,此時b還未被注入: b = " + b);
    }
 
    @PostConstruct
    private void init() {
        System.out.println("@PostConstruct将在依賴注入完成後被自動調用: b = " + b);
    }
}
 
@Component
public class B {
    public B(){
        System.out.println("執行B的構造方法");
    }
}      

測試類:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:application-context.xml"})
public class MessageTest {
 
    @Resource
    A a;
 
    @Test
    public void testAB(){
    }
}      

執行testAB()方法結果:

執行A的構造方法,此時b還未被注入: b = null
執行B的構造方法
@PostConstruct将在依賴注入完成後被自動調用: b = com.nss.B@51841ac6      

通過以上結果可以看出:被@PostConstruct注解的方法将在該類中所有注入操作完成之後執行。

繼續閱讀