如何解决Autowired annotation is not supported on static fields问题给静态变量赋值

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/russle/article/details/83958780

问题由来:
springboot项目中使用加解密功能,密钥在application.properties文件中配置,因此加解密服务类需要读取该变量,为了提高效率,加解密服务类静态初始化的时候就生成了SecretKeySpec(不是每次调用加密或者解密方法时再生成SecretKeySpec)。 如果我们使用如下方式读取配置文件,然后赋值给mySecretKey, springboot就会报Autowired annotation is not supported on static fields

public class EnDecryptionServiceImpl implements IEnDecryptionService{
    @Value("${mySecretKey}")
    private static String mySecretKey;
    ...
    static {
        try {
            byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
            ivspec = new IvParameterSpec(iv);
            cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            ...
            这里用到了mySecretKey。 因此必须把mySecretKey设置为static
        }
        catch (NoSuchPaddingException ex) {
            log.error("no PKCS5Padding in the jvm", ex);
        }
        catch (NoSuchAlgorithmException ex) {
            log.error("no AES algorithm in the jvm", ex);
        }
        catch (Exception ex) {
            log.error("generic exception", ex);
        }
    }
    ...

问题表现:
程序日志提示Autowired annotation is not supported on static fields, 并且原先读取到的mySecretKey为null。

两种解决方法:
1, 给EnDecryptionServiceImpl 增加一个setMySecretKey,然后在该set方法上面加@Autowired即可。
注意:因为我的setMySecretKey(String secretKey)需要一个字符串bean, 因此额外添加一个config生成一个String bean。

    @Autowired
    public void setMySecretKey(String secretKey) {
        mySecretKey = secretKey;
        log.info("set mySecretKey={}", mySecretKey);
        init();
    }

生成String bean

@Configuration
@Slf4j
public class MySecretConfig {
    @Value("${mySecretKey:defatulValue}")
    private  String mySecretKey;

    @Bean
    public String getMySecretKeyFromCfg() {
        return mySecretKey;
    }
}

2, 或者另外一种解决办法,在EnDecryptionServiceTwoImpl的构造函数上加上@Autowired, 同时构造的参数是String secretKey。

    /*
    第二种解决Autowired annotation is not supported on static fields的方式
     */

    @Autowired
    public void EnDecryptionServiceTwoImpl(String secretKey) {
        mySecretKey = secretKey;
        log.info("set mySecretKey={}", mySecretKey);
        init();
    }

通过日志可以发现,EnDecryptionServiceImpl 类的静态变量mySecretKey已经顺利获取到application.properteis中的值了。

完整的代码在[这里](https://github.com/yqbjtu/springboot/tree/master/CLRDemo)。您只需要关注EnDecryptionServiceImpl 类的静态变量如何被赋值的,其余的只是springboot为了演示效果而写的完整程序的代码。

以上两种办法在我的代码中都有,经过验证切实可用。

猜你喜欢

转载自blog.csdn.net/russle/article/details/83958780