Version: Spring 3.2
Context
-
Resource
- FileSystemResource
- ClasspathResource
- UrlResource
- InputStreamResource
- ByteArrayResource
-
XmlBeanFactory
- this.reader.loadBeanDefinitions(resource)
- loadBeanDefinitions(new EncodedResource(resource))
- doLoadBeanDefinitions(inputSource, encodedResource.getResource())
- getValidationModeForResource(resource): 获取XML文件的验证模式
- loadDocument(): 加载XML文件,并得到对应的Document // 自定义xsd验证文件放在META-INF/spring.schemas
- registerBeanDefinitions(doc, resource): 根据返回的Document注册Bean信息
- doRegisterBeanDefinitions(root)
- parseBeanDefinitions(root, this.delegate)
- parseDefaultElement(ele, delegate)
- delegate.parseCustomElement(ele)
- BeanDefinition
- RootBeanDefinition
- ChildBeanDefinition
- GenericBeanDefinition
- 创建用于属性承载的BeanDefinition
- 解析scope、singleton、abstract、lazy-init、autowire、dependency-check、depend-on、autowire-candidate、primary、init-method、destroy-method、factory-method、factory-bean属性
- 解析子元素meta、lookup-method、replaced-method、constructor-arg、property、qualifier
- 解析自定义标签元素:decorateBeanDefinitionIfRequired(ele, bdHolder)
- 遍历所有的属性和子节点,使用对应Namespace的Handler进行修饰
- 注册解析的BeanDefinition
- 通过beanName注册BeanDefinition
- 校验AbstractBeanDefinition的methodOverrides属性
- 处理beanName已经注册的情况
- 加入map缓存
- 清楚解析之前留下的beanName的缓存
- 通过别名注册BeanDefinition
- alias与beanName相同情况处理
- alias覆盖处理
- alias循环检查
- 注册alias
- 通过beanName注册BeanDefinition
- 通知监听器解析及注册完成
-
自定义标签
- 自定义标签使用
- 创建一个需要扩展的插件
- 定义一个XSD文件描述组件内容
- 创建一个文件,实现BeanDefinitionParser接口,用来解析XSD文件中的定义和组件定义
- 创建一个Handler文件,扩展自NamespaceHandlerSupport,将组件注册到Spring容器
- 编写Spring.handlers和Spring.schemas文件
- 自定义标签解析
- 获取对应的命名空间:getNamespceURI()
- 根据命名空间找到对应的NamespaceHandler:getHandlerMappings()
- 调用自定义的NamespceHandler进行解析:findParserForElement(element, parserContext).parse(element, parserContext)
- 自定义标签使用
-
bean的加载
-
(1)转换对应的beanName
(2)尝试从缓存中加载单例
(3)bean实例化
(4)原型模式的依赖检查
(5)检测parentBeanFactory
(6)将从XML读取的GernericBeanDefinition转换为RootBeanDefinition
(7)寻找依赖
(8)针对不同的scope进行bean的创建
(9)类型转换
-
FactoryBean的使用
- 通过实现FactoryBean的接口自定义配置文件注入的属性以快速注入bean
-
缓存中获取单例bean
- 首先尝试从singletonObjects里面获取实例
- 如果获取不到,再尝试从singletonFactories里面获取beanName对应的ObjectFactory
- 然后调用ObjectFactory的getObject方法创建bean,并放到earlySingletonObjects
- 并且从singletonFactories删除这个ObjectFactory
-
从bean的实例获取对象
-
getObjectForBeanInstance(beanInsance, name, beanName, mbd)
-
getObjectFromFactoryBean(factory, beanName, shouldPostProcess)
-
验证FactoryBean的正确性
-
对非FactoryBean不做任何处理
-
对bean进行转换
-
将从Factory中解析bean的工作委托给doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess)
-
尽可能保证所有bean初始化后都会调用注册的BeanPostProcessor的postProcessAfterInitialization方法进行处理
-
-
-
获取单例
- getSingleton(beanName, singletonFactory)
- 检查缓存是否已经加载过
- 若没有加载,则记录beanName的正在加载状态
- 加载单例前记录加载状态
- 通过调用参数传入的ObjectFactory的个体Object方法实例化bean
- 加载单例后的处理方法调用
- 将结果记录至缓存并删除加载bean过程中所记录的各种辅助状态
- 返回处理结果
- getSingleton(beanName, singletonFactory)
-
准备创建bean
- createBean(beanName, mbd, args)
- 根据设置的class属性或者根据className解析Class
- 对override属性进行标记及验证
- 应用初始化前的后处理器,解析指定bean是否存在初始化前的短路操作
- 创建bean
- 处理override属性(lookup-method、repalce-method)
- 在bean实例化的时候如果检测到存在methodOverrides属性,会动态地为当前bean生成代理并使用对应的拦截器为bean做增强处理
- 实例化的前置处理
- 实例化前的后处理器应用:applyBeanPostProcessorsBeforeInstantiation()
- 实例化后的后处理器应用:applyBeanPostProcessorsAfterInitialization()
- createBean(beanName, mbd, args)
-
循环依赖(两个或多个bean相互之间持有对方)
- 构造器循环依赖,只能抛出BeanCurrentlyInCreationException
- setter循环依赖,通过提前暴露一个单例工厂方法,从而使其他bean能引用该bean
- prototype范围的依赖,Spring容器无法完成依赖注入
-
创建bean
- 如果代理或提前改变了bean,直接在postProcessBeforeInstantiation方法执行后返回
- 常规创建,doCreateBean(beanName, mbd, args)
- 如果是单例则需要首先清除缓存
- 实例化bean,将BeanDefinition转换为BeanWrapper
- 如果存在工厂方法则使用工厂方法进行初始化
- 一个类有多个构造函数,每个构造函数都有不同的参数,所以需要根据参数锁定构造函数并进行初始化
- 如果既不存在工厂方法也不存在带有参数的构造函数,则使用默认的构造函数进行bean的实例化
- MergedBeanDefinitionPostPorcessor的应用(类型的预解析)
- 依赖处理,(注入ObjectFactory来创建实例,addSingletonFactory(beanName, getEarlyBeanReference(beanName, mbd, bean)))
- 属性填充(populateBean)
- 应用postProcessAfterInstantiation函数,可以控制程序是否继续进行属性填充
- 根据注入类型,提取依赖的bean,并统一存入PropertyValue中
- autowireByName
- autowireByType
- 应用postProcessPropertyValues方法,对属性获取完毕填充前对属性的再次处理
- 将所有PropertyValues中的属性填充至BeanWrapper中
- applyPropertyValues
- 循环依赖检查
- 注册DisposableBean
- 指定destroy-method或者注册后处理器DestructionAwareBeanPostProcessor
- 完成创建并返回
-
初始化bean
- 激活Aware方法,BeanFactoryAware, ApplicationConextAware, ResouceLoaderAware, ServletContextAware,实现这些接口的bean在初始化后,容器会注入相应的实例
- 处理器的应用,BeanPostProcessor
- 在调用自定义初始化方法前调用postProcessBeforeInitialization
- 在调用自定义初始化方法后调用postProcessAfterInitialization
- 激活自定义的init方法
- 实现InitializingBean接口,使用afterPropertiesSet实现自定义的初始化业务
- 配置init-method,指定初始化业务逻辑
-
容器的扩展功能
ApplicationContext bf = new ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent);
设置配置路径
支持多个配置文件以数组方式同时传入,对于变量会搜寻进行替换
扩展功能
- 初始化前的准备工作,例如对系统属性或者环境变量进行准备及验证
- 初始化BeanFactory,并进行XML读取
- 对BeanFactory进行各种功能填充
- 子类覆盖方法做额外的处理,可利用postProcessBeanFactory进一步扩展业务
- 激活各种BeanFactory处理器
- 注册拦截bean创建的bean处理器
- 为上下文初始化Message源,对不同语言的消息体进行国际化处理
- 初始化应用消息广播器,并放入“applicationEventMulticaster"bean中
- 留给子类来初始化其他的bean
- 在所有注册的bean中查找listener bean,注册到消息广播器中
- 初始化剩下的单实例(非惰性)
- 完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人
环境准备
- initPropertySource符合开放式结构设计,用户可以根据自身的需要重写initPropertySources方法,并在方法中进行个性化的属性处理及设置
- validateRequiredProperties则可以对属性进行验证
public class MyClassPathXmlApplicationContext extends ClassPathXmlApplicationContext {
public MyClassPathXmlApplicationContext(String... configLocations) {
super(configLocations);
}
protected void initPropertySources() {
// 添加验证要求
getEnvironment().setRequiredProperties("VAR");
}
}
加载BeanFactory
obtainFreshBeanFactory() -> refreshBeanFactory()
- 创建DefaultListableBeanFactory
- 指定序列化ID
- 定制BeanFactory
- 加载BeanDefinition
- 使用全局变量记录BeanFactory类实例
定制BeanFactory
- customizeBeanFactory()可以定制是否允许覆盖同名称不同定义的对象、是否允许bean之间存在循环依赖、用于@Qualifier和@Autowired的解析器
- 初始化XmlBeanDefinitionReader,并使用loadBeanDefinitions()方法进行配置文件的加载注册
功能扩展
通过函数prepareBeanFactory(ConfigurableListableBeanFactory beanFactory)扩展功能
- 增加对SpEL语言的支持
- beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver())
- 增加对属性编辑器的支持
- 增加对一些内置类的信息注入,如EnvironmentAware、MessageSourceAware
- beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this))
- ApplicationContextAwareProcessor实现了BeanPostProcessor接口
- 设置了依赖功能可忽略的接口
- beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class)
- 注册一些固定依赖的属性
- beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory)
- 增加AspectJ的支持
- 将相关环境变量及属性注册以单例模式注册
BeanFactory的后处理
激活注册的BeanFactoryPostProcessor
- 特殊处理BeanDefinitionRegistry
- 对于硬编码注册的后处理器,通过AbstractApplicationContext的addBeanFactoryPostProcessor进行添加
- 记录后处理器使用了三个List
- registryPostProcessors: 记录通过硬编码方式注册的BeanDefinitionRegistryPostProcessor类型的处理器
- regularPostProcessors: 记录通过硬编码方式注册的BeanFactoryPostProcessor类型的处理器
- registryPostProcessorBeans: 记录通过配置方式注册的BeanDefinitionRegistryPostProcessor类型的处理器
- 对以上所记录的后处理器进行统一调用BeanFactoryPostProcessor的postProcessBeanFactory方法
- 对beanFactoryPostProcessors中非BeanDefinitionRegistryPostProcessor类型的后处理进行统一的BeanFactoryPostProcessor的postProcessBeanFactory方法调用
- 普通beanFactory的处理
- 直接处理BeanFactoryPostProcessor,调用支持按照PriorityOrdered或者Ordered的顺序调用
注册BeanPostProcessor
- 将配置文件的BeanPostProcessor提取出来并注册进入beanFactory
- 支持根据PriorityOrdered或者Ordered进行排序或者无序
初始化消息资源
- 提取配置中定义的messageSource,并将其记录在Spring的容器AbstractApplicationContext中
- 在获取资源文件的时候直接使用
初始化ApplicationEventMulticaster
- 如果用户自定义了事件广播器,那么使用用户自定义的事件广播器
- 如果用户没有自定义事件广播器,使用默认的ApplicationEventMulticaster
- 产生Spring事件时,默认使用SimpleApplicationEventMulticaster的multicastEvent来广播事件,遍历所有监听器,并使用监听器中的onApplicationEvent方法来进行监听器的处理
注册监听器
protected void registerListeners() {
for (ApplicationListeners<?> listener: getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String lisName: listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(lisName);
}
}
初始化非延迟加载单例
- ConversionService的设置
- 实现Converter接口,注册到ConversionServiceFactoryBean中或添加到conversionService.addConverter()
- 冻结配置
// 冻结所有的bean定义,说明注册的bean定义将不被修改或进行任何进一步的处理
public void freezeConfiguration() {
this.configurationFrozen = true;
synchronized(this.beanDefinitionMap) {
this.frozenBeanDefinitionName = StringUtils.toStringArray(this.beanDefinitionNames);
}
}
- 初始化非延迟加载
- 默认在finishBeanFactoryInitialization中,将所有单例bean提前创建并配置。
finishRefresh
实现Lifecycle接口后Spring会保证在启动或者关闭的时候调用其start与stop方法,来开始或结束生命周期。
- initLifecycleProcessor(): 当ApplicationContext启动或停止时,它会通过LifecycleProcessor来与所有声明bean的周期做状态更新。
- onRefresh(): 启动所有实现了Lifecycle接口bean
- 当完成ApplicationContext初始化的时候,要通过Spring中的事件发布机制来发出ContextRefreshedEvent事件,以保证对应的监听器可以做进一步的逻辑处理
AOP
动态AOP自定义标签
注册解析器
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser())
注册AnnotationAwareAspectJAutoProxyCreator
- 注册或升级AnnotationAwareAspectJAutoProxyCreator:如果已经存在了自动代理创建器,而且存在的自动代理创建器与现在的不一致,那么根据优先级判断到底需要使用哪个
- 处理proxy-target-class以及expose-proxy属性
- proxy-target-class默认为false,表示使用jdk动态代理,被代理对象实现了至少一个接口,true则表示使用cglib动态代理,需要考虑到无法代理Final方法,并且需要cglib依赖
创建AOP代理
- 获取增强方法或者增强器:findCandidateAdvisors()
- this.aspectJAdvisorsBuilder.buildAspectJAdvisors()
- 获取所有在BeanFactory中注册的beanName
- 遍历所有beanName,找出声明AspectJ注解的类
- 对标记为AspectJ注解的类进行增强器的提取:this.advisorFactory.getAdvisors(factory)
- 普通增强器的获取
- 获取切点信息
- 根据切点信息生成增强
- AspectJMethodBeforeAdvice,放置在拦截器链中的MethodBeforeAdviceInterceptor中
- AspectJAfterAdvice,直接放置在拦截器链中
- 增加同步实例化增强器
- 获取DeclareParents注释
- 普通增强器的获取
- 将提取结果加入缓存
- this.aspectJAdvisorsBuilder.buildAspectJAdvisors()
- 寻找到匹配的增强器:findAdvisorsThatCanApply()
- 分开处理引介增强与普通增强
- canApply(Pointcut, targetClass, hasIntroductions)中进行匹配
- 创建代理
- 代理类的创建与处理:proxyFactory.getProxy(this.proxyClassLoader)
- 获取当前类中的属性
- 添加代理接口
- 封装Advisor并加入到ProxyFactory中:buildAdvisors()
- 设置要代理的类
- 提供定制函数customizeProxyFactory
- 进行获取代理操作
- 代理创建与获取
- 创建
- optimize: 控制通过cglib创建的代理是否使用激进的优化策略
- proxyTargetClass: 设置代理方式
- hasNoUserSuppliedProxyInterfaces: 是否存在代理接口
- 如果目标对象实现了接口,默认使用JDK代理
- 如果目标对象实现了接口,可以强制使用cglib代理
- 如果目标对象没有实现接口,必须采用cglib库,Spring会自动在jdk代理与cglib代理之间转换
- 获取代理
- JDK: Proxy.newProxyInstance(classLoader, proxiedInterface, this)
- invoke()方法创建了拦截器链,并使用ReflectiveMethodInvocation进行封装,其proceed方法实现了拦截器的逐一调用
- CGLIB: Enhancer.create()
- enhancer.setCallback(new MethodInterceptorImpl),将拦截器封装在DynamicAdvisedInterceptor并加入callbacks中,通过getCallbacks()设置拦截器链CglibMethodInvocaiton,其继承自ReflectiveMethodInvocation
- JDK: Proxy.newProxyInstance(classLoader, proxiedInterface, this)
- 创建
- 代理类的创建与处理:proxyFactory.getProxy(this.proxyClassLoader)
事务
事务自定义标签
public void init() {
registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
}
根据mode属性进行判断,决定是使用AspectJ方式还是proxy方式进行事务切入
注册InfrastructureAdvisorAutoProxyCreator
AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parentContext, element);
-
new RootBeanDefinition(AnnotationTransactionAttributeSource.class)
-
new RootBeanDefinition(TransactionInterceptor.class)
-
new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class)
-
AopConfigUtils.registerAutoProxyCreatorIfNecessary()
- registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source)
- the class registered implemented the postProcessAfterInitialization(bean, beanName)
- wrapIfNecessary(bean, beanName, cacheKey)
- 找出指定bean对应的增强器
- 根据找出的增强器创建代理
- wrapIfNecessary(bean, beanName, cacheKey)
获取对应class/method的增强器
- getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource)
- 寻找候选增强器:findCandidateAdvisors()
- BeanFactoryUtils.beanNameForTypeIncludingAncestors(this. beanFactory, Advisor.class, true, false);
- advisors.add(this.beanFactory.getBean(name, Advisor.class))
- 候选增强器中寻找匹配项:findAdvisorsThatCanApply(candidateAdvisors, clazz)
- 获取对应类的所有接口并连同类本身一起遍历
- 遍历过程中又对类中的方法再次遍历,一旦匹配成功便认为这个类适用于当前增强器
- 提取事务标签:computeTransactionAttribute(method, targetClass)
- findTransactionAttribute(specificMethod)
- findTransactionAttribute(specificMethod.getDeclaringClass())
- 寻找候选增强器:findCandidateAdvisors()
总结
- 当在某个类中找到了事务属性,则它是与事务增强器(BeanFactoryTransactionAttributeSourceAdvisor)匹配的,也就会被事务功能修饰
- 作为Advisor的实现类,当代理被调用时会调用这个类的增强方法,此bean的Advice,又因为在该类中注入了TransactionInterceptor类型的bean
- 首先执行TransactionInterceptor进行增强,也就是调用其invoke方法完成事务逻辑
事务增强器
声明式事务处理
- 获取事务的属性
- 加载配置中配置的TransactionManager
- 不同的事务处理方式使用不同的逻辑(编程式事务处理不需要属性,CallbackPreferringPlatformTransactionManager实现PlatformTransactionManager接口)
- 在目标方法执行前获取事务并收集事务信息(TransactionInfo包含TransactionAttribute、PlatformTransactionManager以及TransactionStatus相关信息)
- 执行目标方法
- 出现异常尝试异常处理(只对RuntimeException回滚)
- 提交事务前的事务信息清除
- 提交事务
创建事务
-
创建事务:createTransactionIfNecessary(tm, txAttrr, joinpointIndentification)
- 使用DelegatingTransactionAttribute封装传入的TransactionAttribute实例
- 获取事务:getTransaction(definition)
- 创建对应的事务实例:doGetTransaction()
- 如果当前线层存在事务,转向嵌套事务的处理:handleExistingTransaction(definition, transaction, debugEnabled)
- REQUIRES_NEW,启动一个新的事务,如果有一个事务在运行,则会被挂起直到当前事务执行完毕进行复原
- NESTED,如果当前有一个事务正在运行,则该方法运行在一个嵌套的事务中,被嵌套的事务可以独立于封装事务进行提交或者回滚,如果封装事务不存在,类似REQUIRES_NEW处理
- Spring允许嵌入事务的时候,首选设置保存点的方式作为异常处理的回滚
- 对于其他方式,处理方式与REQUIRES_NEW相同,一旦出现异常由Spring的事务异常处理机制完成后续操作
- 事务超时设置验证
- 事务propagationBehavior属性的设置验证
- 构建DefautTransactionStatus
- 完善transaction,包括设置ConnectionHolder、隔离级别、timeout,如果是新连接,则绑定到当前线程:doBegin(transaction, definition)
- 尝试获取连接
- 设置隔离级别以及只读标识
- 更改默认的提交设置
- 标识当前连接已经被事务激活
- 设置过期时间
- 将connectionHolder绑定到当前线程
- 将事务信息记录在当前线程中
- 构建事务信息:prepareTransactionInfo(tm, txAttr, joinpointIdentification, status)
- 将所有的事务信息统一记录在TransactionInfo中
- 包含了目标方法开始前所有的状态信息
- 一旦事务执行失败,Spring会通过TransactionInfo类型实例中的信息进行回滚等工作
回滚处理
- 回滚条件
- 默认只处理RuntimeException和Error两种情况
- 通过属性设置rollbackFor进行扩展
- 回滚处理:rollback(status)
- 调用自定义触发器,包括在回滚前、完成回滚后的调用,出现异常触发器也会进行处理
- 当之前已经保存的事务信息中有保存点信息的时候,使用保存点信息进行回滚。内嵌的事务异常并不会引起外部事务的回滚
- 当之前已经保存的事务信息中的事务为新事物,那么直接回滚,常用于单独事务的处理,对于没有保存点的回滚,Spring同样适用底层数据库连接提供的API来操作的
- 当前事务信息中表明存在事务又不属于以上两种情况,多用于JTA,只做回滚标识,统一不提交
- 回滚后的信息清除
- 设置状态以对事务信息完成标识以避免重复调用
- 如果当前事务是新的同步状态,需要将绑定到当前线程的事务信息清除
- 如果是新事物需要做些清除资源的工作:doCleanupAfterCompletion(transaction)
- 恢复数据库连接的自动提交属性
- 重置数据连接
- 如果当前事务是独立新创建的事务则在事务完成时释放数据库连接
- 如果在事务执行前有事务挂起,那么当前事务执行结束后需要将挂起事务恢复:resume(transaction, resourcesHolder)
- 事务提交:commitTransactionAfterReturing(txInfo)
- 在真正提交数据前,当某个事务既没有保存点又不是新事物,Spring通过设置回滚标识的方式禁止提交,等到外部事务提交时,一旦判断当前事务被设置了回滚标识,则由外部事物来统一进行整体事务的回滚
- 执行一切正常的时候,可以真正进入提交流程了:processCommit(status),主要考虑内嵌事务的执行,会在其开始之前设置保存点,一旦内嵌事务出现异常根据保存点信息进行回滚,如果没有出现异常,由最外层事务负责提交
- 当事务状态中有保存点信息的话不回去提交事务
- 当事务非新事物的时候也不会去执行提交事务操作
Spring消息
JMS的独立使用
- 发送端先开启,向服务器发送消息
- 接收端后开启,会接收到发送端发出的消息
Spring整合ActiveMQ
- Spring配置文件
- ActiveMQConnectionFactory
- JmsTemplate
- ActiveMQQueue
- 发送端
- jmsTemplate.send(destination, message)
- 接收端
- jmsTemplate.receive(destination)
- 创建消息监听器:Implements MessageListener
- 修改配置文件:将factory、destination、listener统一加入注册的DefaultMessageListenerContainer
源码分析
- JmsTemplate
- 通用代码抽取:execute(action, startConnection)
- 创建connection
- 根据connection创建session
- 判断是否需要推送连接信息
- 调用回调函数
- 关闭session
- 释放连接
- 发送消息的实现:doSend(session, destination, messageCreator)
- 根据Destination创建MessageProducer
- 创建Message
- 使用MessageProducer实例发送消息
- 接收消息:receiveSelected(destination, null)
- doReceive(session, consumer)
- doReceive(consumer, timeout)
- 通用代码抽取:execute(action, startConnection)
- 监听器容器,用于查看JMS目标等待消息到达的特殊bean,通过调用onMessage()方法将消息传递给一个MessageListener实现
- SimpleMessageListenerContainer: 只能处理固定数量的JMS会话,且不支持事务
- DefaultMessageListenerContainer: 建立在上一个类型的容器之上,添加了对事务的支持
- 实例化接口中使用了concurrentConsumers属性,根据其数量建立对应的线程:scheduleNewInvoker(),rescheduleTaskIfNecessary(task)
- AsyncMessageListenerInvoker,作为一个Runnable执行
- 根据每个任务设置的最大处理消息数量而作不同处理,小于0默认无限制
- executeOngoingLoop()
- isRunning用来检测running状态是否需要进入while循环,引入了wasWaiting变量,用来判断线程是否处于等待状态
- 如果首次进入等待状态,需要减少线程激活数量计数器
- 线程等待采用全局控制变量lifecycleMonitor的wait方法暂停线程
- invokeListener()::receiveAndExecute(invoker, session, consumer)
- 如果用户配置了this.transactionManager,消息的接收会被控制在事务之内,一旦出现任何异常都会被回滚:this.transactionManager.rollback(status)
- doReceiveAndExecute()
- doExecuteListener(session, message)
- 层层最终调用listener.onMessage(message)激活监听器
- commitIfNecessary(session, message)提交消息本身的事务,告诉消息服务器消息已被接收,可以删除
- serversession.ServerSessionMessage.ListenerContainer: 支持事务,也允许动态地管理JMS会话