从 JVM 角度看 Spring 中方法执行过程和内存状态

Spring 容器中的 Bean 默认是单例的,也就是说我们在使用被Spring管理的对象的时候,不需要重复创建了,从而节省空间。

举个例子:

作为一个 CRUD 攻城狮,平时开发最多的就是一个Web应用

@RestController
public class OrderController{
	@Autowired
	private OrderServiceImpl orderService;
	@RequestMapping(value = "/hello/{orderId}",method = RequestMethod.GET)
	public Order getOrder(@PathVariable("orderId")Long orderId){
		return orderService.get(orderId)}
}

@Service
public class OrderServiceImpl implements OrderService{
	@Autowired
	private OrderDao orderDao;
	public Order get(Long orderId){
		return orderDao.get(orderId);
	}
}

Spring 启动后,所有的对象已经创建好放入了容器,看下图
在这里插入图片描述

但一个客户端发送请求时,Servlet容器创建一个线程1,我们知道一个线程对应一个方法栈,而一个方法对应一个栈帧,下图时请求过来时的栈状态

在这里插入图片描述

此时调用的方法对应的是栈中的一个个栈帧,栈帧中使用到了Spring 容器中的一些对象在哪?在堆中,也可以说Spring 容器中,还是上面图种描述的样子。

此时有一个客户端发送请求过来,Servlet容器为这个客户端创建一个线程2,然后调用方法,栈状态如下
在这里插入图片描述

此时理解一下各个栈帧中的对象共用堆中的对象,大家会不有个疑问,多个线程共用有个对象,线程怎么知道程序执行到哪了?会不会乱了?

大家还记得有程序计数器和方法区这两个东东么?!一个线程对应一个程序计数器,我们这里的两个线程各拥有一个程序计数器

比如我们线程1执行到 orderDao.get(orderId) 这行代码,线程2才执行到 orderService.get(orderId) ,此时各个部件状态状态如下图:
在这里插入图片描述

此时还有个问题,程序执行增么找到方法区的代码的呢?

其实很简单,我们以线程1为例来说,我们执行 getOrder方法对应的栈帧中不是先要从Spring容器中拿到 OrderController 对象

我们既然拿到了这个对象,是不是就可以知道其对应的Class对象了(对象.getClass()),这个Class对象可以认为就是 'OrderContoller’类对应的方法区中的字节码(.class文件)。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

java硕哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值