0
点赞
收藏
分享

微信扫一扫

工具类使用@Value将信息注入到静态变量中

墨春 2021-12-29 阅读 62

在spring工程中,我们经常需要使用到配置文件的一些信息,在每个类中定义,可能导致这些信息变得零散。spring给我们提供了一个注解@Value(),使我们可以注入配置文件中的数据。

bootstrap.yml

 jay:
    key: www.baidu.com

如果你想在你的工具类中注入这个变量,那么你可能面临问题,方法是static的,那么你需要使用静态变量作为参数在方法中使用。

错误示范:

public class testUtils{
       @Value("${jay.key}")
       private static String url;
}

正确示范

@Configuration
public class testUtils{
    private static String url;

    @Value("${jay.key}")
    public void setUrl(String url) {
        url= url;
    }
}

为什么会出现空指针?

先说结论: Spring从源码层面不提供对static修饰符的成员变量进行注入.

  • AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata
/**
     * 解析当前Class被@Autowired标记的成员
     * @param clazz
     * @return
     */
    private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
        List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
        Class<?> targetClass = clazz;
        // 递归遍历当前类及其所有基类,解析全部注解元信息
        do {
            final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
            // 收集被@Autowired、@Value标记的Field.
            // 利用反射机制获取给定类中所有的声明字段,获取字段上的注解信息
            // doWithLocalFields->获取当前类的所有Field,每个field执行lambda内的逻辑.
            ReflectionUtils.doWithLocalFields(targetClass, field -> {
                // 此处逻辑较为复杂,通过debug发现如果为被标注的属性,会返回required:true.
                // 大致的意思是这个field是否被特定的注解标记?这里留一个疑问
                AnnotationAttributes ann = findAutowiredAnnotation(field);
                if (ann != null) {
                    // 如果是static属性的成员,Spring不提供支持
                    if (Modifier.isStatic(field.getModifiers())) {
                        if (logger.isInfoEnabled()) {
                            logger.info("Autowired annotation is not supported on static fields: " + field);
                        }
                        return;
                    }
                    // 判断required的状态
                    boolean required = determineRequiredStatus(ann);
                    // 将当前成员添加进currElements
                    currElements.add(new AutowiredFieldElement(field, required));
                }
            });
    // 省略....
    }
举报

相关推荐

0 条评论