在这篇文章中我想分享我最近遇到的一个问题,我想您可能会感兴趣。
出了什么问题?
测试环境和生产环境的源代码是相同的,本地和测试环境都运行良好,只有生产环境运行的服务类的NPE加载失败,这是为了新的需求而添加的。该类继承自Customize包(自研工具包)的接口。
项目结构
Customize 的设计依赖于 Spring 来管理 API 和服务。通过Spring自动扫描,初始化类时会加载ApiEnhancer和ServiceEnhancer的公共类,并通过ApplicationContext获取实例。调试发现加载它们时,ApplicationContext为null,还没有初始化。是在setApplicationContext方法中通过实现ApplicationContextAware来初始化的,所以推测setApplicationContext方法还没有被执行。
在ApplicationContextProvider类的加载过程中,静态方法在初始化阶段被加载到方法区中。然而,当使用ApplicationContext获取bean的实例时,静态方法是直接通过类名调用的。只要API是在ApplicationContextProvider在堆中分配内存并实例化之前创建的,就不会调用setApplicationContext方法进行初始化。
applicationContextProvider使用注解@Component,Api使用注解@RestController,两个类在同一个路径下。然而,当 Spring 扫描并加载它们时,没有特定的顺序,这意味着这两个类中的每一个都可能在另一个类之前创建。在生产环境中,Api是先于applicationContextProvider创建的,导致通过类名直接调用静态方法获取bean时,applicationContext没有被初始化。
解决方案
如果没有执行ApplicationContextAware接口的实现类的setApplicationContext方法,首先检查该实现类是否设置了延迟加载或者项目是否配置了全局延迟加载。
在这个项目中,问题是由ApiEnhancer和ApplicationContextAware接口的实现类的创建顺序引起的,而Api类只是一个常规的RESTful API,处理业务逻辑,可以在前端调用时加载-结束页。因此,改为延迟加载解决了问题。
建议在加载顺序方面尽量减少类之间的依赖关系。如果不可避免,可以使用延迟加载,或者使用@DependsOn、@Order、@Priority等注解来控制bean的加载顺序
为什么生产环境和测试环境的创建顺序不同?
我们来调试一下Spring的扫描过程。
从ClassPathBeanDeterminationScanner的scan方法开始。
doScan方法
ClassPathScanningCandidateComponentProvider 的 scanCandidateComponents 方法
PathMatchingResourcePatternResolver 的 findAllClassPathResources 方法
doFindPathMatchingJarResources 方法
JarFile是Java标准库中java.util.jar包下的一个类,它继承并扩展了ZipFile。 jarFile.entries() 返回一个名为 JarEntryIterator 的迭代器。
JarExitIterator 是 迭代器模式 的实现,它迭代 JarFile 父类的条目。
ZipFile 的 Entry 方法返回一个名为 ZipExitIterator 的迭代器。
ZipExitIterator 的 nextElement 方法调用 next 方法,后者又调用 getNextEntry 方法。
getNextEntry 是一个原生方法。
native 方法是用非 Java 语言实现的,并在 Java 虚拟机内调用来实现底层功能,这可能会因环境(操作系统或 JDK 版本)而异。 JAR包本身没有顺序,所以实际的遍历顺序可能会根据不同的JAR打包工具和环境而有所不同。
以上是applicationContextAware接口的setApplicationContext方法执行问题,获取Spring bean失败的详细内容。更多信息请关注PHP中文网其他相关文章!

本文讨论了使用咖啡因和Guava缓存在Java中实施多层缓存以提高应用程序性能。它涵盖设置,集成和绩效优势,以及配置和驱逐政策管理最佳PRA

Java的类上载涉及使用带有引导,扩展程序和应用程序类负载器的分层系统加载,链接和初始化类。父代授权模型确保首先加载核心类别,从而影响自定义类LOA

本文使用lambda表达式,流API,方法参考和可选探索将功能编程集成到Java中。 它突出显示了通过简洁性和不变性改善代码可读性和可维护性等好处

本文讨论了使用JPA进行对象相关映射,并具有高级功能,例如缓存和懒惰加载。它涵盖了设置,实体映射和优化性能的最佳实践,同时突出潜在的陷阱。[159个字符]

本文讨论了使用Maven和Gradle进行Java项目管理,构建自动化和依赖性解决方案,以比较其方法和优化策略。

本文使用选择器和频道使用单个线程有效地处理多个连接的Java的NIO API,用于非阻滞I/O。 它详细介绍了过程,好处(可伸缩性,性能)和潜在的陷阱(复杂性,

本文使用Maven和Gradle之类的工具讨论了具有适当的版本控制和依赖关系管理的自定义Java库(JAR文件)的创建和使用。

本文详细介绍了用于网络通信的Java的套接字API,涵盖了客户服务器设置,数据处理和关键考虑因素,例如资源管理,错误处理和安全性。 它还探索了性能优化技术,我


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

MinGW - 适用于 Windows 的极简 GNU
这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

安全考试浏览器
Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

适用于 Eclipse 的 SAP NetWeaver 服务器适配器
将Eclipse与SAP NetWeaver应用服务器集成。

SublimeText3 英文版
推荐:为Win版本,支持代码提示!

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),