name
arthas-springcontext-issues-resolve
description
排查 Spring ApplicationContext / Bean / 配置注入等问题
Spring Context / Bean 排查指南
原则:
先只读查询
(contains/beanNames/type/environment),避免直接
getBean()
触发 Bean 初始化产生副作用。
严格限量
:
vmtool -l
控制实例数量;避免无条件输出完整
getBeanDefinitionNames()
。
- 获取并挑选正确的 ApplicationContext
优先尝试获取常见的 Spring Boot Context(通常是
AbstractApplicationContext
子类):
vmtool --action getInstances --className org.springframework.context.support.AbstractApplicationContext -l 5
如果拿不到结果,可以尝试获取: org.springframework.context.ApplicationContext
如果获取到多个对象,可以从对象的 classloader 的 Class<?> name 来判断。
应用的 ClassLoader 通常是包含
LaunchedURLClassLoader
应用的 ClassLoader 绝不会是 com.taobao.pandora.service.loader.ModuleClassLoader
- 获取配置项的值与来源
只看值(示例:
server.port
):
vmtool --action getInstances --className org.springframework.context.support.AbstractApplicationContext -l 1 --express
'instances[0].getEnvironment().getProperty("server.port")'
获取“来源”
vmtool --action getInstances --className org.springframework.context.support.AbstractApplicationContext -l 1 --express
'#env=instances[0].getEnvironment(), #ps=#env.getPropertySources().get("configurationProperties"), #ps.findConfigurationProperty("server.port")'
如果应用有集成 spring-boot-starter-actuator ,可以尝试
vmtool --action getInstances
--className org.springframework.boot.actuate.env.EnvironmentEndpoint
--express
'instances[0].environmentEntry("server.port")'
- 按 Bean Name 验证是否存在(不触发初始化)
假设你要查的 beanName 为
fooService
:
vmtool --action getInstances --className org.springframework.context.support.AbstractApplicationContext -l 1 --express
'instances[0].containsBean("fooService")'
vmtool --action getInstances --className org.springframework.context.support.AbstractApplicationContext -l 1 --express
'instances[0].containsLocalBean("fooService")'
vmtool --action getInstances --className org.springframework.context.support.AbstractApplicationContext -l 1 --express
'instances[0].containsBeanDefinition("fooService")'
vmtool --action getInstances --className org.springframework.context.support.AbstractApplicationContext -l 1 --express
'instances[0].getAliases("fooService")'
判读:
containsBean=true
但
containsLocalBean=false
:Bean 可能来自
父 Context
。
containsBean=false
且你确定应该存在:优先检查
是否选错 Context
、
@Profile/@Conditional
、配置项/环境变量是否生效。