Struts2中的依赖注入访问会话范围的bean [英] Dependency Injection in Struts2 Accessing Session Scoped Beans
问题描述
// @ Repository
// @ Scope(session)
public class Session {
private Map< String,Object> map = new HashMap<>();
public Map< String,Object> getMap(){
return map;
}
public void setMap(Map< String,Object> map){
this.map = map;
}
}
我已经评论过与Spring bean一起使用的注释。我通过弹簧DI成功创建了同一个bean,并设置了注入对象的范围。现在,我想用Struts2和DI做同样的事情。为此,我在 struts.xml中创建了bean定义
; bean name =sessionclass =jspbean.struts.Sessionscope =session/>
和简单的操作来创建并注入到我的动作
public class DefaultAction extends ActionSupport {
private Session session;
// @Autowired
@Inject(session)
public void setSession(Session session){
this.session = session;
}
public Session getSession(){
return session;
}
private Map< String,String> myMap = new HashMap< String,String>();
public Map< String,String> getMyMap(){
return myMap;
}
public void setMyMap(Map< String,String> myMap){
this.myMap = myMap;
@Override
public String execute()throws异常{
//用样本数据填充我的bean
myMap.put(q1 ,Question1);
myMap.put(q2,Question2);
session.getMap()。put(myMap,myMap);
return SUCCESS;
}
}
在JSP中我使用简单的迭代器超过会话bean
< s:iterator value =session.map ['myMap']>
< s:textfield name =myMap ['%{key}']value =%{value}theme =simplesize =10/>< br&
< / s:iterator>
现在,当我运行这个smple应用程序时,我有异常
Stacktraces
无法实例化Action,jspbean.struts.DefaultAction,为''在命名空间中定义'/'java.lang.IllegalStateException:范围策略未设定。请调用Container.setScopeStrategy()。
com.opensymphony.xwork2.DefaultActionInvocation.createAction(DefaultActionInvocation.java:316)
com.opensymphony.xwork2.DefaultActionInvocation.init(DefaultActionInvocation.java:397)
com。 opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:194)
org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:63)
org.apache.struts2.impl.StrutsActionProxyFactory。 createActionProxy(StrutsActionProxyFactory.java:39)
com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:536)
org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Applicatio nFilterChain.java:243)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
org。 apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
org.apache.catalina.valves。 AccessLogValve.invoke(AccessLogValve.java:936)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter。 java:407)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
org.apache.coyote.AbstractProtocol $ AbstractConnectionH andler.process(AbstractProtocol.java:589)
org.apache.tomcat.util.net.JIoEndpoint $ SocketProcessor.run(JIoEndpoint.java:312)
java.util.concurrent.ThreadPoolExecutor.runWorker(未知源)
java.util.concurrent.ThreadPoolExecutor $ Worker.run(Unknown Source)
java.lang.Thread.run(未知来源)
java .lang.RuntimeException:java.lang.IllegalStateException:范围策略未设置。请调用Container.setScopeStrategy()。
com.opensymphony.xwork2.inject.ContainerImpl $ MethodInjector.inject(ContainerImpl.java:301)
com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl.java:492)
com.opensymphony.xwork2.inject.ContainerImpl $ 6.call(ContainerImpl.java:530)
com.opensymphony.xwork2.inject.ContainerImpl $ 6.call(ContainerImpl.java:528)
com.opensymphony.xwork2.inject.ContainerImpl.callInContext(ContainerImpl.java:584)
com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl.java:528)
com.opensymphony.xwork2。 ObjectFactory.injectInternalBeans(ObjectFactory.java:139)
com.opensymphony.xwork2.spring.SpringObjectFactory.autoWireBean(SpringObjectFactory.java:208)
com.opensymphony.xwork2.spring.SpringObjectFactory.buildBean(SpringObjectFactory。 java:183)
com.opensymphony.xwork2.spring.SpringObjectFactory.buildBean(SpringObjectFactory.java:154)
com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFacto ry.java:151)
com.opensymphony.xwork2.ObjectFactory.buildAction(ObjectFactory.java:121)
com.opensymphony.xwork2.DefaultActionInvocation.createAction(DefaultActionInvocation.java:297)
com.opensymphony.xwork2.DefaultActionInvocation.init(DefaultActionInvocation.java:397)
com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:194)
org.apache.struts2.impl.StrutsActionProxy。准备(StrutsActionProxy.java:63)
org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:39)
com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:536)
org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.jav a:91)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
org.apache。 catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
org.apache.catalina.valves.ErrorReportValve。 invoke(ErrorReportValve.java:99)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java: 118)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
org.apache.coyote.http11.AbstractHttp11Processor.process(Abstract Http11Processor.java:1004)
org.apache.coyote.AbstractProtocol $ AbstractConnectionHandler.process(AbstractProtocol.java:589)
org.apache.tomcat.util.net.JIoEndpoint $ SocketProcessor.run(JIoEndpoint。 java:312)
java.util.concurrent.ThreadPoolExecutor.runWorker(未知源)
java.util.concurrent.ThreadPoolExecutor $ Worker.run(Unknown Source)
java.lang.Thread。 run(Unknown Source)
java.lang.IllegalStateException:范围策略未设置。请调用Container.setScopeStrategy()。
com.opensymphony.xwork2.inject.InternalContext.getScopeStrategy(InternalContext.java:53)
com.opensymphony.xwork2.inject.Scope $ 5 $ 1.create(Scope.java:130)
com.opensymphony.xwork2.inject.ContainerImpl $ ParameterInjector.inject(ContainerImpl.java:469)
com.opensymphony.xwork2.inject.ContainerImpl.getParameters(ContainerImpl.java:484)
com.opensymphony.xwork2.inject.ContainerImpl.access $ 000(ContainerImpl.java:34)
com.opensymphony.xwork2.inject.ContainerImpl $ MethodInjector.inject(ContainerImpl.java:299)
com.opensymphony .xwork2.inject.ContainerImpl.inject(ContainerImpl.java:492)
com.opensymphony.xwork2.inject.ContainerImpl $ 6.call(ContainerImpl.java:530)
com.opensymphony.xwork2.inject。 ContainerImpl $ 6.call(ContainerImpl.java:528)
com.opensymphony.xwork2.inject.ContainerImpl.callInContext(ContainerImpl.java:584)
com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl .java:528)
com.opensymphony.xwork2.ObjectFactory.injectInternalBeans(ObjectFactory.java:139)
com.opensymphony.xwork2.spring.SpringObjectFactory.autoWireBean(SpringObjectFactory.java:208)
com.opensymphony.xwork2.spring。 SpringObjectFactory.buildBean(SpringObjectFactory.java:183)
com.opensymphony.xwork2.spring.SpringObjectFactory.buildBean(SpringObjectFactory.java:154)
com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:
com.opensymphony.xwork2.ObjectFactory.buildAction(ObjectFactory.java:121)
com.opensymphony.xwork2.DefaultActionInvocation.createAction(DefaultActionInvocation.java:297)
com.opensymphony。 xwork2.DefaultActionInvocation.init(DefaultActionInvocation.java:397)
com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:194)
org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy。 java:63)
org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy (StrutsActionProxyFactory.java:39)
com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:536)
org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
org.apache .catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
org.apache.catalina.authenticator.AuthenticatorBase .invoke(AuthenticatorBase.java:472)
org.apache.catalina.core.StandardHostValve。 invoke(StandardHostValve.java:171)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java: 936)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
org.apache.coyote.AbstractProtocol $ AbstractConnectionHandler.process(AbstractProtocol.java:589)
org.apache.tomcat。 util.net.JIoEndpoint $ SocketProcessor.run(JIoEndpoint.java:312)
java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
java.util.concurrent.ThreadPoolExecutor $ Worker.run(Unknown来源)
java.lang.Thread.run(未知来源)
异常说我需要设置范围策略。所以,我的问题是这个范围策略是什么,以及如何在我的简单应用程序中实现。另外,有注释 @Scoped
,我的情况下如何应用注释?
我的示例参考:
让我们从看看什么是$ c> Scope.Strategy 通过查看文档。它说
可插拔范围设定策略。使用户能够提供请求,会话和向导范围的自定义
实现。实现和
传递给
Container.setScopeStrategy(com.opensymphony.xwork2.inject.Scope.Strategy)
好的,假设我想实现会话范围。然后我需要知道我可以实现的地方。该框架具有扩展点,您可以在哪里插入扩展,或者只是扩展默认
实现并提供自己的自定义实现。这可以通过查看 BeanSelectionProvider
。然后分析堆栈跟踪,我决定最好的办法是扩展 DefaultActionProxyFactory
。扩展它需要扩展 DefaultActionProxy
。
public class MyActionProxyFactory extends DefaultActionProxyFactory {
public MyActionProxyFactory(){
super();
}
@Override
public ActionProxy createActionProxy(ActionInvocation inv,String namespace,String actionName,String methodName,boolean executeResult,boolean cleanupContext){
MyActionProxy proxy = new MyActionProxy(inv,namespace,actionName,methodName,executeResult,cleanupContext);
container.inject(proxy);
container.setScopeStrategy(new MyScopeStrategy());
proxy.prepare();
返回代理;
}
}
public class MyActionProxy extends DefaultActionProxy {
protected MyActionProxy(ActionInvocation inv,String namespace,String actionName,String methodName,boolean executeResult, boolean cleanupContext){
super(inv,namespace,actionName,methodName,executeResult,cleanupContext);
}
@Override
protected void prepare(){
super.prepare();
}
}
public class MyScopeStrategy实现Scope.Strategy {
@Override
public< T> T findInRequest(类< T> type,String name,Callable<?extends T>工厂)throws Exception {
return null;
}
@Override
public< T> T findInSession(Class< T> type,String name,Callable<?extends T> factory)throws Exception {
ActionContext context = ActionContext.getContext();
会话映射< String,T> sessionMap =(SessionMap< String,T>)context.getSession();
if(sessionMap == null){
sessionMap = new SessionMap< String,T>(ServletActionContext.getRequest());
context.setSession((Map< String,Object>)sessionMap);
}
T obj = sessionMap.get(name);
if(obj == null){
obj = factory.call();
sessionMap.put(name,obj);
}
return obj;
}
@Override
public< T> T findInWizard(类< T> type,String name,Callable<?extends T>工厂)throws Exception {
return null;
}
}
在配置文件 struts你应该设置属性
< constant name =struts.actionProxyFactoryvalue = jspbean.struts.factory.MyActionProxyFactory/>
这就是你需要注入一个bean Session
与会话范围。可以对其他范围进行类似的实现。注意,像singlton(默认使用),线程和默认的其他范围似乎不需要这种可插拔扩展。最后一个字是关于 @Scoped
注释。如果您通过xml配置提供bean,则不会使用它。但是,如果您以任何其他方式向bean提供 ContainerBuilder
,则可以在其上查找注释并设置相应的范围。
Recently I needed to use DI in Struts2. I know it uses it's own DI implementation like Guice but not Guice, as far as I couldn't find some annotations suitable to set the scope for injected beans. To be short, I created a bean
//@Repository
//@Scope("session")
public class Session {
private Map<String, Object> map = new HashMap<>();
public Map<String, Object> getMap() {
return map;
}
public void setMap(Map<String, Object> map) {
this.map = map;
}
}
I have commented the annotations used with Spring beans. I was successfully created the same bean via spring DI and set the scope in which my objects were injected. Now, I want to do the same with Struts2 and DI. For this purpose I created the bean definition in struts.xml
<bean name="session" class="jspbean.struts.Session" scope="session"/>
and simple action to get that bean created and injected into my action
public class DefaultAction extends ActionSupport {
private Session session;
// @Autowired
@Inject("session")
public void setSession(Session session) {
this.session = session;
}
public Session getSession() {
return session;
}
private Map<String, String> myMap = new HashMap<String, String>();
public Map<String, String> getMyMap() {
return myMap;
}
public void setMyMap(Map<String, String> myMap) {
this.myMap = myMap;
}
@Override
public String execute() throws Exception {
//populate my bean with sample data
myMap.put("q1", "Question1");
myMap.put("q2", "Question2");
session.getMap().put("myMap", myMap);
return SUCCESS;
}
}
in the JSP I use simple iterator over session bean
<s:iterator value="session.map['myMap']">
<s:textfield name="myMap['%{key}']" value="%{value}" theme="simple" size="10" /><br>
</s:iterator>
Now, when I'm running this smple application I've got the exception
Stacktraces
Unable to instantiate Action, jspbean.struts.DefaultAction, defined for '' in namespace '/'java.lang.IllegalStateException: Scope strategy not set. Please call Container.setScopeStrategy().
com.opensymphony.xwork2.DefaultActionInvocation.createAction(DefaultActionInvocation.java:316)
com.opensymphony.xwork2.DefaultActionInvocation.init(DefaultActionInvocation.java:397)
com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:194)
org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:63)
org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:39)
com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:536)
org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
java.lang.Thread.run(Unknown Source)
java.lang.RuntimeException: java.lang.IllegalStateException: Scope strategy not set. Please call Container.setScopeStrategy().
com.opensymphony.xwork2.inject.ContainerImpl$MethodInjector.inject(ContainerImpl.java:301)
com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl.java:492)
com.opensymphony.xwork2.inject.ContainerImpl$6.call(ContainerImpl.java:530)
com.opensymphony.xwork2.inject.ContainerImpl$6.call(ContainerImpl.java:528)
com.opensymphony.xwork2.inject.ContainerImpl.callInContext(ContainerImpl.java:584)
com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl.java:528)
com.opensymphony.xwork2.ObjectFactory.injectInternalBeans(ObjectFactory.java:139)
com.opensymphony.xwork2.spring.SpringObjectFactory.autoWireBean(SpringObjectFactory.java:208)
com.opensymphony.xwork2.spring.SpringObjectFactory.buildBean(SpringObjectFactory.java:183)
com.opensymphony.xwork2.spring.SpringObjectFactory.buildBean(SpringObjectFactory.java:154)
com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:151)
com.opensymphony.xwork2.ObjectFactory.buildAction(ObjectFactory.java:121)
com.opensymphony.xwork2.DefaultActionInvocation.createAction(DefaultActionInvocation.java:297)
com.opensymphony.xwork2.DefaultActionInvocation.init(DefaultActionInvocation.java:397)
com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:194)
org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:63)
org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:39)
com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:536)
org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
java.lang.Thread.run(Unknown Source)
java.lang.IllegalStateException: Scope strategy not set. Please call Container.setScopeStrategy().
com.opensymphony.xwork2.inject.InternalContext.getScopeStrategy(InternalContext.java:53)
com.opensymphony.xwork2.inject.Scope$5$1.create(Scope.java:130)
com.opensymphony.xwork2.inject.ContainerImpl$ParameterInjector.inject(ContainerImpl.java:469)
com.opensymphony.xwork2.inject.ContainerImpl.getParameters(ContainerImpl.java:484)
com.opensymphony.xwork2.inject.ContainerImpl.access$000(ContainerImpl.java:34)
com.opensymphony.xwork2.inject.ContainerImpl$MethodInjector.inject(ContainerImpl.java:299)
com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl.java:492)
com.opensymphony.xwork2.inject.ContainerImpl$6.call(ContainerImpl.java:530)
com.opensymphony.xwork2.inject.ContainerImpl$6.call(ContainerImpl.java:528)
com.opensymphony.xwork2.inject.ContainerImpl.callInContext(ContainerImpl.java:584)
com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl.java:528)
com.opensymphony.xwork2.ObjectFactory.injectInternalBeans(ObjectFactory.java:139)
com.opensymphony.xwork2.spring.SpringObjectFactory.autoWireBean(SpringObjectFactory.java:208)
com.opensymphony.xwork2.spring.SpringObjectFactory.buildBean(SpringObjectFactory.java:183)
com.opensymphony.xwork2.spring.SpringObjectFactory.buildBean(SpringObjectFactory.java:154)
com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:151)
com.opensymphony.xwork2.ObjectFactory.buildAction(ObjectFactory.java:121)
com.opensymphony.xwork2.DefaultActionInvocation.createAction(DefaultActionInvocation.java:297)
com.opensymphony.xwork2.DefaultActionInvocation.init(DefaultActionInvocation.java:397)
com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:194)
org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:63)
org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:39)
com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:536)
org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
java.lang.Thread.run(Unknown Source)
The exception says that I need to set the scope strategy. So, my question is what is this scope strategy and how it could be implemented in my simple application. Also, there is annotation @Scoped
, how this annotations to apply in my case?
My example references:
Let's start from looking what is a Scope.Strategy
by looking at the docs. It says
Pluggable scoping strategy. Enables users to provide custom implementations of request, session, and wizard scopes. Implement and pass to
Container.setScopeStrategy(com.opensymphony.xwork2.inject.Scope.Strategy)
Ok, assume I want to implement session scope. Then I need to know the place where I could implement it. The framework has it's extension points where where you could plug your extensions or simply extend the default
implementation and provide your own custom implementations. This is easy done via looking at the BeanSelectionProvider
. Then analyzing the stacktraces I decided the best point would be to extend the DefaultActionProxyFactory
. Extending it requires to extend the DefaultActionProxy
also.
public class MyActionProxyFactory extends DefaultActionProxyFactory {
public MyActionProxyFactory() {
super();
}
@Override
public ActionProxy createActionProxy(ActionInvocation inv, String namespace, String actionName, String methodName, boolean executeResult, boolean cleanupContext) {
MyActionProxy proxy = new MyActionProxy(inv, namespace, actionName, methodName, executeResult, cleanupContext);
container.inject(proxy);
container.setScopeStrategy(new MyScopeStrategy());
proxy.prepare();
return proxy;
}
}
public class MyActionProxy extends DefaultActionProxy {
protected MyActionProxy(ActionInvocation inv, String namespace, String actionName, String methodName, boolean executeResult, boolean cleanupContext) {
super(inv, namespace, actionName, methodName, executeResult, cleanupContext);
}
@Override
protected void prepare() {
super.prepare();
}
}
public class MyScopeStrategy implements Scope.Strategy {
@Override
public <T> T findInRequest(Class<T> type, String name, Callable<? extends T> factory) throws Exception {
return null;
}
@Override
public <T> T findInSession(Class<T> type, String name, Callable<? extends T> factory) throws Exception {
ActionContext context = ActionContext.getContext();
SessionMap<String, T> sessionMap = (SessionMap<String, T>) context.getSession();
if (sessionMap == null) {
sessionMap = new SessionMap<String, T>(ServletActionContext.getRequest());
context.setSession((Map<String, Object>) sessionMap);
}
T obj = sessionMap.get(name);
if (obj == null) {
obj = factory.call();
sessionMap.put(name, obj);
}
return obj;
}
@Override
public <T> T findInWizard(Class<T> type, String name, Callable<? extends T> factory) throws Exception {
return null;
}
}
In the configuration file struts.xml
you should set the property
<constant name="struts.actionProxyFactory" value="jspbean.struts.factory.MyActionProxyFactory"/>
That's all you need to inject a bean Session
with the session scope. Similar implementations could be done for other scopes. Notice, that other scopes like singlton (used by default), thread, and default seems don't require such pluggable extension. And the last word is about @Scoped
annotation. It's not used if you provide the beans via xml configuration. But if you supply the ContainerBuilder
with the bean in any other way it's able to find annotation on it and set the corresponding scope.
这篇关于Struts2中的依赖注入访问会话范围的bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!