Spring和null指针异常

时间:2013-09-24 16:21:35

标签: spring hibernate nullpointerexception

我正在尝试这样做:

@Controller    
public class HomeController {

        @Autowired
        private TemplatesService templatesService;    

        public final String TEST = templatesService.getUri();

getUri

@SuppressWarnings("unchecked")
    public String getUri() {

        return (String) sessionFactory.getCurrentSession()
                .createQuery("select uri from Templates WHERE state=1")
                .uniqueResult();
    }

如果我在任何方法中声明TEST,它都能正常工作。但现在我有了这个:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'homeController' defined in file [C:\Users\anton\springsource\vfabric-tc-server-developer-2.8.2.RELEASE\base-instance\wtpwebapps\blog\WEB-INF\classes\net\babobka\blog\controller\HomeController.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [net.babobka.blog.controller.HomeController]: Constructor threw exception; nested exception is java.lang.NullPointerException
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:997)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:943)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:385)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:284)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111) 

我的根背景(我觉得它没有帮助):

    <context:annotation-config />


    <context:component-scan base-package="net.babobka.blog" />
    <mvc:resources mapping="/resources/**" location="/resources/" />
    <cache:annotation-driven />

    <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
        <property name="caches">
            <set>
                <bean
                    class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"
                    p:name="template" />
                <bean
                    class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"
                    p:name="headHunter" />

            </set>
        </property>
    </bean>

    <bean id="converter" class="net.babobka.blog.headHunter.Converter" />


    <bean id="propertyConfigurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
        p:location="/WEB-INF/db/jdbc.properties" />

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close" p:driverClassName="${jdbc.driverClassName}"
        p:url="${jdbc.databaseurl}" p:username="${jdbc.username}" p:password="${jdbc.password}" />
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation">
            <value>/WEB-INF/db/hibernate.cfg.xml</value>
        </property>
        <property name="configurationClass">
            <value>org.hibernate.cfg.AnnotationConfiguration</value>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${jdbc.dialect}</prop>
                <prop key="hibernate.show_sql">${jdbc.show_sql}</prop>
                <prop key="hibernate.connection.useUnicode">true</prop>
                <prop key="hibernate.connection.characterEncoding">UTF-8</prop>
                <prop key="hibernate.connection.charSet">UTF-8</prop>
            </props>
        </property>
    </bean>




    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    <mvc:annotation-driven />
    <tx:annotation-driven />
    <task:annotation-driven />



    <bean id="Backupper" class="net.babobka.blog.backupper.Backupper"></bean>

    <bean id="OldDataRemoval" class="net.babobka.blog.termination.OldDataRemoval"></bean>

    <bean id="HeadHunterImport" class="net.babobka.blog.headHunter.HeadHunterImport"></bean>

    <bean id="urlForwardController"
        class="org.springframework.web.servlet.mvc.UrlFilenameViewController" />

    <bean id="tilesConfigurer"
        class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
        <property name="definitions">
            <list>
                <value>/WEB-INF/tiles.xml</value>
            </list>
        </property>
    </bean>

    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass"
            value="org.springframework.web.servlet.view.tiles2.TilesView" />
    </bean>





</beans>

怎么了?

2 个答案:

答案 0 :(得分:3)

它不起作用,因为当您引用templatesService来设置TEST时,@PostConstruct尚未注入。字段注入仅在对象实例化后才起作用。您需要解决此问题的方法是使用@Controller public class HomeController { @Autowired private TemplatesService templatesService; public String test; @PostConstruct public void init() { this.test = templatesService.getUri(); } 来设置测试。

  @Controller    
  public class HomeController {

    private TemplatesService templatesService;    

    public final String TEST;

    @Autowired
    public HomeController(TemplatesService templatesService) {
        this.templatesService = templatesService;
        this.TEST = templatesService.getUri();
    }

如果你仍想使用final,你可以使用构造函数注入然后设置TEST。

{{1}}

答案 1 :(得分:1)

这是初始化顺序的问题。 Spring在调用bean的构造函数之后会将依赖项注入@Autowired字段,但是在对象构造期间执行字段初始化程序 - 因此在字段自动装配之前。因此,该字段仍为null,这就是为什么尝试调用方法会抛出NullPointerException

备选方案:

  • 通过构造函数注入传递TemplatesService,并从构造函数而不是字段初始值设定项中分配最终字段
  • 继续通过字段注入注入TemplatesService,但将bean的初始化移动到@PostConstruct方法。您必须删除final以安抚编译器。
  • 通过setter注入注入TemplatesService,并在setter中执行必要的初始化。您必须删除final以安抚编译器。