HttpServletRequest自动装配到任意Spring组件的文档在哪里?

omqzjyyz  于 12个月前  发布在  Spring
关注(0)|答案(3)|浏览(88)

今天,我发现可以将HttpServletRequest自动连接到任意的单例Spring bean中。

@Component
public class MyComponent {
    private final HttpServletRequest servletRequest;

    public MyComponent(HttpServletRequest servletRequest) {
        this.servletRequest = servletRequest;
    }
}

字符串
我还没有找到权威的来源,但从我在网上搜索到的信息来看,这实际上是一个委托给运行线程的实际HttpServletRequest的 Package 器。
例如,2012年的this blog post指出:
那么当多个请求来到这个服务时,对应于用户请求的正确的httpServletRequest是如何注入到这个服务对象中的呢?答案是,一个真实的HttpServletRequest并没有真正注入,只是注入了一个代理。代理在内部是对RequestContextHolder的引用,在某个时候将HttpServletRequest绑定到一个threadlocal变量。
我还不清楚这是Spring的核心特性、Spring MVC的特性还是Sping Boot 提供的特性。
我还没有找到任何权威的消息来源(例如在Spring文档,Spring内部,或Spring发行说明中)解释这是一个受支持的特性,并解释它是如何工作的。我猜它在那里,但我没有运气找到它。如果我要使用这样的特性,我更希望有这样的背景,这样我就可以推理出何时以及如何最好地使用它,以及何时避免它。
此功能的文档在哪里?
注意事项:这是一个类似于Inject HttpServletRequest into Controller的问题,但是,这是在询问这种方法的缺陷以及它是如何工作的,而不是解决它在哪里或如何被文档化或以其他方式指定的问题。

chhqkbe1

chhqkbe11#

HttpServletRequest自动配置代理的可能性是SpringMVC的一部分,遗憾的是它没有正确地文档化。
你能找到的关于它的最好的信息是在spring-web:3.0.0的一些发行说明中。例如,看看release notes of 3.0.0.M4,特别是在这个问题上,Juergen Hoeller(String的主要开发者之一)谈到了这个版本以来它是如何工作的。
另外,请随时检查源代码(WebApplicationContextUtils,RequestContextHolder),它们都有很好的文档记录。

vojdkbi0

vojdkbi02#

你得到的另一个答案涵盖了这个特性在哪里有(没有)文档记录;它还涵盖了这个特性的支持程度,因为它指出这个特性现在已经到了第三个主要版本,这使得它似乎不太可能很快消失。
不过,你让我对它的工作原理很感兴趣,所以我想我会把我的发现写下来。(不是构造函数注入),但它的很多内容也适用于其他用例。下面是详细的描述,链接到特定的代码行,但首先有一个执行摘要:几乎没有任何代码是专门针对HttpServletRequest的,而专门针对HttpServletRequest的代码是涉及的最简单的代码。即使它这样做,我认为,如果您愿意在应用程序上下文预刷新方面做些手脚,您也可以自己重新创建它。
所以,细节:当上下文刷新时,WebApplicationContextUtils转到DefaultListableBeanFactory并说“如果有人问你他们在哪里可以得到ServletRequest,你可以使用这个RequestObjectFactory回答他们“。稍后在同一上下文刷新期间,同一个bean工厂正在创建bean。当它到达@Component时,它看到它需要自动连接HttpServletRequest。因为这是一个接口,它从RequestObjectFactory构造java.lang.reflect.Proxy,并将 that 分配给@Autowired字段。
稍后,servlet容器接收对应用程序的servlet的请求,并通过应用程序的过滤器链发送它。该链中的一个过滤器是RequestContextFilter,它设置RequestContextHolder的请求属性。请注意,该类使用ThreadLocal s;由于每个请求都在不同的线程中处理,因此没有其他线程会改变请求属性。
晚些时候(但仍在处理相同的请求),@Component的方法被调用。它又调用@Autowired HttpServletRequest字段上的方法。该字段包含一个代理,所以方法调用被分派到创建代理时使用的调用处理程序。(参见上面两段的“构造”链接。)调用处理程序根据RequestObjectFactorygetObject方法返回的任何内容调用该方法;最后,该方法可以访问servlet容器设置的请求。

cbjzeqam

cbjzeqam3#

根据spring-framework#26201的要求,这是从Spring 6.1.3开始记录的。
每个进样请求/会话直接引用:
作为工厂作用域的替代方案,Spring WebApplicationContext还支持HttpServletRequestHttpServletResponseHttpSessionWebRequest和(如果存在JSF)FacesContextExternalContext到Spring管理的bean中,只是通过类型-Spring通常会为这样的请求和会话对象注入代理,这具有优势在单例bean和可序列化bean中工作,类似于工厂范围bean的范围代理。

相关问题