Spring源码深度解析概览

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
    • 通知监听器解析及注册完成
  • 自定义标签

    • 自定义标签使用
      • 创建一个需要扩展的插件
      • 定义一个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过程中所记录的各种辅助状态
        • 返回处理结果
    • 准备创建bean

      • createBean(beanName, mbd, args)
        • 根据设置的class属性或者根据className解析Class
        • 对override属性进行标记及验证
        • 应用初始化前的后处理器,解析指定bean是否存在初始化前的短路操作
        • 创建bean
      • 处理override属性(lookup-method、repalce-method)
        • 在bean实例化的时候如果检测到存在methodOverrides属性,会动态地为当前bean生成代理并使用对应的拦截器为bean做增强处理
      • 实例化的前置处理
        • 实例化前的后处理器应用:applyBeanPostProcessorsBeforeInstantiation()
        • 实例化后的后处理器应用:applyBeanPostProcessorsAfterInitialization()
    • 循环依赖(两个或多个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通知别人
环境准备
  1. initPropertySource符合开放式结构设计,用户可以根据自身的需要重写initPropertySources方法,并在方法中进行个性化的属性处理及设置
  2. 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)扩展功能

  1. 增加对SpEL语言的支持
    • beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver())
  2. 增加对属性编辑器的支持
  3. 增加对一些内置类的信息注入,如EnvironmentAware、MessageSourceAware
    • beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this))
    • ApplicationContextAwareProcessor实现了BeanPostProcessor接口
  4. 设置了依赖功能可忽略的接口
    • beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class)
  5. 注册一些固定依赖的属性
    • beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory)
  6. 增加AspectJ的支持
  7. 将相关环境变量及属性注册以单例模式注册
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);
    }
}
初始化非延迟加载单例
  1. ConversionService的设置
    • 实现Converter接口,注册到ConversionServiceFactoryBean中或添加到conversionService.addConverter()
  2. 冻结配置
// 冻结所有的bean定义,说明注册的bean定义将不被修改或进行任何进一步的处理
public void freezeConfiguration() {
	this.configurationFrozen = true;
	synchronized(this.beanDefinitionMap) {
		this.frozenBeanDefinitionName = StringUtils.toStringArray(this.beanDefinitionNames);
	}
}
  1. 初始化非延迟加载
    • 默认在finishBeanFactoryInitialization中,将所有单例bean提前创建并配置。
finishRefresh

实现Lifecycle接口后Spring会保证在启动或者关闭的时候调用其start与stop方法,来开始或结束生命周期。

  1. initLifecycleProcessor(): 当ApplicationContext启动或停止时,它会通过LifecycleProcessor来与所有声明bean的周期做状态更新。
  2. onRefresh(): 启动所有实现了Lifecycle接口bean
  3. 当完成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注释
      • 将提取结果加入缓存
  • 寻找到匹配的增强器: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

事务

事务自定义标签
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对应的增强器
        • 根据找出的增强器创建代理

获取对应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())

总结

  1. 当在某个类中找到了事务属性,则它是与事务增强器(BeanFactoryTransactionAttributeSourceAdvisor)匹配的,也就会被事务功能修饰
  2. 作为Advisor的实现类,当代理被调用时会调用这个类的增强方法,此bean的Advice,又因为在该类中注入了TransactionInterceptor类型的bean
  3. 首先执行TransactionInterceptor进行增强,也就是调用其invoke方法完成事务逻辑
事务增强器

声明式事务处理

  1. 获取事务的属性
  2. 加载配置中配置的TransactionManager
  3. 不同的事务处理方式使用不同的逻辑(编程式事务处理不需要属性,CallbackPreferringPlatformTransactionManager实现PlatformTransactionManager接口)
  4. 在目标方法执行前获取事务并收集事务信息(TransactionInfo包含TransactionAttribute、PlatformTransactionManager以及TransactionStatus相关信息)
  5. 执行目标方法
  6. 出现异常尝试异常处理(只对RuntimeException回滚)
  7. 提交事务前的事务信息清除
  8. 提交事务

创建事务

  • 创建事务: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)
  1. 创建消息监听器:Implements MessageListener
  2. 修改配置文件:将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)
  • 监听器容器,用于查看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会话
  • 10
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值