You can make anything
by writing

C.S.Lewis

by anonymDev Apr 27. 2022

JPA 카지노 게임 생성의 비밀

진짜는 프록시(Proxy)다

아래 소스코드들의 출처는 spring-project임을 밝힙니다.

spring-data-jpa는 2.6.x를 기준으로 작성했습니다.


spring-data-jpa를 사용하면JPA 카지노 게임를 인터페이스로 선언해서 사용한다.


엔티티의 타입이 Country인 Country카지노 게임 인터페이스를 예시로 정의했다.

publicinterfaceCountry카지노 게임extendsJpa카지노 게임<Country, Long {

Country findByName(String name);

...

}


간단히인터페이스선언하면 되기 때문에편리하다. 그런데직접구현하지않은save(), saveAll(), findAll() 같은메서드들은대체어디서나온걸까? 라는 궁금증을 가진적이 있을까.


비밀은 SimpleJpa카지노 게임에 있다. 지난 글'Jpa카지노 게임는 Save와 Update를 어떻게 구분하는지'에서 SimpleJpa카지노 게임에 대해서 간단하게 언급했었다.

인터페이스로 선언된 Jpa카지노 게임의 save()를 호출하면 내부적으로 SimpleDataJpa카지노 게임의 save()를 호출한다.


Country카지노 게임인터페이스는자체는사실껍데기에불과하다. spring-data-jpa에는JPA카지노 게임생성하는Jpa카지노 게임Factory 클래스가존재하는데개발자가정의한Country카지노 게임 인터페이스를참조하여Jpa카지노 게임대신구현하는역할을한다.


Jpa카지노 게임Factory는 spring-data-commons 모듈의 카지노 게임FactorySupport를 확장하고 있다.


<Jpa카지노 게임Factory.java

importorg.springframework.data.카지노 게임.core.support.카지노 게임FactorySupport;


publicclassJpa카지노 게임Factory extends카지노 게임FactorySupport{

...


카지노 게임FactorySupport는 전달받은 카지노 게임 인터페이스로 Proxy 인스턴스를 생성하는 추상 클래스이다.


<카지노 게임FactorySupport.java

packageorg.springframework.data.카지노 게임.core.support;


publicabstract class카지노 게임FactorySupport implementsBeanClassLoaderAware, BeanFactoryAware {

...


카지노 게임FactorySupport를 확장하여 다양한 spring-data-XXX에서 카지노 게임를 생성한다. 카지노 게임FactorySupport에는 get카지노 게임라는 카지노 게임 인스턴스를 생성하는 메서드가 기본으로 정의돼 있다. 이 메서드는카지노 게임 인터페이스를 구현한 Proxy를생성한다. Jpa카지노 게임Factory는 부모 클래스의 메서드인 get카지노 게임를 상속 받는다.


<카지노 게임FactorySupport.java

public<T T get카지노 게임(Class<T 카지노 게임Interface, 카지노 게임Fragments fragments) {

//첫 번째 파라미터 카지노 게임Interface로 Country카지노 게임가 전달된다.

...

ProxyFactory result = new ProxyFactory();
result.setTarget(target);
result.setInterfaces(카지노 게임Interface, 카지노 게임.class, TransactionalProxy.class);

// 카지노 게임Interface로 전달된 Country카지노 게임의 인터페이스를 구현한다.

...

T카지노 게임 = (T) result.getProxy(classLoader);
...
return repository; // Proxy 인스턴스를 반환한다.

}


대신 spring-data-jpaJpa카지노 게임Factory가 추상 메서드인 get카지노 게임BaseClassSimpleJpa카지노 게임.class반환하도록오버라이드했다.


<Jpa카지노 게임Factory.class

@Override
protectedClass<? get카지노 게임BaseClass(카지노 게임Metadata metadata) {
returnSimpleJpa카지노 게임.class;
}


<카지노 게임FactorySupport.java

protectedabstractClass<? get카지노 게임BaseClass(카지노 게임Metadata metadata);

...


카지노 게임 Base Class 클래스는 무엇일까?


메서드명세를살펴보면Base Class실제카지노 게임 인스턴스를지원하는클래스이다. SimpleJpa카지노 게임실제로생성된Jpa카지노 게임 인스턴스를지원하는(Backing)인스턴스의클래스(타입)된다.

Returns the base class backing the actual repository instance.
Make sure *getTarget카지노 게임(카지노 게임Information) returns an instance of this class.

출처: docs.spring.io


get카지노 게임BaseClass반환하는Base classget카지노 게임Information에서카지노 게임Information 인스턴스를조립할전달된다. 카지노 게임Information은 말 그대로 카지노 게임의 정보를 담고있다(예: 엔티티의 타입은 무엇인지, Base Class는 무엇인지 등등).


<카지노 게임FactorySupport.java

private카지노 게임Information get카지노 게임Information(카지노 게임Metadata metadata,
카지노 게임Composition composition) {

....
return카지노 게임InformationCache.computeIfAbsent(cacheKey, key - {
Class<? baseClass= repositoryBaseClass.orElse(get카지노 게임BaseClass(metadata));

//get카지노 게임BaseClass를 호출해 Base Class를 가져온다(SimpleJpa카지노 게임.class).
returnnew Default카지노 게임Information(metadata, baseClass, composition);
});
}

...


하나 더! API 명세에서 getTarget카지노 게임가 반환하는 인스턴스의 클래스가 Base Class와 같아야 한다고 했다.

Make sure *getTarget카지노 게임(카지노 게임Information) returns an instance of this class.

카지노 게임InformationgetTarget카지노 게임인자로Base Class 정보를전달해Target카지노 게임 인스턴스의Class 타입을결정한다. Jpa카지노 게임Factory경우Target카지노 게임SimpleJpa카지노 게임.class되겠다.


Target카지노 게임는 무엇일까?

Query Proxy를 지원하는 카지노 게임 인스턴스라고 한다.

Create a 카지노 게임 instance as backing for the query proxy.

출처: docs.spring.io


앞서 카지노 게임FactorySupport에는 실질적인 카지노 게임 인스턴스를 생성하는 get카지노 게임가 메서드가 정의돼 있다고 했다. 메서드를 훑어보면서 Target카지노 게임에 대해서 알아보자(아래 코드의 코멘트 (1), (2), (3). (4)를 읽으면서 따라가 보자)


<카지노 게임FactorySupport.java

public<T T get카지노 게임(Class<T 카지노 게임Interface, 카지노 게임Fragments fragments) {

...

카지노 게임Information information =get카지노 게임Information(metadata, composition);

//(1) Base Class 정보가 담긴 카지노 게임Information을 가져온다.

...

Object target = getTarget카지노 게임(information);//(2) Target카지노 게임를 생성한다.
...
ProxyFactory result = new ProxyFactory();
result.setTarget(target);//(3) Target카지노 게임는 Proxy의 target 인자로 전달된다.
result.setInterfaces(카지노 게임Interface, 카지노 게임.class, TransactionalProxy.class);

...

T카지노 게임 = (T) result.getProxy(classLoader);
...
returnrepository; //(4) Proxy 카지노 게임를 반환한다.

}


아하! Proxy 인스턴스의 target이 Target카지노 게임였구나! 즉 Proxy로 생성된 카지노 게임 인스턴스의 target 인스턴스가 SimpleJpa카지노 게임의 인스턴스였다는걸 알게 됐다. 그렇다면 SimpleJpa카지노 게임가 뒤에서 Jpa카지노 게임 인터페이스의 실 구현체를 제공한다는 의미이다.


정리하면

1. 최종적으로 Bean으로 생성되는 Country카지노 게임는 Proxy 인스턴스이다(Proxy 카지노 게임).

2. Jpa카지노 게임는 Proxy 인스턴스의 Target을 SimpleJpa카지노 게임.class의 인스턴스로 주입한다.

3. Proxy 카지노 게임 인스턴스 내부에서 SimpleJpa카지노 게임(target)가 실 구현체를 실행한다.

브런치는 최신 브라우저에 최적화 되어있습니다.