请比较两个代码片段并解释为什么一个工作而另一个工作没有

时间:2013-10-22 14:29:10

标签: java spring spring-mvc dependency-injection

第一个片段(不起作用)

配置:

@Configuration
public class UiConfig {
    @Bean //if i doesn't write this bean  result will not change
    ApplicationWebListener getApplicationWebListener(){
        return new ApplicationWebListener();
    }
}   

监听器:

@WebListener
public class ApplicationWebListener implements ServletContextListener {
    @Autowired
    DatabaseHelper databaseHelper;

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        System.out.println("ServletContextListener destroyed");
    }

    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        System.out.println("ServletContextListener started");
        databaseHelper.fillEmptyTables();
    }
}

结果:

java.lang.NullPointerException
    at com.epam.hhsystem.web.controllers.ApplicationWebListener.contextInitialized(ApplicationWebListener.java:24)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4887)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5381)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)

第二段:

配置:

@Configuration
public class UiConfig {
    @Bean//if I doesn't write this bean MyApplicationListener code doesn't execute
    MyApplicationListener getMyApplicationListener(){
        return new MyApplicationListener();
    }
}

监听器:

public class MyApplicationListener implements
        ApplicationListener<ContextRefreshedEvent> {

    @Autowired
    DatabaseHelper databaseHelper;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {

        databaseHelper.fillEmptyTables();
    }

}

结果 - 方法调用和良好的工作。

DatabaseHelper:

@Component    
public class DatabaseHelper {
        @Autowired
        UtilService utilService;

        public  void fillEmptyTables(){
            if(!isSkillsInDatabase()){
                utilService.addGeneratedSkill();
            }
            if(!isEventTypesInDatabase()){
                utilService.addGeneratedEventType();
            }
            if(!isEventStatusesInDatabase()){
                utilService.addGeneratedEventStatus();
            }

        }
        public  boolean isSkillsInDatabase(){
            return utilService.getAllSkills().size() != 0; 
        }
        public  boolean isEventStatusesInDatabase(){
            return utilService.getAllEventStatuses().size() != 0; 
        }
        public  boolean isEventTypesInDatabase(){
            return utilService.getAllEventTypes().size() != 0; 
        }
    }

你能解释一下这些情况吗?

1 个答案:

答案 0 :(得分:1)

查看堆栈跟踪

java.lang.NullPointerException
    at com.epam.hhsystem.web.controllers.ApplicationWebListener.contextInitialized(ApplicationWebListener.java:24)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4887)

监听器由容器启动。 @WebListener注释告诉Servlet容器实例化ApplicationWebListener类。 这不是Spring托管bean。因此,Spring不会将任何内容自动装入其中,DatabaseHelper字段仍为null

这个bean

@Bean //if i doesn't write this bean  result will not change
ApplicationWebListener getApplicationWebListener(){
    return new ApplicationWebListener();
}

将保留在您的上下文中,根本不会被容器使用,因为它未在容器中注册。

您的第二个代码段是一个完全不相关的用例。