728x90
프록시(proxy)란❓
프록시(Proxy)란 소프트웨어 디자인 패턴의 하나로, 다른 객체를 대신하여 그 객체에 대한 접근을 제어하거나 기능을 확장하는 객체를 의미합니다.
프록시는 실제 객체를 대신하여 그 객체의 메서드 호출을 가로채고, 필요한 경우 실제 객체에 대한 작업을 수행합니다. 프록시는 일반적으로 원래 객체와 같은 인터페이스를 구현하여, 클라이언트가 원래 객체를 사용하는 것처럼 보이게 합니다.
한마디로 표현하자면 "가짜 객체"라고 할 수 있습니다.
위 그림에서 알 수 있듯이 프록시 객체는 실제 Entity를 상속 받아서 만들어지기 때문에 실제 클래스와 겉 모양이 같습니다.
프록시 객체는 실제 엔티티에 대한 접근을 지연시키며, 실제 엔티티가 필요할 때까지 데이터베이스 쿼리를 실행하지 않습니다. 또한 프록시 객체는 실제 엔티티의 메서드를 호출할 때, 이 호출을 실제 엔티티 객체로 위임(delegate)합니다.
프록시 객체의 특징
지연 로딩
- 프록시 객체는 실제 엔티티를 데이터베이스에서
로드하지 않고, 메서드 호출 시점에 데이터베이스에서 로드합니다. 이는 초기 로딩 시점에 불필요한 데이터 로딩을 방지하고 성능을 최적화하는 데 도움을 줍니다.
프록시 생성
- JPA는 프록시 객체를 생성할 때 원래 엔티티 클래스를 상속받고, 실제 데이터는 필요할 때 로드합니다.
트랜잭션 범위
- 프록시 객체는 트랜잭션이 유효한 범위 내에서만 동작하며, 트랜잭션이 종료되면
데이터 로딩이 불가능할 수 있습니다.
프록시(proxy) 객체의 작동 방식
1. 프록시 객체의 생성
- JPA는 엔티티의 실제 인스턴스 대신 프록시 객체를 생성합니다. 이 프록시 객체는 실제 엔티티의 모든 메서드를 호출할 때 해당 엔티티가 실제로 로드되도록 하는 역할을 합니다.
- 프록시 객체는 원본 엔티티의 메타데이터를 포함하고 있으며, 실제 엔티티 객체를 나중에 로드할 수 있는 정보를 가지고 있습니다.
2. 프록시 객체의 동작
public class HubPathResponseDto {
private UUID hubPathId;
private String departureHubName;
private String arrivalHubName;
public static HubPathResponseDto of(HubPath hubPath) {
return new HubPathResponseDto(
hubPath.getHubPathId(),
hubPath.getDepartureHub().getName(), // 프록시 객체가 초기화됨
hubPath.getArrivalHub().getName() // 프록시 객체가 초기화됨
);
}
}
- 프록시 객체가 메서드를 호출할 때, 해당 메서드가 실제 엔티티를 필요로 하는 경우에 데이터베이스에서 데이터를 로드합니다. 이를 "프록시 초기화"라고 합니다.
- 예를 들어, getName() 메서드를 호출하면, 프록시 객체는 실제 엔티티를 로드하기 위해 데이터베이스 쿼리를 실행하고, 그 결과를 반환합니다.
3. 프록시와 실제 엔티티의 위임
- 프록시 객체는 실제 엔티티에 대한 접근을 지연시키며, 실제 엔티티가 필요할 때까지 데이터베이스 쿼리를 실행하지 않습니다.
- 프록시 객체는 실제 엔티티의 메서드를 호출할 때, 이 호출을 실제 엔티티 객체로 위임합니다.
프록시(proxy) 객체의 장점과 단점
장점
- 성능 최적화
- 데이터가 실제로 필요할 때만 로드되므로 불필요한 데이터 로딩을 방지합니다.
- 메모리 절약
- 초기 로딩 시에
모든 연관된 데이터를 로드하지 않기 때문에 메모리 사용을 절약합니다.
- 초기 로딩 시에
단점
- N+1 문제
- 여러 엔티티를 처리할 때, 연관된 엔티티에 대한 지연 로딩이 반복적으로 발생할 수 있어 성능 문제가 발생할 수 있습니다.
- 프록시 초기화
- 프록시 객체가 실제 데이터베이스 쿼리를 발생시키므로, 프록시 객체를 사용할 때 주의가 필요합니다.
'Framework > JPA' 카테고리의 다른 글
[QueryDSL] QueryDSL - @QueryProjction 어노테이션이란❓ (0) | 2024.10.06 |
---|---|
[JPA] @Modifying 어노테이션이란 무엇일까❓ (0) | 2024.10.01 |
[JPA] Spring Data JPA의 페이징과 정렬을 쉽게 구현하는 방법: Pageable과 PageRequest (0) | 2024.09.02 |
[JPA] JPA에서 단방향 및 양방향 관계 이해 (@ManyToOne, @OneToMany, @OneToOne, @ManyToMany) (1) | 2024.08.23 |
[JPA] JPA에서 낙관적 락(Optimistic Locking)을 통한 동시성 제어하기 (@Version) (0) | 2024.08.22 |