add user agent parser and update build configuration
This commit is contained in:
155
docs/모듈.md
Normal file
155
docs/모듈.md
Normal file
@@ -0,0 +1,155 @@
|
||||
# **자바 모듈 시스템(Module System) 완벽 정리**
|
||||
|
||||
## **1. 자바 모듈이란?**
|
||||
자바 9에서 도입된 **모듈 시스템**은 **코드를 논리적으로 분리**하고, **불필요한 의존성을 줄이며**, **캡슐화를 강화**하는 기능이다.
|
||||
기존의 **JAR 파일을 묶는 개념**이 아니라, 모듈 자체가 **의존성 관리 및 접근 제어 기능**을 갖는다.
|
||||
|
||||
---
|
||||
|
||||
## **2. 모듈의 핵심 개념**
|
||||
### ✅ **모듈의 구성 요소**
|
||||
1. `module-info.java` 파일 (모듈의 정의 파일)
|
||||
2. 패키지 (캡슐화할 클래스 포함)
|
||||
3. 다른 모듈에 대한 의존성 선언
|
||||
|
||||
### ✅ **모듈의 주요 키워드**
|
||||
| 키워드 | 설명 |
|
||||
|--------|------|
|
||||
| `module` | 모듈을 정의하는 키워드 |
|
||||
| `requires` | 다른 모듈을 가져올 때 사용 |
|
||||
| `exports` | 특정 패키지를 외부에서 사용 가능하도록 공개 |
|
||||
| `opens` | 리플렉션(Reflection)을 허용 (ex: Jackson, Hibernate) |
|
||||
| `provides ... with` | 서비스 제공자 패턴 구현 시 사용 |
|
||||
| `uses` | 특정 서비스 인터페이스 사용 시 명시 |
|
||||
|
||||
---
|
||||
|
||||
## **3. 모듈 예제**
|
||||
### ✅ **모듈 프로젝트 구성**
|
||||
다음과 같은 두 개의 모듈이 있다고 가정하자.
|
||||
- **`com.example.moduleA`** (API를 제공하는 모듈)
|
||||
- **`com.example.moduleB`** (`moduleA`의 기능을 사용하는 모듈)
|
||||
|
||||
📁 **프로젝트 구조**
|
||||
```
|
||||
/project
|
||||
├── moduleA
|
||||
│ ├── src/com/example/moduleA/MyService.java
|
||||
│ ├── src/module-info.java
|
||||
│
|
||||
├── moduleB
|
||||
│ ├── src/com/example/moduleB/MainApp.java
|
||||
│ ├── src/module-info.java
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### ✅ **1. `moduleA` (API 제공 모듈)**
|
||||
📌 **`moduleA`는 `MyService` 클래스를 제공**하며, `moduleB`에서 사용 가능하도록 공개해야 한다.
|
||||
|
||||
#### 📌 **📄 moduleA/src/module-info.java**
|
||||
```java
|
||||
module com.example.moduleA {
|
||||
exports com.example.moduleA; // 패키지 공개
|
||||
}
|
||||
```
|
||||
|
||||
#### 📌 **📄 moduleA/src/com/example/moduleA/MyService.java**
|
||||
```java
|
||||
package com.example.moduleA;
|
||||
|
||||
public class MyService {
|
||||
public String getMessage() {
|
||||
return "Hello from Module A!";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### ✅ **2. `moduleB` (API 사용 모듈)**
|
||||
📌 **`moduleB`는 `moduleA`의 클래스를 사용**하므로, `requires` 키워드로 `moduleA`를 포함해야 한다.
|
||||
|
||||
#### 📌 **📄 moduleB/src/module-info.java**
|
||||
```java
|
||||
module com.example.moduleB {
|
||||
requires com.example.moduleA; // moduleA를 사용하기 위해 선언
|
||||
}
|
||||
```
|
||||
|
||||
#### 📌 **📄 moduleB/src/com/example/moduleB/MainApp.java**
|
||||
```java
|
||||
package com.example.moduleB;
|
||||
|
||||
import com.example.moduleA.MyService;
|
||||
|
||||
public class MainApp {
|
||||
public static void main(String[] args) {
|
||||
MyService service = new MyService();
|
||||
System.out.println(service.getMessage());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## **4. 모듈 프로젝트 실행 방법**
|
||||
📌 터미널에서 모듈을 직접 컴파일하고 실행할 수도 있다.
|
||||
|
||||
### ✅ **1. 모듈별 컴파일**
|
||||
```sh
|
||||
# moduleA 컴파일
|
||||
javac -d out/moduleA src/moduleA/module-info.java src/moduleA/com/example/moduleA/MyService.java
|
||||
|
||||
# moduleB 컴파일 (moduleA를 classpath에 추가)
|
||||
javac -d out/moduleB --module-path out/moduleA src/moduleB/module-info.java src/moduleB/com/example/moduleB/MainApp.java
|
||||
```
|
||||
|
||||
### ✅ **2. 프로그램 실행**
|
||||
```sh
|
||||
java --module-path out/moduleA:out/moduleB --module com.example.moduleB/com.example.moduleB.MainApp
|
||||
```
|
||||
✔ `Hello from Module A!` 출력
|
||||
|
||||
---
|
||||
|
||||
## **5. `exports`와 `opens` 차이점**
|
||||
| 키워드 | 설명 |
|
||||
|--------|------|
|
||||
| `exports 패키지명;` | 패키지를 외부 모듈에서 사용할 수 있도록 공개 |
|
||||
| `opens 패키지명;` | 리플렉션(Reflection)으로 접근 가능하지만 일반적인 import는 불가능 |
|
||||
|
||||
📌 예를 들어, **Jackson, Hibernate 같은 프레임워크는 리플렉션을 사용**하므로 `opens`가 필요하다.
|
||||
```java
|
||||
module com.example.moduleA {
|
||||
opens com.example.moduleA to jackson.databind;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## **6. 모듈 시스템의 장점**
|
||||
✅ **1. 강력한 캡슐화:**
|
||||
필요한 패키지만 `exports` 가능하여, **불필요한 내부 코드 노출 방지**
|
||||
|
||||
✅ **2. 명확한 의존성 관리:**
|
||||
`requires` 키워드로 **명확한 모듈 간 의존성**을 선언
|
||||
|
||||
✅ **3. 경량화된 런타임:**
|
||||
JVM이 필요 없는 모듈을 제외하고 실행 가능 (예: `jlink` 사용)
|
||||
|
||||
---
|
||||
|
||||
## **7. 모듈 시스템의 단점**
|
||||
❌ **1. 기존 라이브러리와의 호환성 문제:**
|
||||
기존 JAR 파일 중에는 **모듈 시스템을 지원하지 않는 것들이 있음**
|
||||
|
||||
❌ **2. 학습 곡선이 존재:**
|
||||
모듈 시스템을 처음 접하는 경우, **기존 classpath 방식보다 설정이 다소 복잡**
|
||||
|
||||
---
|
||||
|
||||
## **8. 결론**
|
||||
자바 모듈 시스템은 **의존성을 명확하게 관리하고 캡슐화를 강화**하는 강력한 기능이다.
|
||||
하지만, 기존 라이브러리와의 호환성을 고려해야 하며, **소규모 프로젝트에서는 필요하지 않을 수도 있다.**
|
||||
대규모 프로젝트에서는 **모듈을 도입하면 유지보수성과 성능이 향상**될 수 있다.
|
||||
Reference in New Issue
Block a user