2. Plugin 로딩 구조
전체 흐름
ApplicationContextModuleFactory
-> ApplicationContextModule
-> PluginJarsProvider
-> PluginClassLoaderProvider
-> PluginContextLoadResult
-> DefaultPluginContextLoadResult
-> ProfilerPluginLoader.load(pluginClassLoader)
-> DefaultProfilerPluginContextLoader.load(...)
-> DefaultPluginSetup.setupPlugin(...)
-> ProfilerPlugin.setup(...)
-> PluginSetupResult
이름 때문에 헷갈릴 수 있는데, PluginModule은 plugin metadata registry를 바인딩하는 module이고, 실제 plugin setup 흐름은 ApplicationContextModule 쪽 바인딩에서 시작된다.
2.1 Guice 바인딩 위치
파일:
agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/ApplicationContextModule.java
핵심 메소드:
configure()
ApplicationContextModule.configure()는 plugin 관련 객체를 singleton으로 바인딩한다.
bind(ClassLoader).annotatedWith(PluginClassLoader).toProvider(PluginClassLoaderProvider)
bind(PluginSetup).toProvider(PluginSetupProvider)
bind(ProfilerPluginContextLoader).toProvider(ProfilerPluginContextLoaderProvider)
bind(PluginContextLoadResult).toProvider(PluginContextLoadResultProvider)
bind(ClassFileTransformer).toProvider(ClassFileTransformerProvider)
이 바인딩이 중요한 이유는 DefaultApplicationContext 생성자에서 injector.getInstance(ClassFileTransformer.class)를 호출할 때 plugin 로딩과 setup이 같이 당겨지기 때문이다.
2.2 Plugin jar 목록 만들기
파일:
agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/plugin/PluginJarsProvider.javaagent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/plugin/PluginClassLoaderProvider.java
핵심 메소드:
PluginJarsProvider.get()PluginJarsProvider.createPluginJars(...)PluginClassLoaderProvider.get()
PluginJarsProvider는 bootstrap 단계에서 넘어온 plugin jar path 목록을 PluginJar 객체 목록으로 바꾼다.
PluginJarsProvider(...)
-> createPluginJarFilter(pluginLoadingConfig)
-> createPluginJars(pluginJarPaths, pluginFilter, pluginLoadOrder)
-> filter(...)
-> sort(...)
여기서 profiler.plugin.import-plugin 같은 import 설정이 있으면 ImportPluginFilterFactory를 쓰고, 아니면 기본 plugin loading 설정 기반의 DefaultPluginFilterFactory를 쓴다.
PluginClassLoaderProvider는 이 plugin jar URL들로 별도 URLClassLoader를 만든다.
PluginClassLoaderProvider(...)
-> pluginJars.map(PluginJar::getURL)
-> new URLClassLoader(urls, Object.class.getClassLoader())
백엔드 관점으로 보면 plugin jar는 Spring의 auto-configuration 후보 jar이고, PluginClassLoader는 그 후보들을 읽기 위한 별도 classpath다.
2.3 ProfilerPlugin discovery와 setup
파일:
agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/PluginContextLoadResultProvider.javaagent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/DefaultPluginContextLoadResult.javaagent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/DefaultProfilerPluginContextLoader.javaagent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/DefaultPluginSetup.java
핵심 메소드:
PluginContextLoadResultProvider.get()DefaultPluginContextLoadResult(...)DefaultProfilerPluginContextLoader.load(List<ProfilerPlugin>)DefaultProfilerPluginContextLoader.setupPlugin(...)DefaultPluginSetup.setupPlugin(...)
DefaultPluginContextLoadResult 생성자에서 실제 plugin discovery가 일어난다.
new DefaultPluginContextLoadResult(...)
-> new ProfilerPluginLoader()
-> profilerPluginLoader.load(pluginClassLoader)
-> profilerPluginContextLoader.load(profilerPlugins)
DefaultProfilerPluginContextLoader.load()는 발견된 ProfilerPlugin 인스턴스를 jar 단위로 묶고, 각 plugin을 setup한다.
load(profilerPlugins)
-> new DefaultProfilerPluginGlobalContext(...)
-> new JarPluginComponents(pluginJars)
-> jarPluginComponents.addProfilerPlugin(...)
-> jarPluginComponents.buildJarPlugins()
-> setupPlugin(globalContext, jarPlugin)
-> pluginsSetupResult.setApplicationType(...)
setupPlugin(...)은 plugin package filter와 class injector를 만들고 PluginSetup으로 넘긴다.
setupPlugin(globalContext, jarPlugin)
-> createPluginFilterChain(pluginPackageList)
-> createPluginRequirementFilterChain(requirementList)
-> filterProfilerPlugin(disabledPlugins)
-> classInjectorFactory.newClassInjector(pluginConfig)
-> pluginSetup.setupPlugin(globalContext, profilerPlugin, classInjector)
DefaultPluginSetup.setupPlugin()은 plugin이 사용할 InstrumentContext와 ProfilerPluginSetupContext를 만든다.
setupPlugin(...)
-> new ClassFileTransformerLoader(...)
-> new DefaultProfilerPluginSetupContext(globalContext)
-> new GuardProfilerPluginSetupContext(setupContext)
-> new PluginInstrumentContext(...)
-> preparePlugin(...)
-> profilerPlugin.setup(guardSetupContext)
-> new PluginSetupResult(setupContext, transformerRegistry)
preparePlugin(...)에서 plugin이 TransformTemplateAware이면 TransformTemplate을 주입한다. 실제 plugin 코드는 이 template으로 "어떤 클래스를 변환할지" 등록한다.
'개발 메모' 카테고리의 다른 글
| Pinpoint 분석 #6 (0) | 2026.08.04 |
|---|---|
| Pinpoint 분석 #5 (0) | 2026.08.04 |
| Pinpoint 분석 #3 (0) | 2026.08.04 |
| Pinpoint 분석 #2 (0) | 2026.08.04 |
| Pinpoint 분석 #1 (0) | 2026.08.04 |