Spring中⼀个Bean的创建⼤概分为以下⼏个步骤:
image.png
Spring本身并没有针对Bean做线程安全的处理,所以:
**⽆状态的**
,那么Bean则是线程安全的**有状态的**
,那么Bean则不是线程安全的。另外,Bean是不是线程安全,跟Bean的作⽤域没有关系,Bean的作⽤域只是表示Bean的⽣命周期范围,对于任何⽣命周期的Bean都是⼀个对象,这个对象是不是线程安全的,还是得看这个Bean对象本身。有状态会话bean :每个用户有自己特有的一个实例,在用户的生存期内,bean保持了用户的信息,即“有状态”;一旦用户灭亡(调用结束或实例结束),bean的生命期也告结束。即每个用户最初都会得到一个初始的bean。
无状态会话bean :bean一旦实例化就被加进会话池中,各个用户都可以共用。即使用户已经消亡,bean 的生命期也不一定结束,它可能依然存在于会话池中,供其他用户调用。由于没有特定的用户,那么也就不能保持某一用户的状态,所以叫无状态bean。但无状态会话bean 并非没有状态,如果它有自己的属性(变量),那么这些变量就会受到所有调用它的用户的影响,这是在实际应用中必须注意的。
BeanFactory
是Spring中⾮常核⼼的组件,表示Bean⼯⼚
,可以⽣成Bean,维护Bean,⽽ApplicationContext
继承了BeanFactory
,所以ApplicationContext
拥有BeanFactory
所有的特点,也是⼀个Bean⼯⼚,但是ApplicationContext
除了继承了BeanFactory之外,还继承了诸如EnvironmentCapable
、 MessageSource
、ApplicationEventPublisher
等接⼝,从⽽ApplicationContext
还有获取系统环境变量、国际化、事件发布等功能,这是BeanFactory所不具备的。
@Transactional
注解的Bean,Spring会创建⼀个代理对象作为Bean@Transactional
注解autocommit
属性为false
,禁⽌此连接的⾃动提交,这是实现Spring事务⾮常重要的⼀步image.png
因为Spring事务是基于代理来实现的,所以某个加了@Transactional
的⽅法只有是被代理对象调⽤时,那么这个注解才会⽣效,所以如果是被代理对象来调⽤这个⽅法,那么@Transactional是不会失效的。同时如果某个⽅法是private的,那么@Transactional也会失效,因为底层cglib是基于⽗⼦类来实现的,⼦类是不能重载⽗类的private
⽅法的,所以⽆法很好的利⽤代理,也会导致@Transactianal失效。具体失效的情况也可参考之前的文章:
Spring容器启动流程是怎样的
BeanDefinition
对象,并存在⼀个Map中BeanDefinition
进⾏创建Bean,对于多例Bean不需要在启动过程中去进⾏创建,对于多例Bean会在每次获取Bean时利⽤BeanDefinition去创建BeanDefinition
创建Bean就是Bean的创建⽣命周期,这期间包括了合并BeanDefinition、推断构造⽅法、实例化、属性填充、初始化前、初始化、初始化后等步骤,其中AOP就是发⽣在初始化后这⼀步骤中BeanFactoryPostProcessor
和BeanPostProcessor
的注册,Spring的扫描就是通过BenaFactoryPostProcessor
来实现的,依赖注⼊就是通过BeanPostProcessor
来实现的@Import
等注解image.png
DispatcherServlet
收到请求调⽤HandlerMapping
处理器映射器。DispatcherServlet
。DispatcherServlet
调⽤HandlerAdapter
处理器适配器。HandlerAdapter
经过适配调⽤具体的处理器(Controller,也叫后端控制器)Controller
执⾏完成返回ModelAndView
。HandlerAdapter
将controller
执⾏结果ModelAndView
返回给DispatcherServlet
。DispatcherServlet
将ModelAndView
传给ViewReslover
视图解析器。ViewReslover
解析后返回具体View
。DispatcherServlet
根据View
进⾏渲染视图(即将模型数据填充⾄视图中)。DispatcherServlet
响应⽤户。