天天看點

【Spring】autowired NullPointerException

代碼:

@Service
public class Api {

    @Autowired
    private ServiceA serviceA;

    private String name = serviceA.getName();

}

@Service
public class ServiceA {

    public String getName(){
        return "";
    }
}


public static void main(String args[]) {
     ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class);
}
           

報錯:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'api' defined in file [/Users/miracle/test/mvn/test_spring/target/classes/com/abc/api.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.abc.api]: Constructor threw exception; nested exception is java.lang.NullPointerException

    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1076)

    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1021)

    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)

    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)

    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)

    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)

    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)

    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)

    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700)

    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)

    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)

    at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:84)

    at Main.main(Main.java:40)

Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.abc.api]: Constructor threw exception; nested exception is java.lang.NullPointerException

    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:164)

    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:89)

    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1069)

    ... 12 more

Caused by: java.lang.NullPointerException

    at com.abc.api.<init>(api.java:12)

    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)

    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)

    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)

    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:148)

    ... 14 more

這個錯是因為不了解springbean的周期導緻的。

Api類中,直接在成員屬性上指派是最先執行的,早于構造器。而spring的ioc容器的執行個體化bean以及屬性注入是在構造器之後的,而postConstruct是在屬性注入之後執行的。是以getName方法的調用一定是NPE的。

解決辦法,将name=getName的調用放在postConstruct之中。