如何使用正确初始化的 spring bean 在 struts 中手动调用调度
How to manually invoke a dispatch in struts with spring beans properly initialized
我正在开发一个应用程序来从后端自动执行一组长时间的操作,目前这些操作必须由用户完成。
所以我需要在我正在开发的程序的Action中调用Actions中的相关调度方法。
我正在开发的 Action 是
public class AutomatedAction extends DispatchAction{
public ActionForward create(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception{
MyAction myAction = new MyAction();
myAction.myDispatch();
// Want to call more dispatches like this
return null;
}
}
MyAction class 的样本是
public class MyAction extends DispatchAction{
public ActionForward myDispatch(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception{
// Some code
getSomeBD().doOperation();
}
}
但我面临的问题是在 myDispatch() 方法内部,有 Spring 个用于层映射的 bean,例如 -
getSomeBD().doOperation();
这在手动方式下工作正常,但是当我检查 bean 的 getter 时,上面的代码出现 NullPointerException -
getSomeBD()
谁能解释为什么会这样?据我所知,spring beans 在服务器启动时被初始化,所以为什么要给我一个 NullPointer?
正如 Aleksandr M 所说,我找到了答案。因为 spring bean 不会通过调用 new MyAction()
注入,所以我必须从上下文中获取 MyAction bean 本身。
所以我所做的是将 - implements ApplicationContextAware
添加到 AutomatedAction
class。
public class AutomatedAction extends DispatchAction implements ApplicationContextAware{}
通过实现 ApplicationContextAware
我们可以覆盖它的
public void setApplicationContext(ApplicationContext context);
方法并通过定义一个实例变量获取应用程序上下文。然后我能够从上下文中获取 bean,而不是创建一个新实例。
private ApplicationContext context;
public ApplicationContext getContext() {
return context;
}
public void setContext(ApplicationContext context) {
this.context = context;
}
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
this.context = context;
}
所以最终的编码看起来像这样。
自动操作 class -
public class AutomatedAction extends DispatchAction implements ApplicationContextAware {
private ApplicationContext context;
public ApplicationContext getContext() {
return context;
}
public void setContext(ApplicationContext context) {
this.context = context;
}
public ActionForward create(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception{
MyAction myAction = (MyAction) getContext().getBean("/MyActionBean");
myAction.myDispatch();
// do more
return null;
}
}
MyAction class(无变化)
public class MyAction extends DispatchAction{
public ActionForward myDispatch(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception{
// Some code
getSomeBD().doOperation();
}
}
我正在开发一个应用程序来从后端自动执行一组长时间的操作,目前这些操作必须由用户完成。
所以我需要在我正在开发的程序的Action中调用Actions中的相关调度方法。
我正在开发的 Action 是
public class AutomatedAction extends DispatchAction{
public ActionForward create(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception{
MyAction myAction = new MyAction();
myAction.myDispatch();
// Want to call more dispatches like this
return null;
}
}
MyAction class 的样本是
public class MyAction extends DispatchAction{
public ActionForward myDispatch(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception{
// Some code
getSomeBD().doOperation();
}
}
但我面临的问题是在 myDispatch() 方法内部,有 Spring 个用于层映射的 bean,例如 -
getSomeBD().doOperation();
这在手动方式下工作正常,但是当我检查 bean 的 getter 时,上面的代码出现 NullPointerException -
getSomeBD()
谁能解释为什么会这样?据我所知,spring beans 在服务器启动时被初始化,所以为什么要给我一个 NullPointer?
正如 Aleksandr M 所说,我找到了答案。因为 spring bean 不会通过调用 new MyAction()
注入,所以我必须从上下文中获取 MyAction bean 本身。
所以我所做的是将 - implements ApplicationContextAware
添加到 AutomatedAction
class。
public class AutomatedAction extends DispatchAction implements ApplicationContextAware{}
通过实现 ApplicationContextAware
我们可以覆盖它的
public void setApplicationContext(ApplicationContext context);
方法并通过定义一个实例变量获取应用程序上下文。然后我能够从上下文中获取 bean,而不是创建一个新实例。
private ApplicationContext context;
public ApplicationContext getContext() {
return context;
}
public void setContext(ApplicationContext context) {
this.context = context;
}
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
this.context = context;
}
所以最终的编码看起来像这样。
自动操作 class -
public class AutomatedAction extends DispatchAction implements ApplicationContextAware {
private ApplicationContext context;
public ApplicationContext getContext() {
return context;
}
public void setContext(ApplicationContext context) {
this.context = context;
}
public ActionForward create(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception{
MyAction myAction = (MyAction) getContext().getBean("/MyActionBean");
myAction.myDispatch();
// do more
return null;
}
}
MyAction class(无变化)
public class MyAction extends DispatchAction{
public ActionForward myDispatch(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception{
// Some code
getSomeBD().doOperation();
}
}