Spring之HttpServletRequest注入和ObjectFactory原理
为什么可以直接注入HttpServletRequest
如果我们要使用HttpServletRequest,可以通过Controller的参数,也可以如下,直接在Controller(也可以是Service)注入HttpServletRequest,那这是怎么实现的呢?
1 |
|
注入函数在 WebApplicationContextUtils#registerWebApplicationScopes内
1 | beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory()); |
RequestObjectFactory是一个ObjectFactory,其中getObject方法返回ServletRequest接口,方法内部,每次取从ThreadLocal里取RequestAttributes(WebApplicationContextUtils#currentRequestAttributes)
set的时机,是在请求时,通过Filter进行set,RequestContextFilter#initContextHolders
猜测
所以我们猜测,每次在访问注入的对象的方法时,都通过ObjectFactory.getObject获取到真实操作的对象,然后再调用对应的方法
验证
注册时调用的是registerResolvableDependency,看源码可知添加到resolvableDependencies,解析注入依赖时,会调用AutowireUtils#resolveAutowiringValue,如下,可以看到,如果注册的是ObjectFactory且Serializable且返回类型是接口,则注入JDK动态代理对象,getObject将会被多次调用(每调用一次方法都会调用一次),否则直接注入getObject的结果,此时getObject只会执行一次。
1 | public static Object resolveAutowiringValue(Object autowiringValue, Class<?> requiredType) { |
JDK动态代理的InvocationHandler如下:
1 |
|
得到验证