禁用 Spring 的隐式方法依赖注入

Disable Spring's implicit method dependency injection

我目前正在使用 Struts 开发一个应用程序,在我扩展 ActionSupport 以访问 i18n 功能之前,hello world 页面工作得很好。执行此操作后,操作总是开始 returning input 作为结果字符串。这显然是出乎意料的,因为目前没有进行任何验证。调试后,我注意到 Spring 决定注入一个字段错误映射,所以验证总是看到一些东西,导致意外的 return 值。

]1

这是堆栈跟踪:

Daemon Thread [http-0.0.0.0-8080-2] (Suspended (breakpoint at line 79 in ActionSupport))    
Index(ActionSupport).setFieldErrors(Map<String,List<String>>) line: 79  
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]  
NativeMethodAccessorImpl.invoke(Object, Object[]) line: not available   
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: not available   
Method.invoke(Object, Object...) line: not available    
BeanWrapperImpl.setPropertyValue(BeanWrapperImpl$PropertyTokenHolder, PropertyValue) line: 1134 
BeanWrapperImpl.setPropertyValue(PropertyValue) line: 903   
BeanWrapperImpl(AbstractPropertyAccessor).setPropertyValues(PropertyValues, boolean, boolean) line: 75  
BeanWrapperImpl(AbstractPropertyAccessor).setPropertyValues(PropertyValues) line: 57    
DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).applyPropertyValues(String, BeanDefinition, BeanWrapper, PropertyValues) line: 1450  
DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).populateBean(String, RootBeanDefinition, BeanWrapper) line: 1158 
DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).autowireBeanProperties(Object, int, boolean) line: 376   
StrutsSpringObjectFactory(SpringObjectFactory).autoWireBean(Object, AutowireCapableBeanFactory) line: 218   
StrutsSpringObjectFactory(SpringObjectFactory).buildBean(Class, Map<String,Object>) line: 198   
StrutsSpringObjectFactory(SpringObjectFactory).buildBean(String, Map<String,Object>, boolean) line: 164 
StrutsSpringObjectFactory(ObjectFactory).buildBean(String, Map<String,Object>) line: 178    
DefaultActionFactory.buildAction(String, String, ActionConfig, Map<String,Object>) line: 22 
StrutsSpringObjectFactory(ObjectFactory).buildAction(String, String, ActionConfig, Map<String,Object>) line: 148    
DefaultActionInvocation.createAction(Map<String,Object>) line: 295  
DefaultActionInvocation.init(ActionProxy) line: 395 
StrutsActionProxy(DefaultActionProxy).prepare() line: 194   
StrutsActionProxy.prepare() line: 63    
StrutsActionProxyFactory.createActionProxy(ActionInvocation, String, String, String, boolean, boolean) line: 37 
StrutsActionProxyFactory(DefaultActionProxyFactory).createActionProxy(String, String, String, Map<String,Object>, boolean, boolean) line: 58    
Dispatcher.serviceAction(HttpServletRequest, HttpServletResponse, ActionMapping) line: 554  
ExecuteOperations.executeAction(HttpServletRequest, HttpServletResponse, ActionMapping) line: 81    
StrutsPrepareAndExecuteFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 99   
ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 235  
ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 206  
OpenSessionInViewFilter.doFilterInternal(HttpServletRequest, HttpServletResponse, FilterChain) line: 232    
OpenSessionInViewFilter(OncePerRequestFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 106  
ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 235  
ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 206  
ReplyHeaderFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 96   
ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 235  
ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 206  
StandardWrapperValve.invoke(Request, Response) line: 230    
StandardContextValve.invoke(Request, Response) line: 175    
SecurityAssociationValve.invoke(Request, Response) line: 182    
JaccContextValve.invoke(Request, Response) line: 84 
StandardHostValve.invoke(Request, Response) line: 127   
ErrorReportValve.invoke(Request, Response) line: 102    
CachedConnectionValve.invoke(Request, Response) line: 157   
StandardEngineValve.invoke(Request, Response) line: 109 
CoyoteAdapter.service(Request, Response) line: 262  
Http11Processor.process(Socket) line: 844   
Http11Protocol$Http11ConnectionHandler.process(Socket) line: 583    
JIoEndpoint$Worker.run() line: 446  
Thread.run() line: not available    

这基本上就是 class 包含的全部内容:

public class Index extends ActionSupport implements UserAware
{
    private User user;


    @Override
    public String execute()
    {
        System.out.println("this doesn't print out");
        return "SUCCESS";
    }

    @Override
    public void setUser(User user)
    {
        this.user = user;
    }

    public User getUser()
    {
        return user;
    }
}

我只使用 @Autowired 注释的 属性 注入,所以我想禁用方法注入来解决这个问题。那当然是问题所在。我可能误解了症状。

版本

Struts 和 Spring 默认情况下不能很好地结合在一起,您需要在 struts2-spring-plugin-x.y.z.jar 添加 WEB-INF/lib 从你的 struts lib 目录。并在 web.xml 中正确配置它,参考这个 http://www.tutorialspoint.com/struts_2/struts_spring.htm

发生这种情况是因为 ActionSupport 实现了验证所需的所有接口,例如 Validatable and ValidationAware

ValidationAware classes can accept Action (class level) or field level error messages. Action level messages are kept in a Collection. Field level error messages are kept in a Map from String field name to a List of field error messages.

最后一个更具体地用于注入错误,但它不是 Spring 作业(Spring 使用其对象工厂来构建操作并注入 its dependencies),这是一个 Struts 工作来支持带有字段错误和动作错误的动作,并且用 validation 拦截器做得很好。

This interceptor runs the action through the standard validation framework, which in turn checks the action against any validation rules (found in files such as ActionClass-validation.xml) and adds field-level and action-level error messages (provided that the action implements com.opensymphony.xwork2.ValidationAware).

validation 拦截器包含在 defaultStack 中,默认情况下在任何操作中使用。如果操作不需要验证功能,您可以通过创建新堆栈或覆盖操作配置来从堆栈中删除此拦截器。如果向其他方法提供验证,则可以从拦截器中排除某些方法或应用 @SkipValidation 注释。这将禁用操作方法的验证。

我可以通过在 struts.xml 文件中将自动装配类型更改为 none 来解决这个问题。我最初将其设置为 type,因为我认为 @Autowire 注入将无法正常工作。我想我错了,因为那些注射仍然有效。

<constant name="struts.objectFactory.spring.autoWire" value="type" />

<constant name="struts.objectFactory.spring.autoWire" value="none" />

感谢所有参与者的帮助。