Spring @Value注解不生效问题排查

排查问题原因

如下代码所示,我想要载构造函数里面使用@Value注解配置的demo.name但是发现一直是null

@Service
public class DemoService {

    @Value("demo.name")
    public String name;

    public DemoService() {
        System.out.println("name = " + name);
    }
 }

原来这跟Bean生命周期有关系

Bean创建时先创建一个对象:一般调用无参构造函数new一个对象,也就是上述代码的new DemoService()

然后再填充属性

Bean生命周期如下

1、实例化Bean对象,调用构造函数,此时属性一般都为null

2、设置对象属性

3、检查Aware相关接口,如BeanNameAware#setBeanNameBeanFactoryAware#setBeanFactory

4、BeanPostProcessor#postProceBeforeInitialization方法前置处理

5、调用InitializingBean#afterPropertiesSet方法

6、调用beaninit-method

7、BeanPostProcessor#postProcessAfterInitialization后置处理

8、注册必要的Destruction相关回调接口

9、使用Bean

10、是否实现DisposableBean接口,如果实现则调用他的destory接口

11、调用beandestroy-method

下面提供2种方式来解决问题:

1、使用构造函数解决问题

2、使用@PostConstruct注解解决问题

使用构造函数解决问题

理解问题之后我们就可以解决问题了,下面是一种解决方案,在构造函数之前传参数之前进行注入

@Service
public class DemoService implements BeanNameAware, BeanFactoryAware, InitializingBean {

    @Value("demo.name")
    public String name;

    public DemoService(@Value("demo.name") String name) {
        System.out.println("name = " + name);
    }
}

使用@PostConstruct注解解决问题

上述代码为null的问题,可以使用@PostConstruct注解修改为如下

@Service
public class DemoService {

    @Value("demo.name")
    public String name;

    public DemoService() {
    }

    @PostConstruct
    public void init() {
        System.out.println("name = " + name);
    }
}

@PostConstruct 执行时机

1 、@PostConstruct注解在BeanNameAware#setBeanNameBeanFactoryAware#setBeanFactory执行完毕之后执行。

2、@PostConstruct注解在(BeanPostProcessor#postProcessAfterInitialization)之前开始执行

使用@PostConstruct注意事项:

1、只有一个非静态方法能使用此注解
2、被注解的方法不得有任何参数
3、被注解的方法返回值必须为void
4、被注解方法不得抛出已检查异常
5、此方法只会被执行一次

你可能感兴趣的:(Spring @Value注解不生效问题排查)