[Java] 라이브러리(Library) & 모듈(module) & 리플렉션(reflection)
by 우와한개발자
[ 라이브러리 ]
1. 라이브러리란?
- 자바로 작성된 다양한 클래스와 메서드들의 집합
- 자바 라이브러리는 크게 자바 표준 라이브러리와 외부 라이브러리로 나뉨
1) 자바 표준 라이브러리 (Java Standard Library)
- 오라클에서 제공하는 공식 자바 라이브러리
- 자바 개발 플랫폼에 기본으로 포함
- 입출력, 컬렉션, 스레딩, 네트워킹, 알고리즘 등 클래스 포함
2) 외부(Third-party) 라이브러리
- 다양한 개발자가 개발한 라이브러리
- 메이블(Maven), 그래들(Gradle)과 같은 빌드 도구를 통해 쉽게 프로젝트에 추가 가능
- Apache Commons, Google Guava, Jackson 등
2. 라이브러리 배포 파일
1) JAR (Java Archive)
- 자바 클래스 파일, 리소스, 메타데이터 및 관련 라이브러리 등을 패키징하기 위한 파일 형식
2) WAR (Web Archive)
- 자바 웹 애플리케이션을 패키징하고 배포하기 위한 파일 형식
- 웹 애플리케이션의 웹 리소스(HTML, CSS, 이미지 등), JSP 파일, 서블릿 클래스, 라이브러리 JAR 파일, 웹 관련 XML 파일 등 포함
3)EAR (Enterprise Archive)
- 여러 개의 웹 모듈(WAR)과 EJB(J2EE의 일종인 Enterprise JavaBeans) 모듈을 하나로 묶어 Java 엔터프라이즈 애플리케이션을 패키징하고 배포하기 위한 파일 형식
- 볼 일 거의 없음
3. 라이브러리 생성 : 이클립스 Export 기능
1)이클립스 Export 로 .jar 파일 패키징
내보낼 프로젝트 우클릭
→ Export
→ Export generated class files and resources 체크
Export Java source files and resources 체크
Select the export destination 의 JAR file 에 패키징 후 저장할 위치와 파일명 적기
→ Finish
⚠️ 배포 파일(.jar)을 만들 때 소스코드를 같이 패키징함.
2) .jar 파일 이름 기본 원칙
- artifactId-version 형식 사용 : 프로젝트이름-버전.jar
- 전부 소문자 권장
- 단어 구분은 하이픈(-) 사용
- 공백 및 특수문자 사용 금지
- 버전은 시맨틱 버저닝(SemVer) 권장
- 숫자로 시작 가능하지만 비권장
4. 라이브러리 사용
- 프로젝트/lib 폴더 생성 후 라이브러리(.jar 파일) 드래그
- Build Path 설정 (그래야 사용 가능)
프로젝트 우클릭
→ Build Path
→ Configure Build Path
→ Libraries의 Classpath
→ Add JARs
→ 프로젝트/lib 폴더 내 추가한 JAR 파일 선택
⚠️ Add External JARs : 내 컴퓨터(드라이브)에 저장된 라이브러리 가져올 때 사용
[ 모듈 module ]
- Java 9 부터 도입
- 이전에는 자바 애플리케이션을 JAR 파일로 패키징하고 클래스 패스를 통해 의존성을 관리하는 방식이었음
- 모듈의 이름은 공백 없이 영문으로만 사용
1. 모듈(Module) 이란?
1) 모듈 (Module)
- 클래스, 인터페이스, 리소스 및 기타 관련된 코드를 논리적으로 그룹화한 것
2) 모듈 디스크립터 (Module Descriptor) : module-info.java 파일
- 모듈의 이름, 의존성, 내보낼 패키지 등 정의
- 각 모듈은 반드시 module-info.java 파일을 가지고 있음
// module-info.java
module com.example.myproject {
exports com.example.mymodule; // 다른 모듈에게 공개할 패키지
requires some.other.module; // 필요로 하는 다른 모듈
}
3) 의존성 관리
- 모듈 시스템은 각 모듈이 필요로 하는 다른 모듈을 명시적으로 선언
4) 모듈 경로 (Module Path)
- 클래스 패스 대신 모듈 경로를 사용해 모듈을 로드하고 의존성 해결
5) 캡슐화 (Encapsulation)
- 모듈은 자체적으로 패키지를 내보내거나 숨길 수 있음
- 외부에서의 직접적인 접근 제한, 모듈 간의 인터페이스 명확히 정의
2. 모듈 생성 : 이클립스 Export 기능
1) 모듈 디스크립터 생성 : 프로젝트/module-info.java 파일 생성
module com.example.calculator {
exports com.example.calculator; // 공개할 패키지
}
2) module-info.java 키워드 정리
| 키워드 | 의미 | 언제 사용 | 예시 |
| requires | 다른 모듈 의존 | 다른 모듈 사용 시 | requires java.sql; |
| requires transitive | 의존 모듈을 재전파 | 라이브러리 모듈 만들 때 | requires transitive com.example.lib; |
| requires static | 컴파일 시만 필요 | optional 의존성 | requires static lombok; |
| exports | 패키지 공개 | 다른 모듈이 접근 가능 | exports com.example.api; |
| exports ... to | 특정 모듈에만 공개 | 제한적 공개 | exports com.example.api to com.client; |
| opens | 리플렉션 허용 | Spring/JPA 사용 시 | opens com.example.entity; |
| opens ... to | 특정 모듈에만 리플렉션 허용 | 보안 강화 | opens com.example.entity to spring.core; |
| uses | 서비스 사용 선언 | ServiceLoader 사용 | uses PaymentService; |
| provides ... with | 서비스 구현 등록 | SPI 구현 제공 | provides PaymentService with CardPaymentService; |
| open module | 전체 패키지 리플렉션 허용 | Spring Boot 등 | open module com.example.app {} |
3) 모듈 이름 기본 원칙
- 패키지 이름 규칙과 동일하게 작성
- 전부 소문자
- 역도메인(reverse domain) 방식 권장
- 하이픈(-) 사용 불가
- 숫자로 시작 불가
4).jar 파일 패키징
내보낼 모듈 우클릭
→ Export
→ Export generated class files and resources 체크,
Export Java source files and resources 체크
Select the export destination 의 JAR file 에 패지징 후 저장할 위치와 파일명 적기
→ Finish
3. 모듈 사용
- 프로젝트/modules 폴더 생성 후 모듈 파일(.jar 파일) 드래그
- Build Path 설정 (그래야 사용 가능)
프로젝트 우클릭
→ Build Path
→ Configure Build Path
→ Libraries의 Modulepath
→ Add JARs
→ 프로젝트/moules 폴더 내 추가한 JAR파일 선택
⚠️ Add External JARs : 내 컴퓨터(드라이브)에 저장된 모듈 가져올 때 가져온 모듈을 사용할 모듈의 모듈 디스크립터에 가져온 모듈 지정 필요
AppModule/
├─ src/
│ ├─ com/
│ │ └─ example/
│ │ └─ app/
│ │ └─ App.java
│ └─module-info.java
│
└─ modules/.jar
// AppModule 프로젝트의 module-info.java
module com.example.app {
requires CalculatorModule;
}
4. 전이 모듈과 모듈 그룹
1) 전이 모듈 (Transitive Module)
- 다른 모듈이 의존성을 가질 때, 그 의존성을 전이적으로 가져오는 모듈
- A → B, B → requires transitive C 관계일 때, A는 B와 C 두 모듈에 대한 의존성을 자동으로 갖게 됨
- 이를 통해 A에서 C 모듈을 의존성 설정하지 않아도 C 모듈을 사용할 수 있게 됨
module A {
requires B;
}
module B {
requires transitive C; // B를 쓰는 모듈은 자동으로 C도 사용 가능
}
module C {
// 모듈 C의 정의
}
⚠️ 만약 B 모듈에 transitive 선언이 없다면, A가 C 모듈을 사용해야 할 상황이 있을 때 A 모듈에도 requires C;를 별도로 설정해야 함
2) 모듈 그룹 (Module Group)
- 여러 모듈을 묶어서 관리하고, 모듈 간의 의존성을 일괄적으로 처리하는 개념
- 프로젝트의 모듈들을 논리적으로 그룹화하여 모듈 간의 관계를 명확하게 정의해 주며, 주로 특정 기능이나 비즈니스 영역에 관련된 모듈들을 함께 묶어 사용할 때 유용함
- A 모듈이 B와 C를 transitive로 의존성 명시 → B와 C가 있어야 하는 곳에 A만 의존성 설정하면 됨
module A {
requires transitive B;
requires transitive C;
}
module B {
// 모듈 B의 정의
}
module C {
// 모듈 C의 정의
}
// AppModule에서는 A만 requires 하면 B, C도 자동으로 사용 가능
module AppModule {
requires A;
}
[ 리플렉션 Reflection ]
1. 리플렉션이란?
- 실행 중인 프로그램의 클래스, 인터페이스, 메서드, 필드 등의 구조에 대한 정보를 동적으로 얻거나 조작하는 기능
- 클래스의 인스턴스 생성, 메서드 호출, 필드 값 읽기/수정 등의 작업 수행 가능
- 리플렉션 코드를 작성하지 않고도 클래스의 정보를 검사하고, 실행 중에 객체를 제어할 수 있어 유연성을 제공
- 주로 프레임워크, 라이브러리, 개발 도구 등 다양한 컴포넌트에서 사용
- java.lang.reflect 패키지를 통해 제공
2. 주요 클래스
1) Class 클래스 : java.lang.Class
- 클래스의 메타데이터를 제공하는 주요 클래스
- 클래스의 이름, 패키지, 메서드, 필드 등의 정보를 얻을 수 있음
Class<?> myClass = Class.forName("MyClass"); // MyClass의 Class 객체 얻기
Class<?> myClass = MyClass.class; // MyClass의 Class 객체 얻기
2) Constructor 클래스 : java.lang.reflect.Constructor
- 클래스의 생성자를 나타냄
- 인스턴스를 동적으로 생성할 때 사용
Constructor<MyClass> constructor = MyClass.class.getConstructor(); // 생성자
MyClass instance = constructor.newInstance(); // 인스턴스 생성
3) Method 클래스 : java.lang.reflect.Method
- 클래스의 메서드를 나타냄
- 메서드 이름, 매개변수, 반환 타입 등의 정보를 얻을 수 있음
Method myMethod = MyClass.class.getMethod("myMethod", int.class, String.class); // 메서드 얻기
Object result = myMethod.invoke(instance, 42, "Hello"); // 메서드 호출
4) Field 클래스 : java.lang.reflect.Field
- 클래스의 필드를 나타냄
- 필드의 이름, 타입, 값을 읽거나 수정할 수 있음
Field myField = MyClass.class.getDeclaredField("myField"); // 필드 얻기
myField.setAccessible(true); // private 필드에 접근하기 위한 설정
Object value = myField.get(instance); // 필드 값 얻기
3. 모듈 시스템과 리플렉션
- 자바 모듈 시스템에서는 기본적으로 리플렉션을 통한 내부 구조 접근을 제한
- 특정 모듈에 대해 리플렉션을 허용하려면 module-info.java에 opens 지시어 사용
// module-info.java
module CalculatorModule {
exports com.example.calculator; // 공개할 패키지
opens com.example.calculator.internal; // 리플렉션 허용
}
⚠️ exports 패키지는 자유롭게 접근 가능하지만 리플렉션은 별도로 opens 선언이 필요
4. 리플렉션 주의사항
| 항목 | 내용 |
| 캡슐화 남용 | private 필드/메서드에도 접근 가능하므로 캡슐화 원칙이 깨질 수 있음 |
| 성능 저하 | 일반 메서드 호출보다 느림, 성능이 중요한 곳에서는 주의 |
| 런타임 오류 | 컴파일러가 일부 오류를 잡지 못하고 런타임에 발견될 수 있음 |
| 타입 안전성 | 가능하다면 타입 안전성을 유지하는 방향으로 사용 권장 |
'언어 > Java' 카테고리의 다른 글
| [Java] 파일 입출력 - 입출력 스트림과 직렬화(Serialization) (0) | 2026.03.04 |
|---|---|
| [Java] record 클래스와 Lombok 라이브러리 (1) | 2026.03.04 |
| [Java] 주석(/, /*, /**)과 공백, 식별자와 예약어 (0) | 2026.03.03 |
| [Java] 내부 클래스(nested Class)와 익명 클래스(Anonymous Class) (0) | 2026.03.03 |
| [Java] 주요 어노테이션 정리 - Java, Lombok, Spring, JPA (0) | 2026.03.03 |
블로그의 정보
우와한개발자 님의 블로그
우와한개발자