2016-03-31 2 views
2

Я получаю исключение NullPointerException Autowiring в контекстеInitialized, может быть, кто-то может мне помочь, спасибо большое.Spring Boot, Autowired имеет значение null в ServletContextListener.contextInitialized

Главный класс

@SpringBootApplication 
@CompnentScan 
public class Application extends SpringBootServletInitializer { 
    public static void main(String[] args) throws Exception { 
    SpringApplication.run(Application.class, args); 
    } 

    @Override 
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 
    return application.sources(Application.class); 
    } 

    @Bean 
    public ProfileAdminListener profileAdminListener() { 
    return new ProfileAdminListener(); 
    } 
} 

контекста сервлета

@WebListener() 
public class ProfileAdminListener implements ServletContextListener { 

private final Timer timer = new Timer(); 

public ProfileAdminListener() { 
    setProperties(); 
} 

private void setProperties() { 
    .... 
} 

@Override 
public void contextDestroyed(ServletContextEvent sce) { 
    timer.cancel(); 
    timer.purge(); 
} 

@Override 
public void contextInitialized(ServletContextEvent sce) { 
    startProtokollTask(); 
} 

private void startProtokollTask() { 
    ProtokollFileWriteTask task = ProtokollFileWriteTask.getInstance(); 
    timer.schedule(task, 0, 10000); 
} 
} 

Задача

@Component 
public class ProtokollFileWriteTask extends TimerTask { 

private static ProtokollFileWriteTask instance = new ProtokollFileWriteTask(); 

@Autowired 
private ProtokollService protokollService; 

private ProtokollFileWriteTask() { 
} 

public static ProtokollFileWriteTask getInstance() { 
    return instance; 
} 

@Override 
public void run() { 
    writeFile(); 
} 

private void writeFile() { 
    protokollService.writeProtokollFile("c:\temp"); <---- prtokollService is null 
} 
} 

После запуска областью применения, я хочу, чтобы начать timetask, но я получаю NullPointerException becuase в protokollservice нулевой. Я думаю, что сервис не был init, прежде чем использовать его.

При использовании обычной конфигурации весны mvc xml это не проблема. Как настроить его весной? Благодарю.

+0

Сработало в примере с springboot страницы ??? – SkorpEN

+0

Возможный дубликат [Почему моя Spring @Autowired поле null?] (Http://stackoverflow.com/questions/19896870/why-is-my-spring-autowired-field-null) – kryger

+1

Через цепочку вызовов вы в конечном счете используйте поле 'instance', которое создается с помощью ключевого слова' new', которое, таким образом, не управляется Spring, поэтому аннотация '@ Autowired' фактически не используется. Вам нужно будет создать экземпляр всех ваших компонентов с помощью Spring, чтобы сделать работу по аутсорсингу. – kryger

ответ

0

Ответ на вопрос Kryger прав, эта проблема в том, что я новый timetask, это не контролируется весной. Большое спасибо.

0

Вы colud создать новый компонент со статическим методом, с помощью, например:

@Component 
public class ProtokollFileWriterTaskCreator { 
    @Autowired 
    ProtokollFileWriteTask bean; 

    public ProtokollFileWriteTask create() { 
    return bean; 
    } 

} 

С другой стороны, измените другой компонент:

@Component 
public class ProtokollFileWriteTask extends TimerTask { 
    @Autowired 
    private ProtokolService protokollService; 

    @Override 
    public void run() { 
    writeFile(); 
    } 

    private void writeFile() { 
    protokollService.writeProtokollFile("c:\\temp"); 
    } 

} 

В классе Weblistener вы должны использовать создатель боб :

@WebListener 
public class ProfileAdminListener implements ServletContextListener { 
    private final Timer timer = new Timer(); 

    @Autowired 
    ProtokollFileWriterTaskCreator timerTaskFactory; 

    public ProfileAdminListener() { 
    setProperties(); 
    } 

    private void setProperties() { 
    //nothing 
    } 

    @Override 
    public void contextDestroyed(ServletContextEvent sce) { 
    timer.cancel(); 
    timer.purge(); 
    } 

    @Override 
    public void contextInitialized(ServletContextEvent sce) { 
    startProtokollTask(); 
    } 

    private void startProtokollTask() { 
    timer.schedule(timerTaskFactory.create(), 0, 10000); 
    } 

} 

проблема заключалась в том, что вы использовали оператор новый создать бобы Это несовместимо с обозначениями @Autowire

Извините за мой плохой английский

+0

Спасибо, г-н Yewen –

Смежные вопросы