我正在尝试控制上下文加载过程。正如我在Spring参考文档中所读到的,我决定使用Spring提供的Phased接口。
启动时,相位最低的对象首先开始,然后开始 停止,遵循相反的顺序。因此,一个对象 实现SmartLifecycle并返回其getPhase()方法 Integer.MIN_VALUE将是第一个开始和最后一个 停。在光谱的另一端,相位值为 Integer.MAX_VALUE表示应该启动该对象 最后一次停止(可能是因为它取决于其他进程 要跑步了。在考虑相位值时,它也很重要 要知道任何"正常"的默认阶段。生命周期对象 没有实现SmartLifecycle会为0.因此,任何负面的 阶段值表示对象应该在那些之前开始 标准组件(并在它们之后停止),反之亦然 正相值。
public interface Phased {
int getPhase();
}
public interface SmartLifecycle extends Lifecycle, Phased {
boolean isAutoStartup();
void stop(Runnable callback);
}
只有我想在所有其他控制器初始化后分阶段加载两个控制器。
为了实现这种行为,我在两个Spring组件中都实现了阶段接口。
首先要初始化@Service。
@Service
public class BatchTaskController implements Phased{
@Autowired
private ActorService actorService;
@Autowired
private SessionFactory sessionFactory;
public BatchTaskController(){
this.batch();
}
public void batch(){
//TO DO...
}
@Override
public int getPhase() {
return 1;
}
}
@Controller在批处理任务@Service后初始化。
@Controller
public class MainController implements Phased{
@Autowired
private ActorService actorService;
@Autowired
private SessionFactory sessionFactory;
@RequestMapping(value = {"/", "/index"})
public String showHome(HttpServletRequest request) {
//TO DO
return "index";
}
@Override
public int getPhase() {
return 2;
}
}
ActorService @Service未实现Phased Interface。因此,我想我可以在上面公开的Spring Reference文章中看到,ActorService @Service比之前的@Controllers更早开始,因为默认情况下ActorService @Service阶段值为0。
但是,当我部署我的应用程序时,我得到下一个NullPointerException错误。
04-04-2014 08:34:10,286 AM ERROR ContextLoader:331 - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'batchTaskController' defined in file [E:\Desarrollo\Spring\pjcomspringehcache\target\pjcomspringehcache-1.0-SNAPSHOT\WEB-INF\classes\com\pjcom\pjcomspringehcache\BatchTaskController.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.pjcom.pjcomspringehcache.BatchTaskController]: 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:703)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4738)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5158)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:726)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:702)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:697)
at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:579)
at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1744)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.uti
l.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:744)
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.pjcom.pjcomspringehcache.BatchTaskController]: 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)
... 26 more
Caused by: java.lang.NullPointerException
at com.pjcom.pjcomspringehcache.BatchTaskController.batch(BatchTaskController.java:32)
at com.pjcom.pjcomspringehcache.BatchTaskController.<init>(BatchTaskController.java:23)
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:408)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:148)
... 28 more
为什么?
解
首先要初始化@Service。
@Service
public class BatchTaskController implements Phased{
@Autowired
private ActorService actorService;
@Autowired
private SessionFactory sessionFactory;
@PostConstruct
public void batch(){
//TO DO...
}
@Override
public int getPhase() {
return 1;
}
}