Spring源码解读:Spring注入Request原理


前言

之前我在这篇文章说过Spring往容器里管理了Request对象,所以你可以在spring的任何实例里面注入HTTPRequest对象。具体是怎么实现的呢?
今天就来更详细地分析下~

一、来个例子

public class HealthController {
   

    @Resource
    private HttpServletRequest request;

    @ApiOperation("健康检查")
    @GetMapping("check")
    public String health() {
   
    	System.out.println(request);
        System.out.println(request.getRequestURI());
        return "OK";
    }
}

为了测试,在我们的健康检查接口类里注入了request对象,同时在健康检查的接口里打印信息
接口调用之后,打印结果如下

Current HttpServletRequest
/xxxxx/api/health/check

如果不想通过注入方式,也可以通过((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest()拿到咱们的request对象。

二、解析一下

1. 为啥会打印Current HttpServletRequest

想想,我们给Spring注入的ServletRequest对象是什么

beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());

我们再来看看这个RequestObjectFactory类

	@SuppressWarnings("serial")
	private static class RequestObjectFactory implements ObjectFactory<ServletRequest>, Serializable {
   

		@Override
		public ServletRequest getObject() {
   
			return currentRequestAttributes().getRequest();
		}

		@Override
		public String toString() {
   
			return "Current HttpServletRequest";
		}
	}

可以看到toString()方法的返回,也就是咱们的打印

2. 既然是Spring注入的对象,为啥能做到动态变化

其实此处很容易想到动态代理,毕竟整个Spring的AOP都是基于动态代理做的,但是这个动态代理却又是如此特殊,多数情况下,我们的动态代理不过是在实现invoke()的时候,在target.method调用前后加上咱们的私有逻辑。
但是注意此处Spring给该Request注入的是个RequestObjectFactory,也不是动态代理对象啊。别着急,咱们看看Spring给咱们实际在注入的时候是怎么处理的。
通过添加断点,我们可以发现,在request进行注入的时候,走了以下的逻辑:

/**
	 * Resolve the given autowiring value against the given required type,
	 * e.g. an {@link ObjectFactory} value to its actu
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值