Util工具类中将非静态方法改造为静态方法

开发工作中经常需要写一些Util工具类提供给其他地方使用,工具类中的方法一般都要求是static的,便于使用者用ClassName.methodName()直接调用。但是有时候发现有些方法不能使用static修饰,因为他们引用了bean,bean的加载顺序是迟于静态属性。这里简单记录下把工具类中的非静态方法改造为静态方法;

如下是最近写的一个工具类,可以看到工具类提供的getNewAccessToken()方法为非静态方法,如果加了static会报错,因为这里使用到了redisTemplateInstance实例bean了,静态方法中不能引用非静态属性

@Slf4j
@Component
@RefreshScope
public class XXXXTokenUtil {


    @Value("${XXX.grant.clientId}")
    private String clientIdInstance;

    @Value("${XXX.grant.clientSecret}")
    private String clientSecretInstance;

    @Value("${XXX.grant.grantType}")
    private String grantTypeInstance;

    @Value("${XXX.grant.username}")
    private String usernameInstance;

    @Value("${XXX.grant.password}")
    private String passwordInstance;

    @Value("${XXX.domain}")
    private String domainInstance;

    private static final String CACHED_TOKEN_KEY = "XXX_TOKEN";

    @Autowired
    private RedisTemplate<String, String> redisTemplateInstance;

    public  String getAccessToken() {

        String cache = redisTemplate.opsForValue().get(CACHED_TOKEN_KEY );
        if (StringUtils.isNotEmpty(cache)) {
            return cache;
        }

        XXX newAccessToken = getNewAccessToken();
        redisTemplate.opsForValue().set(CACHED_TOKEN_KEY, newAccessToken.getAccessToken(), newAccessToken.getExpiresIn() - 300, TimeUnit.MILLISECONDS);
        return newAccessToken.getAccessToken();
    }

    private XXXXToken getNewAccessToken() {

        String response = HttpUtil.createPost(domain + "/auth/oauth/token")
                .form("client_id", clientId)
                .form("client_secret", clientSecret)
                .form("username", username)
                .form("password", password)
                .form("grant_type", grantType)
                .timeout(1000 * 10)
                .execute()
                .body();

        if (StringUtils.isEmpty(response)) {
            log.error("get access token from xxxis empty.");
            throw new BusinessException("获取访问token结果为空");
        }
        return JacksonUtil.convertToObject(response, XXX.class);
    }
}

改造为静态方法:
这里使用延迟的思想,工具类静态方法中使用的属性全部改造为静态属性,只是属性值为空,在bean加载最后阶段,借助Spring提供的扩展机制延迟赋值,这个延迟是无需担心的,他是在bean初始化完成后执行的,这个时间点是早于bean可用时间点的。这里使用的是InitializingBean完成延迟赋值的,也可以借助其他的方法,如@PostConstruct注解,Aware相关接口,PostProcessor接口等。

需要注意的是如下工具类注入的nacos配置属性,只会在首次加载时读取,后续修改是不会动态变化的。如果静态配置也想一起动态变化,可能需要去监听nacos的通知事件额外处理,这里暂未研究过。

@Slf4j
@Component
// @RefreshScope
public class XXXXTokenUtil implements InitializingBean {

    private static String clientId;

    private static String clientSecret;

    private static String grantType;

    private static String username;

    private static String password;

    private static String domain;

    private static RedisTemplate<String, String> redisTemplate;

    @Value("${XXX.grant.clientId}")
    private String clientIdInstance;

    @Value("${XXX.grant.clientSecret}")
    private String clientSecretInstance;

    @Value("${XXX.grant.grantType}")
    private String grantTypeInstance;

    @Value("${XXX.grant.username}")
    private String usernameInstance;

    @Value("${XXX.grant.password}")
    private String passwordInstance;

    @Value("${XXX.domain}")
    private String domainInstance;

    private static final String CACHED_TOKEN_KEY = "XXXX_TOKEN";

    @Autowired
    private RedisTemplate<String, String> redisTemplateInstance;

    @Override
    public void afterPropertiesSet() {
        clientId = clientIdInstance;
        clientSecret = clientSecretInstance;
        grantType = grantTypeInstance;
        username = usernameInstance;
        password = passwordInstance;
        domain = domainInstance;
        redisTemplate = redisTemplateInstance;
    }


    public static String getAccessToken() {

        String cache = redisTemplate.opsForValue().get(CACHED_TOKEN_KEY);
        if (StringUtils.isNotEmpty(cache)) {
            return cache;
        }

        XXXXX newAccessToken = getNewAccessToken();
        redisTemplate.opsForValue().set(CACHED_TOKEN_KEY, newAccessToken.getAccessToken(), newAccessToken.getExpiresIn() - 300, TimeUnit.MILLISECONDS);
        return newAccessToken.getAccessToken();
    }

    private static XXXX getNewAccessToken() {

        String response = HttpUtil.createPost(domain + "/auth/oauth/token")
                .form("client_id", clientId)
                .form("client_secret", clientSecret)
                .form("username", username)
                .form("password", password)
                .form("grant_type", grantType)
                .timeout(1000 * 10)
                .execute()
                .body();

        if (StringUtils.isEmpty(response)) {
            log.error("get access token from XXX is empty.");
            throw new BusinessException("获取访问token结果为空");
        }

        return JacksonUtil.convertToObject(response, XXXXX.class);
    }

}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值