Java静态变量注入配置值,工具类使用@Value将信息注入到静态变量中

在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;

}

}

通过@Component和在Setter上打上注解,即可将配置文件的信息注入到静态变量中了.

为什么会出现空指针?

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

AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata

/**

* 解析当前Class被@Autowired标记的成员

* @param clazz

* @return

*/

private InjectionMetadata buildAutowiringMetadata(final Class> clazz) {

List elements = new ArrayList<>();

Class> targetClass = clazz;

// 递归遍历当前类及其所有基类,解析全部注解元信息

do {

final List 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));

}

});

// 省略....

}

static的变量是归属于Class的,而Spring容器上下文只对Java对象进行管理,Spring不鼓励对static变量做注入Bean的操作,因此如果需要在某些工具类中将Bean赋值给静态变量,可以使用构造注入的方式. 或者使用@PostConstruct作为桥梁.

想深入的朋友可以看看这篇文章: 想用@Autowired注入static静态成员?官方不推荐你却还偏要这么做

你可能感兴趣的:(Java静态变量注入配置值)