1:问题描述
配置文件application.yml:
person.name: nobody
person.age: 20
实体类Person:
package com.nobody.pojo.entity;
import java.io.Serializable;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Person implements Serializable {
/**
*
*/
private static final long serialVersionUID = -8245392957106320519L;
@Value("${person.name}")
private static String name;
private static String age;
@Value("${person.age}")
public void setAge(String age) {
Person.age = age;
}
public void setName(String name) {
Person.name = name;
}
public static String getName() {
return name;
}
public static String getAge() {
return age;
}
}
测试接口类DemoController:
package com.nobody.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.nobody.ehr.pojo.entity.Person;
@RequestMapping("demo")
@RestController
public class DemoController {
@GetMapping
public String demo() {
System.out.println("name:" + Person.getName() + ", age:" + Person.getAge());
return "";
}
}
测试结果:
@Value注解放在属性上注入值失败,而@Value放在setter方法上(注意,该方法也不能是静态方法)注入成功。
name:null, age:20
2:分析
启动日志:
[19:37:45] INFO [restartedMain] o.s.b.f.a.AutowiredAnnotationBeanPostProcessor
- Autowired annotation is not supported on static fields: private static java.lang.String com.nobody.pojo.entity.Person.name
源码分析:
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
ReflectionUtils.doWithLocalFields(targetClass, field -> {
AnnotationAttributes ann = findAutowiredAnnotation(field);
if (ann != null) {
//这里对静态属性注入做了过滤
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
});
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
//这里对静态方法做了过滤
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static methods: " + method);
}
return;
}
if (method.getParameterCount() == 0) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation should only be used on methods with parameters: " +
method);
}
}
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return new InjectionMetadata(clazz, elements);
}
3:结论
从源码上发现,理论上spring是可以对静态域注入的,只是spring没有这样做,它认为依赖注入发生的时段是在实例的生命周期,而不是类的生命周期。