服务端期望使用 面向对象编程, 和 spring 结合的话只能是通过 prototype 的 bean 定义,并通过 getBean 获取.

优雅停机探究:

     代码说明:

1. 类关系 SimpleSpringTest PrototypeScopeBean

         2. 执行流程: SimpleSpringTest内的方法通过getBean 获取prototype的 bean. 内有有线程池执行相关逻辑.

3. 两个类对实现了 spring 的关闭事件通知

4. 先上层SimpleSpringTest关闭连接,然后内部PrototypeScopeBean关闭线程shutdown.保证所有线程都执行完才退出. [ 否则由于内存无持久化,导致相关数据和流程丢失.分布式问题. 最好通过 mq 发送. ]

     操作流程:

1. 启动代码

2.关闭代码

3. 正常结果: 按预期顺序关闭. 暂停3秒后,输出对应的关闭日志

异常:

1. 都打印出了对应的关闭日志.但是没有暂停3秒.

深入探究:

1.  对应的线程池里并没有执行 worker. 还以为我自己对线程池的 shutdown和 await 的理解错误了. 细细又看了一遍源码.还研究了下interruptIdleWorkers里的线程 interrupt方法,把对应线程都中断了. 但是runnable 的 sleep又没有打印出被interrupt的错误日志. 以为自己对interrupt 理解错了.又学习了一遍interrupt.

2. 最终发现原来的PrototypeScopeBean和 close 时的PrototypeScopeBean不是同一个 bean

3. 回过头看 spring 的关闭流程代码.

    发现发起 event 时会回调

1. sington 实例,

2. get 新的 prototype bean

而我的线程池是非 static 的,导致出错. 无法完成优雅关闭.

从prototype beandefinition 谈 spring 的关闭流程和 prototype 的特性

 

从prototype beandefinition 谈 spring 的关闭流程和 prototype 的特性

 

 

 

xml 配置的都会生成新的 bean 定义.

从prototype beandefinition 谈 spring 的关闭流程和 prototype 的特性

发现了通知的 list,通过

defaultRetriever.applicationListeners  笔者注释: 实现了 listener 的sington 的实例.

NOTE: 如果 bean 有@scope 的 prototype 注解,但是 xml 里又配置了 <bean,id 不一致> 但是没有配置 scope. 会生成两个 beanDefinition,且一个是 sington,一个是 prototype. 注解不影响 xml 的属性. 单例的实例会主动生成.

defaultRetriever.applicationListenerBeans 笔者注释:  字符串 ,所有实现了listener的 beanDefinition Name

NOTE:每个在 annotation 注解 和 xml 配置解析后都会生成一个 beanDefinition. 只有sington才会生成直接生成实例. 可在 getBean(class)的代码里证明.

总结:

1.  beanDefinition 何时生成?

id 是@service 的 value, xml 配置里的 id .一个sington 配置两遍,会有两个 beanDefinition. 注解解析也有. 同时生成. 如果 id 一致,xml 会覆盖注解.

2. 实例何时生成?

 singoton: xml 定义解析时,注解解析时

 prototype: getBean 时. 一旦有多个 beanDefinition,通过getBean(class)会报错 bean 数量不对.

3. spring 事件通知通知哪些对象?

1. 所有继承了 listener 的 sington 实例

2. 新建一个 prototype 的实例,并且调用. 所以 prototype 里被事件处理的东西最好是 static 的. 不然没有意义.这点面向对象写法容易出错,且容易内存泄露.新建大量的线程池.线程池何时被回收.?

4. prototype的特点是什么?

  1.  getBean("name")时 或者被注入autowired injected时会自动生成一个 bean

      2. getBean(class) 在只有一个 beanDefinition 时不会抛错. 不要 xml 写了一个,注解又有一个.

          NOTE: 这个接口会有锁,并发下性能比较差. 3.1.2

附录:

   事件通知堆栈:

  • "Thread-0"@2,180 in group "main": RUNNING
  • onApplicationEvent():48, PrototypeScopeBean {com...test.unmock.test}
  • onApplicationEvent():15, PrototypeScopeBean {com..test.unmock.test}
  • multicastEvent():97, SimpleApplicationEventMulticaster {org.springframework.context.event}
  • publishEvent():324, AbstractApplicationContext {org.springframework.context.support}
  • doClose():1025, AbstractApplicationContext {org.springframework.context.support}
  • run():958, AbstractApplicationContext$1 {org.springframework.context.support}

 

 

 

从线上问题谈spring生命周期类lifeCycle类和bean的生命周期 

 

相关文章:

  • 2021-11-06
  • 2022-12-23
  • 2022-01-04
  • 2022-12-23
  • 2021-07-25
  • 2022-02-24
  • 2021-11-21
  • 2021-09-24
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-05-24
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案