Tomcat (5) 소스 코드 분석 Tomcat 시작 과정 - 클래스 로드 과정 깊이 이해
19716 단어 Tomcat
Tomcat( )Tomcat
을 할 수 있 도록 해 야 한다 고 생각 했다.맞물리다.시작 클래스 로 더 의 핵심 코드 가 시작 과정 에 있 기 때문에 저 는 먼저 tomcat 의 시작 과정 을 분석 하고 소스 코드 와 결합 하여 tomcat 의 클래스 로 더 가 어떻게 실현 되 는 지 알 아 보고 tomcat 의 클래스 로 더 를 철저히 이해 하기 로 했 습 니 다.Tomcat 의 작 동 과정 이 매우 복잡 하기 때문에 건물 주가 작 동 과정 을 분리 분석 할 때 예전 에 말 한 것 처럼 작 동 과정 에 따라 분석 할 수 없다. 그렇지 않 으 면 글 의 편폭 이 너무 길 고 조리 가 뚜렷 하지 않 을 것 이다. Tomcat 의 작 동 과정 은 용기 의 생명 주 기 를 초기 화 하 는 것 을 포함 하고 JMX 의 관리 와 관련 되 며 우리 가 현재 분석 하고 있 는 클래스 로 더 도 포함한다. 그래서우 리 는 차원 분석 을 바 꿔 야 한다.
또 하 나 는 커 넥 터 와 용기 가 밀접 하 게 연결 되 어 있 기 때문에 커 넥 터 의 역할 은 http 요청 을 분석 하 는 것 입 니 다. 따라서 건물 주 는 우리 의 계획 이 변경 되 어야 한다 고 생각 합 니 다. 우 리 는 수명 주기 와 클래스 로 더 를 분석 한 후에 소스 코드 분석 커 넥 터 와 용 기 를 결합 하여 tomcat 의 핵심 구성 요소 가 HTTP 요청 을 받 은 후에 어떻게 작 동 하 는 지 알 아 보 겠 습 니 다.
그래서 오늘 우리 의 임 무 는 debug tomcat 소스 코드 로 tomcat 시작 과정의 모든 작업 을 분석 하 는 것 입 니 다.이 글 을 보기 전에 학생 들 은 우리 의 네 번 째 분석 tomcat 의 글 을 보고 tomcat 의 클래스 로 더 를 이해 하 기 를 바 랍 니 다.
다음은 이 글 의 디 렉 터 리 구조 입 니 다.
1. tomcat, main
2. init
3. setCatalinaHome
4. setCatalinaBase
5. . intiClassLoaders
6. createClassLoader
7. initClassLoaders
8. init , , ?
9. ? securityClassLoad
10. loadCorePackage
11. init
12. WebAppClassLoader, startInternal
13. createClassLoader
14. tomcat
1. tomcat 를 시작 하여 main 방법 으로 들 어가 기
우 리 는 이전에 clone 에서 내 린 Tomcat - Source - code 소스 코드 를 열 고 Bootstrap 류 를 찾 아 main 방법 을 찾 아 451 줄 에 정지점 을 두 고 main 방법 을 시작 하여 디 버 깅 을 시작 합 니 다.
건물 주 는 이미 많은 주석 을 쓴 것 을 볼 수 있 습 니 다. 왜냐하면 건물 주 는 debug 가 지 났 기 때 문 입 니 다. 우 리 는 코드 를 보고 먼저 '수호' 대상 이 null 인지 아 닌 지 를 판단 한 다음 에 if 블록 에 들 어가 기본 구조 기의 Bootstrap 대상 을 만 들 고 주석
// Don't set daemon until init() has completed
이 있 습 니 다.init 방법 이 완성 되 기 전에 daemon 변 수 를 설정 하지 말 라 고 합 니 다. 뒤의 많은 절차 가 이 변수 에 의존 하기 때문에 초기 화 가 끝 난 후에 야 값 을 설정 할 수 있 습 니 다. 다시 보고 init 방법 에 들 어 갑 니 다.2. init 진입 방법
이 방법 설명:
Initialize daemon.
이 데 몬 을 초기 화 하 겠 다 고 밝 혔 습 니 다. 즉, 이 변수 Bootstrap 입 니 다.이 방법 을 살 펴 보 자. 우선
setCatalinaHome()
방법, 즉 우리 가 가상 컴퓨터 를 시작 할 때 설정 한 VM 매개 변수 이다.이 방법 으로 들 어가 보 겠 습 니 다.
3. setCatalinaHome 진입 방법
분명히 우 리 는 Catalina. home 을 설정 한 적 이 있 기 때문에 classpath 에 있 는 catalina. home 의 값 이 null 이 아니 기 때문에 직접 return 합 니 다. null 이 아니라면 프로젝트 루트 디 렉 터 리 에서 boostrap 의 jar 패 키 지 를 가 져 옵 니 다. 존재 한다 면 이전 디 렉 터 리 를 catalina. home 으로 설정 합 니 다. 존재 하지 않 는 다 면 프로젝트 루트 디 렉 터 리 를 catalina. home 으로 설정 합 니 다. 이것 이 setCatalina Home 방법의 논리 입 니 다.
4. setCatalinaBase 진입 방법
다음 단 계 는 setCatalinaBase 방법 을 실행 하 는 것 입 니 다.
catalina.base
를 가 져 올 수 있 습 니 다. 직접 return 입 니 다. 존재 하지 않 으 면 catalina.home
을 catalina.base
로 설정 하고 catalina.home
도 비어 있 으 면 프로젝트 루트 디 렉 터 리 를 catatlina.base
로 설정 합 니 다.5. 다음은 클래스 로 더 가 솜 씨 를 발휘 할 때 입 니 다. inticlassLoaders 에 들 어 가 는 방법
inticlassLoaders (), 여러 종류의 로 더 를 초기 화 합 니 다. 이 방법 에 들 어가 서 구체 적 인 논 리 를 봅 니 다.
우선, common 클래스 로 더 를 만 듭 니 다. 부모 클래스 로 더 는 null 입 니 다. 주의: 자바 가 추천 하 는 클래스 로 더 메커니즘 이 라면 부모 클래스 로 더 는 시스템 클래스 로 더 나 확장 클래스 로 더 여야 합 니 다. 그래서 이것 은 클래스 로 더 의 부모 위임 모델 에 현저히 어 긋 납 니 다. 자, tomcat 를 계속 봅 시다. 우 리 는 creatClassLoader 방법 에 들 어가 서 어떻게 실현 되 는 지 봅 시다.(이 방법 은 매우 길다. 우 리 는 중요 한 논리 에 주목한다):
6. createClassLoader 에 들 어 가 는 방법
private ClassLoader createClassLoader(String name, ClassLoader parent)
throws Exception {
// /org/apache/catalina/startup/catalina.properties key
// common.loader Value=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar
String value = CatalinaProperties.getProperty(name + ".loader");
// ( ), null
if ((value == null) || (value.equals(""))){
return parent;
}
//
value = replace(value);
//Repository ClassLoaderFactory , 2 , location, type,
List repositories = new ArrayList();
/*
, value
*/
// class ,
// StandardClassLoader java.net.URLClassLoader , URLClassLoader .
// null, URLClassLoader .
// , common ,
ClassLoader classLoader = ClassLoaderFactory.createClassLoader// , parent 0,
(repositories, parent);
// Retrieving MBean server // JMX bean,
MBeanServer mBeanServer = null;
if (MBeanServerFactory.findMBeanServer(null).size() > 0) {
mBeanServer = MBeanServerFactory.findMBeanServer(null).get(0);
} else {
mBeanServer = ManagementFactory.getPlatformMBeanServer();
}
// Register the server classloader
ObjectName objectName =
new ObjectName("Catalina:type=ServerClassLoader,name=" + name);
// .
mBeanServer.registerMBean(classLoader, objectName);
return classLoader;
}
````
, :
1. `/org/apache/catalina/startup/catalina.properties ` lib jar . key ( common.loader、server.loader、shared.loader) value . . .
2. , jar .
3. `ClassLoaderFactory.createClassLoader(repositories, parent)` , `java.net.URLClassLoader` `StandardClassLoader` jar , URLClassLoader , crateClassLoader , array jar , null `StandardClassLoader` .
4. ClassLoader JMX ( , , )。
![](http://upload-images.jianshu.io/upload_images/4236553-4adc8d0b36c05114.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
`StandardClassLoader` , , URLClassLoader :
![](http://upload-images.jianshu.io/upload_images/4236553-973fd96d79b6594d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
URLClassLoader SecureClassLoader , SecureClassLoader ClassLoader , . .
"se-preview-section-delimiter">
##### 7. initClassLoaders
`commonLoader = createClassLoader("common", null);`, null, null ? key key value null, null, common .
catalinaloader sharedLoader , createClassLoader , , null, common . ? debug :
![](http://upload-images.jianshu.io/upload_images/4236553-fd0d2db752af5723.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](http://upload-images.jianshu.io/upload_images/4236553-e81758f680ec5dff.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
, , , .
"se-preview-section-delimiter">
### 8. init , , ?
![](http://upload-images.jianshu.io/upload_images/4236553-774ddc72bda64f5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
catalinaLoader . . , , .
![](http://upload-images.jianshu.io/upload_images/4236553-05cbefb1693430cb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
"se-preview-section-delimiter">
#### 9. ? securityClassLoad
![](http://upload-images.jianshu.io/upload_images/4236553-a88757e3f188b647.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](http://upload-images.jianshu.io/upload_images/4236553-7b0ecfa890763864.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
, Tomcat , ClassLoader catalinaLoader, ,Tomcat catalinaLoader 。
securityClassLoad Tomcat class, :
* Tomcat class, org.apache.catalina.core class;
* org.apache.catalina.loader.WebappClassLoader$PrivilegedFindResourceByName;
* Tomcat session class, org.apache.catalina.session class;
* Tomcat class, org.apache.catalina.util class;
* javax.servlet.http.Cookie;
* Tomcat class, org.apache.catalina.connector class;
* Tomcat class, org.apache.catalina.util class;
"se-preview-section-delimiter">
#### 10. loadCorePackage
Tomcat class loadCorePackage , :
"se-preview-section-delimiter">
```java
private static final void loadCorePackage(ClassLoader loader)
throws Exception {
final String basePackage = "org.apache.catalina.core.";
loader.loadClass
(basePackage +
"AccessLogAdapter");
loader.loadClass
(basePackage +
"ApplicationContextFacade$1");
loader.loadClass
(basePackage +
"ApplicationDispatcher$PrivilegedForward");
loader.loadClass
(basePackage +
"ApplicationDispatcher$PrivilegedInclude");
loader.loadClass
(basePackage +
"AsyncContextImpl");
loader.loadClass
(basePackage +
"AsyncContextImpl$DebugException");
loader.loadClass
(basePackage +
"AsyncContextImpl$1");
loader.loadClass
(basePackage +
"AsyncContextImpl$PrivilegedGetTccl");
loader.loadClass
(basePackage +
"AsyncContextImpl$PrivilegedSetTccl");
loader.loadClass
(basePackage +
"AsyncListenerWrapper");
loader.loadClass
(basePackage +
"ContainerBase$PrivilegedAddChild");
loader.loadClass
(basePackage +
"DefaultInstanceManager$1");
loader.loadClass
(basePackage +
"DefaultInstanceManager$2");
loader.loadClass
(basePackage +
"DefaultInstanceManager$3");
loader.loadClass
(basePackage +
"DefaultInstanceManager$AnnotationCacheEntry");
loader.loadClass
(basePackage +
"DefaultInstanceManager$AnnotationCacheEntryType");
loader.loadClass
(basePackage +
"ApplicationHttpRequest$AttributeNamesEnumerator");
}
catalinaClassLoader 가 이 가방 의 클래스 를 불 러 왔 습 니 다. 이전 이해 에 따 르 면 catalinaClassLoader 가 불 러 온 클래스 는 Tomcat 용기 의 개인 클래스 로 더 입 니 다. 불 러 오 는 경로 의 class 는 Webapp 에 보이 지 않 습 니 다.
11. init 로 돌아 가 는 방법
먼저 로 그 를 인쇄 한 다음 클래스 catalinaLoader 클래스 로 더
org.apache.catalina.startup.Catalina
클래스 를 불 러 옵 니 다. 이 어 이 클래스 의 대상 을 만 듭 니 다. "시작 대상 인 스 턴 스" 라 는 뜻 으로 startupInstance 를 만 든 다음 이 인 스 턴 스 를 반사 호출 하 는 setParent ClassLoader 방법 을 사용 합 니 다. 매개 변 수 는 shared Loader 입 니 다. 이 인 스 턴 스 의 부모 클래스 로 더 를 shared Loader 라 고 표시 합 니 다.마지막 으로 catalina Daemon 을 이 인 스 턴 스 로 설정 합 니 다.
12. WebAppClassLoader 를 찾 아 startInternal 에 들 어 가 는 방법
우 리 는 소스 코드 를 통 해 comonClassLoader, catalina ClassLoader, shared Loader 를 초기 화 했다 는 것 을 알 게 되 었 습 니 다. 그러나 우 리 는 지난 글 의 그림 을 떠 올 리 면 뭔 가 부족 한 것 같 습 니 다.
WebAppClassLoader 는 요?
웹 앱 ClassLoaser 는 각 웹 앱 의 개인 적 인 클래스 로 더 입 니 다. 로 딩 경로 에 있 는 class 는 현재 웹 앱 에 만 보 입 니 다. 그러면 그 는 어떻게 초기 화 했 습 니까? 웹 앱 ClassLoaser 의 초기 화 시간 은 이 세 가지 종류의 로 더 를 초기 화 하 는 시간 과 다 릅 니 다. 웹 앱 ClassLoaser 는 Context 와 밀접 한 관 계 를 가지 기 때문에 org. apache. catalina. core. StandardCo 를 어떻게 초기 화 합 니까?ntext 는 함께 WebAppClassLoader 를 초기 화 합 니 다. 이 클래스 에서 startInternal 방법 은 초기 화 클래스 로 더 의 논 리 를 포함 하고 핵심 소스 코드 는 다음 과 같 습 니 다.
@Override
protected synchronized void startInternal() throws LifecycleException {
if (getLoader() == null) {
WebappLoader webappLoader = new WebappLoader(getParentClassLoader());
webappLoader.setDelegate(getDelegate());
setLoader(webappLoader);
}
if ((loader != null) && (loader instanceof Lifecycle)) {
((Lifecycle) loader).start();
}
}
먼저 WebAppClassLoader 를 만 든 다음 에 setLoader (webappLoader) 를 만 들 고 start 방법 을 호출 합 니 다. 이 방법 은 템 플 릿 방법 입 니 다. 내부 에 startInternal 방법 이 하위 클래스 에 사용 되 고 있 습 니 다. WebAppClassLoader 의 startInternal 방법 핵심 실현 을 보 겠 습 니 다.
@Override
protected void startInternal() throws LifecycleException {
classLoader = createClassLoader();
classLoader.setResources(container.getResources());
classLoader.setDelegate(this.delegate);
classLoader.setSearchExternalFirst(searchExternalFirst);
if (container instanceof StandardContext) {
classLoader.setAntiJARLocking(
((StandardContext) container).getAntiJARLocking());
classLoader.setClearReferencesStatic(
((StandardContext) container).getClearReferencesStatic());
classLoader.setClearReferencesStopThreads(
((StandardContext) container).getClearReferencesStopThreads());
classLoader.setClearReferencesStopTimerThreads(
((StandardContext) container).getClearReferencesStopTimerThreads());
classLoader.setClearReferencesHttpClientKeepAliveThread(
((StandardContext) container).getClearReferencesHttpClientKeepAliveThread());
}
for (int i = 0; i < repositories.length; i++) {
classLoader.addRepository(repositories[i]);
}
}
13. createClassLoader 에 들 어 가 는 방법
우선
classLoader = createClassLoader();
클래스 로 더 를 만 들 고 현재 웹 앱 의 다음 context 클래스 자원 으로 자원 경 로 를 설정 합 니 다. 마지막 으로 createClassLoader 의 실현 을 살 펴 보 겠 습 니 다.
/**
* Create associated classLoader.
*/
private WebappClassLoader createClassLoader()
throws Exception {
Class> clazz = Class.forName(loaderClass);
WebappClassLoader classLoader = null;
if (parentClassLoader == null) {
parentClassLoader = container.getParentClassLoader();
}
Class>[] argTypes = { ClassLoader.class };
Object[] args = { parentClassLoader };
Constructor> constr = clazz.getConstructor(argTypes);
classLoader = (WebappClassLoader) constr.newInstance(args);
return classLoader;
}
이 곳 의 loaderClass 는 문자열
org.apache.catalina.loader.WebappClassLoader
입 니 다. 우선 반 사 를 통 해 classLoader 를 실례 화 합 니 다. 이제 웹 앱 ClassLoader 는 StandardContext 가 초기 화 될 때 실례 화 되 었 고, 웹 앱 ClassLoader 와 Context 가 밀접 한 관 계 를 증명 합 니 다.14. omcat 클래스 로드 구조 시스템 생 성 완료
이로써 우리 의 Tomcat 류 로 딩 구조 체 계 는 구축 되 었 습 니 다. 정말 TMD 가 복잡 합 니 다!!! 하지만 소스 코드 를 읽 는 것 은 우리 의 수준 을 향상 시 키 는 가장 빠 른 수단 이라는 것 을 기억 하 세 요. 소스 코드 에서 대사 들 의 디자인 모델 과 각종 고급 용법 은 우리 의 공력 을 크게 증가 시 킬 것 입 니 다. 계속 힘 내세 요!!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[tomcat] tomcat을 설치 및 시작하고 명령 파일을 만듭니다 (.command) for MacMac에서 tomcat을 설치하고 시작하려면 두 가지 유형을 시도했습니다. 1) Apache Tomcat에서 다운로드 2) Homebrew를 사용하여 설치 1) 그러면 환경 설정이 귀찮게 되었기 때문에 2)에서 설치...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.