天天看點

@postconstruct注解方法沒有執行[email protected]注解,你該好好看看

@postconstruct注解方法沒有執行[email protected]注解,你該好好看看

在最近的工作中,get到一個很實用的注解,分享給諸位。

痛點

做過微信或支付寶支付的童鞋,可能遇到過這種問題,就是填寫支付結果回調,就是在支付成功之後,支付寶要根據我們給的位址給我們進行通知,通知我們使用者是否支付成功,如果成功我們就要去處理下面相應的業務邏輯,如果在測試服務,那麼這個回調位址我們就需要填寫測試服務的,如果釋出到線上那麼我們就需要改成線上的位址。

針對上面的場景,我們一般都會通過如下的方式,進行一個動态配置,不需要每次去改,防止出現問題。

public class PayTest {

    @Value("${spring.profiles.active}")
    private String environment;

    public Object notify(HttpServletRequest request) {

        if ("prod".equals(environment)) {
            // 正式環境
        } else if ("test".equals(environment)) {

            // 測試環境
        }
        return "SUCCESS";
    }
}
           

上面的代碼看起來沒有一點問題,但是身為搬磚的我們咋可能這樣搬,姿勢不對呀!

問題:

擴充性太差

,如果這個參數我們還需要在别的地方用到,那麼我們是不是還要使用@Value的注解擷取一遍,假如有天我們的leader突然說嗎,test這個單詞看着太low了,換個高端一點的,換成dev,那麼我們是不是要把項目中所有的test都要改過來,如果少還好,要是很多,那我們怕不是涼了。

是以我們能不能将這些配置參數搞成一個全局的靜态變量,這樣的話我們直接飲用就好了,哪怕到時候真的要改,那我也隻需要改動一處就好了。

注意大坑

有的朋友可能就比較自信了,那我直接加個static修飾下不就好了,如果你真是打算這樣做,那你就準備卷好鋪蓋走人吧。直接加static擷取到的值其實是一個null,至于原因,大家複習下類以及靜态變量變量的加載順序。

@PostConstruct注解

那麼既然說出了問題,肯定就有解決方法,不然你以為我跟你玩呢。

首先這個注解是由Java提供的,它用來修飾一個非靜态的void方法。它會在伺服器加載Servlet的時候運作,并且隻運作一次

改造:

@Component
public class SystemConstant {

    public static String surroundings;

    @Value("${spring.profiles.active}")
    public String environment;

    @PostConstruct
    public void initialize() {
        System.out.println("初始化環境...");
        surroundings = this.environment;
    }
}
           

結果:

我們可以看到在項目啟動的時候進行了初始化

@postconstruct注解方法沒有執行[email protected]注解,你該好好看看

到這裡我們已經可以拿到目前運作的環境是測試還是正式,這樣就可以做到動态配置

@postconstruct注解方法沒有執行[email protected]注解,你該好好看看

最後想說

其實這個注解遠不止這點用處,像我之前寫的Redis工具類,我使用的是RedisTemplate操作Redis,導緻寫出來的方法沒辦法用static修飾,每次使用Redis工具類隻能先注入到容器然後再調用,使用了這個注解就可以完美的解決這種尴尬的問題。代碼如下。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * @ClassName RedisUtil
 * @Description TODO
 * @Auther bingfeng
 * @Date 2019/7/4/004 17:14
 * @Version 1.0
 */
@Component
public class RedisUtil {

    private static RedisTemplate<Object, Object> redisTemplates;

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @PostConstruct
    public void initialize() {
        redisTemplates = this.redisTemplate;
    }

    /**
     * 添加元素
     *
     * @param key
     * @param value
     */
    public static void set(Object key, Object value) {

        if (key == null || value == null) {
            return;
        }
        redisTemplates.opsForValue().set(key, value);
    }
}
           

繼續閱讀