如何用自定义范围和@Autowired依赖项实例化Springbean?

如何用自定义范围和@Autowired依赖项实例化Springbean?,spring,scope,httprequest,autowired,thread-local,Spring,Scope,Httprequest,Autowired,Thread Local,在我们的项目中,我们使用Spring请求范围的bean。现在我们需要支持异步请求,而请求范围的bean不适用于子线程。我知道,它“支持”异步,但似乎RequestContextFilter希望主线程等待子线程完成,而我们不是这样。我们的主线程在使用@Async注释生成新线程后立即返回,并且DispatcherServlet清除RequestContextHolder。因此,当子线程需要请求范围的bean时,@Autowired失败 我也知道,但它不会清理线程本地属性,在线程池的情况下,使用它不仅

在我们的项目中,我们使用Spring请求范围的bean。现在我们需要支持异步请求,而请求范围的bean不适用于子线程。我知道,它“支持”异步,但似乎
RequestContextFilter
希望主线程等待子线程完成,而我们不是这样。我们的主线程在使用
@Async
注释生成新线程后立即返回,并且
DispatcherServlet
清除
RequestContextHolder
。因此,当子线程需要请求范围的bean时,
@Autowired
失败

我也知道,但它不会清理线程本地属性,在线程池的情况下,使用它不仅危险,而且毫无用处

我需要的是一个自定义范围。到目前为止,我已经找到了3个有用的示例,但它们都有不足之处,因为它们作为自定义范围的一部分实例化的bean是没有任何依赖关系的普通POJO。不用说,这在实际应用程序中是不存在的。有人能提出一种方法来实例化对其他范围的bean具有
@Autowired
依赖关系的自定义范围的bean吗

到目前为止,我发现:


从这里继续讨论

我指的是链接指向的
。每次引用autowired字段时,都会调用自定义范围的
get()
方法,根据某些条件查找实例

我知道我可以查找依赖项(尽管不确定如何查找,范围不是bean,也许我需要在实例化期间传递应用程序上下文?)。我不明白的是,如果这些依赖项被标记为@Autowired,如何将它们注入我的bean中?或者你是说自定义范围的bean不应该有@Autowired依赖项

它自动工作;Spring为bean注入了一个代理,在该bean上的每个方法调用上调用
scope.get()
,在当前调用的上下文中返回您想要的特定实例

查看
AbstractRequestAttributesScope
以了解其工作原理(在这种情况下,从HTTP请求获取实例,如果实例不存在,则创建实例)

因此,您的代码在代理上调用
foo()
;框架调用作用域以获取所需的实例,然后对该实例调用
foo()


您希望调用的公开方法必须在接口上,或者未在web层上声明
final

异步支持,而只是拍击
@async
是不同的事情。相反,您希望使用
差异结果
可调用
并从控制器返回该结果。通过这种方式,您可以使用servlet规范的异步功能。当使用
@async
时,您基本上会得到一个后台线程,无法访问请求范围内的变量。@M.Deinum不,我们不希望使用来自控制器的
延迟结果
可调用
,因为我们的客户端无法处理该问题。我们的需求在上面描述的方式中是独一无二的。那么为什么还要使用请求范围的bean呢?只需将所需的内容作为方法参数传递,而不需要自定义范围,这样只会使事情变得复杂…将十几个内容作为方法参数传递?不用了,谢谢。即使将它们包装在一个对象中并通过也是一种令人反感的设计。这是一种观点,我认为,为类似的东西滥用范围是值得怀疑的。你已经有了这个对象,所以你已经在其中设置了一些东西,如果把它作为一个单独的对象传递而不是使用一个作用域,那会使事情变得更糟。我做了一个小项目,试图做两件事:1)创建一个自定义作用域,效果很好。2) 当使用
@Async
时,使自定义作用域工作,但不工作。生成新线程的类是
AnnotationAsyncExecutionInterceptor
,我对它进行了子类化,然后让Spring调用我的类而不是它自己的类。不知何故,它一直在调用
AnnotationAsyncExecutionInterceptor.invoke
,而不是我的。下面的maven项目可能会被签出,
mvn清理测试将显示问题。