Pinpoint 분석 #4

2026. 8. 4. 00:19·개발 메모

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.java
  • agent-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.java
  • agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/DefaultPluginContextLoadResult.java
  • agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/DefaultProfilerPluginContextLoader.java
  • agent-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
'개발 메모' 카테고리의 다른 글
  • Pinpoint 분석 #6
  • Pinpoint 분석 #5
  • Pinpoint 분석 #3
  • Pinpoint 분석 #2
csb0710
csb0710
  • csb0710
    데모장
    csb0710
  • 전체
    오늘
    어제
    • 분류 전체보기 (60)
      • 스프링부트 메모 (7)
      • 개발 메모 (10)
      • 클라우드 메모 (10)
      • 설치&설정 메모 (2)
      • 알고리즘 메모 (18)
      • 인턴 메모 (7)
      • 데이터베이스 메모 (3)
      • 책 메모 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    디비설치
    그리디
    자동 답변 봇
    알고리즘
    이지퍼블리싱
    코딩테스트
    GitHub
    코드트리조별과제
    HBase
    오블완
    .gitmodules
    서버 연결
    스프링부트
    코드트리
    submodule
    백준
    서버배포
    서버생성
    티스토리챌린지
    디비설정
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
csb0710
Pinpoint 분석 #4
상단으로

티스토리툴바