在3.0版本中,对一些容器的生命周期的处理做了不小的改变,包括:
- DefaultMessageListenerContainer
- GenericMessageEndpointManager
- JmsMessageEndpointManager
- SchedulerFactoryBean
- SimpleMessageListenerContainer
这些容器实现了一个叫SmartLifecycle的新接口,能够自动启动。看名字就很智能,它用一种新的方式来管理启动顺序,在application context初始化结束后,开始初始化这些容器,如果isAutoStartup()为true,通过getPhase()来确认启动顺序,值越小就优先启动,关闭时相反,下面是实现:
private void startBeans(boolean autoStartupOnly) {
Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
Map<Integer, LifecycleGroup> phases = new HashMap<Integer, LifecycleGroup>();
for (Map.Entry<String, ? extends Lifecycle> entry : lifecycleBeans.entrySet()) {
Lifecycle lifecycle = entry.getValue();
if (!autoStartupOnly || (lifecycle instanceof SmartLifecycle && ((SmartLifecycle) lifecycle).isAutoStartup())) {
int phase = getPhase(lifecycle);
LifecycleGroup group = phases.get(phase);
if (group == null) {
group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans);
phases.put(phase, group);
}
group.add(entry.getKey(), lifecycle);
}
}
if (phases.size() > 0) {
List<Integer> keys = new ArrayList<Integer>(phases.keySet());
Collections.sort(keys);
for (Integer key : keys) {
phases.get(key).start();
}
}
}
可以看到根据phase的值,分组到LifecycleGroup中,然后自然排序,调用start()方法初始化(无视bean的lazy-init为true)。默认phase的值设为Integer.MAX_VALUE,说明是最晚进行处理的。
这种处理方式非常优雅,但依赖于Spring2.5版本的项目迁移过来时,问题就来了。其实项目中已经实现了类似上面的处理流程,就是注册一个ContextRefreshedEvent事件监听器,事件触发时说明容器已经初始化结束了,使用的是DefaultMessageListenerContainer,这个容器需要通过编程方式实例化的,而不是配置在xml文件中,这样更加灵活。在2.5版本中,DefaultMessageListenerContainer的afterPropertiesSet()方法会调用doStart()开始接收消息,但在3.0版本中由于流程改变,下面这段代码在initialize()中已经被去掉:
if (this.autoStartup) {
doStart();
}
doInitialize();
而生命周期是先于ApplicationEvent前执行的,看下面代码就很清楚了:
protected void finishRefresh() {
// Initialize lifecycle processor for this context.
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// Publish the final event.
publishEvent(new ContextRefreshedEvent(this));
}
这样,这样处理的之后,问题就来了:
本来在创建单例对象回调afterPropertiesSet()中开始接受消息,现在延后了
spring准备在SmartLifecycle中初始化DefaultMessageListenerContainer准备接受消息时,由于对象是在ContextRefreshedEvent中创建的,此时getLifecycleBeans()还没有任何bean
触发ContextRefreshedEvent事件后需要的对象都创建好了,spring已经不鸟你了
这样的结果是整个流程中没有没有知道到DefaultMessageListenerContainer的start()方法,所有程序启动后不会监控任何的MQ服务器。
问题找到了,解决就简单了(大半个下午也没了-_-!),用spring的SmartLifecycle方式来处理,以前的那陀实现删光光。
分享到:
相关推荐
### 整合Flex与Spring常遇到的问题 在实际开发过程中,将Adobe Flex与Spring框架进行集成是一项复杂的任务,尤其对于初次尝试的开发者来说更是如此。本文根据多年的实践经验,总结了在整合Flex与Spring时常见的几个...
Spring 2到Spring 3的升级反映了框架为了满足不断变化的Java开发需求所做的适应和创新。通过深入研究这些文档,开发者可以了解到Spring如何处理依赖注入,如何利用AOP实现横切关注点,以及如何构建高效、松耦合的...
博主可能还会讨论在Spring 2.x中遇到的挑战,比如JUnit3与Spring的集成,以及如何在没有注解支持的情况下管理测试环境。此外,可能还会提及升级到JUnit4或其他现代测试库的可能性和步骤,因为这在当时是一个常见的...
在使用Spring Data Elasticsearch框架时,可能会遇到一个常见的问题,即版本兼容性问题。Spring Data Elasticsearch 5.4.0设计时可能并未考虑到与Elasticsearch 5.4.1的完全兼容,导致在升级Elasticsearch到5.4.1后...
然而,随着Java版本的升级,有时候不同版本的Spring和JDK之间可能会出现兼容性问题。在本例中,我们讨论的是Spring 3.2.0版本与JDK 1.8之间的冲突。 Spring 3.2.0发布于2012年,那时JDK 1.8尚未推出(JDK 1.8在2014...
以下是升级过程中可能遇到的问题和解决方案。 Eureka Server 依赖更新 在升级到 Finchley 版本时,Eureka Server 的依赖需要更新。升级前,依赖的是 `spring-cloud-starter-eureka-server`,升级后需要依赖 `...
在升级Spring Cloud应用到Spring Boot 2.x及Finchley.RELEASE版本时,开发者可能会遇到一系列挑战。本文将深入探讨这些挑战以及如何解决它们。 首先,Spring Boot 2.x引入了对Java 8的最低需求,这意味着如果您的...
Spring ROO是一个基于Java的工具,它简化了...此外,如果在升级过程中遇到问题,查阅官方文档或社区资源通常都能找到解决方案。保持你的开发环境和依赖库的最新状态,有助于利用最新的特性和性能优化,提升开发效率。
值得注意的是,部分依赖如Druid数据库连接池和P6Spy SQL查询日志记录器的版本注释为“升级失败,下次再升”,表明这些依赖可能在尝试升级过程中遇到了问题,未来计划再次尝试升级。 此配置还包含了一些未升级的依赖...
同时,理解源码有助于我们在遇到问题时,能更快地定位和解决问题。 总结,Spring Framework 4.3.17的源码是一份宝贵的教育资源,它揭示了Spring的内在设计原则和实现细节。对于Java开发者来说,深入学习并掌握这...
他还分享了解决数据库读写分离、错误处理、依赖注入失效等问题的经验,以及在特定环境下如IDEA内嵌Jetty运行Spring项目时可能遇到的异常处理。 总的来说,这些内容涵盖了Spring的多个重要方面,包括事务管理、AOP、...
10. **文档和社区支持**:Spring框架有着丰富的官方文档和活跃的社区支持,遇到问题时,开发者可以找到大量资源和解决方案。 总的来说,Spring 5.2.8.RELEASE不仅是一个稳定的版本,也是Spring框架发展的重要里程碑...
标题中的"spring-cglib-repack-3.2.2.jar"和"spring-objenesis-repack-2.2.jar"是两个重要的Java库,它们...如果在构建Spring项目时遇到问题,检查这些依赖是否正确引入和匹配项目的其他依赖,可以避免很多潜在的问题。
在Eclipse Spring IDE的压缩包中,readme.txt可能包含了关于如何安装和使用此插件的详细步骤,以及可能遇到的问题和解决办法。 **springide-1.3.6**:这可能是Eclipse Spring IDE的一个特定版本号。版本号中的数字...
- **常见问题解答**:汇总了开发者在使用过程中可能遇到的问题及解决办法。 - **项目地址**:给出了SpringBlade及其相关项目的GitHub地址,便于用户获取最新源码和支持。 #### 五、工程结构解析 - **blade-auth**:...
当处理过程中遇到错误时,Spring Batch 提供了多种策略,如跳过错误记录、重新执行失败步骤甚至整个作业。 5. **作业调度** 通过集成Quartz、Spring Integration或其他调度工具,可以方便地安排批处理作业的执行...
通过阅读文档,开发者可以快速掌握Spring.NET的关键概念和使用方法,解决开发过程中遇到的问题。 在开始使用Spring.NET 2.0.0之前,建议先通读中文参考文档,理解框架的基本结构和核心概念。然后,可以逐步将Spring...
Spring Boot是一个开源Java基础框架,它用于简化Spring应用的初始搭建以及开发...同时,官方参考手册为开发过程中可能遇到的各种情况提供了详尽的指导和示例,帮助开发者在实际开发中遇到问题时能够迅速找到解决方案。
SpringBlade致力于创造新颖的开发模式,整理归纳开发中遇到的痛点和生产中的坑,并将解决方案融合到框架中。Sword是SpringBlade前端UI框架,主要技术选型为React、Ant Design、Umi、Dva。Saber核心框架项目地址,...
在Spring框架的运作过程中,有时会遇到由于类加载器或依赖冲突导致的问题,特别是涉及到动态代理的时候。在本资源包中,包含的是针对此类问题的解决方案——`spring-cglib-repack`和`spring-objenesis-repack`。 ...