ABOUT ME

-

오늘
-
어제
-
-
  • JPA - JPA의 원리
    Back-end/JPA 2020. 6. 30. 17:01

    JPA의 원리

    JPA가 동작하는 원리에 대해서 학습해보겠습니다.

    JpaRepository<Entity, Id> 인터페이스

    • 위 인터페이스를 사용하면 기본적인 CRUD 기능을 포함한 내장 API를 사용할 수 있습니다.
    • @Repository가 없어도 빈으로 등록해 줍니다.

    JpaRepository가 없을 때 로직

    @Repository
    @Transactional
    public class PostRepository {
    
        @PersistenceContext
        EntityManager entityManager;
    
        public Post add(Post post) {
            entityManager.persist(post);
            return post;
        }
    
        public void delete(Post post) {
            entityManager.remove(post);
        }
    
        public List<Post> findAll() {
            return entityManager.createQuery("SELECT p FROM Post AS p", Post.class).getResultList();
        }
    }

     

    Principle

    위처럼 하나하나 CRUD에 관련된 로직을 설정해줬었습니다.
    하지만 JPA를 활용하면 아래와 같은 인터페이스 하나로 가능합니다.

     

    Principle

    인터페이스로 생성하고 JpaRepository를 상속받아 사용합니다. 이 JpaRepository는 빈으로 등록할 필요도 없습니다.

    Principle

    이렇게 만든 인터페이스를 의존성 주입만 받고 바로 사용할 수 있습니다.
    그렇다면 빈으로 등록되는 과정은 어떻게 될까요? 바로 @EnableJpaRepositories부터 시작되는 자동설정 입니다.

    EnableJpaRepositories

    SpringBoot가 아닌 Spring 프로젝트에서는 @EnableJpaRepositories를 애플리케이션 클래스에 설정해주어야 합니다.
    하지만 SpringBoot에서는 내장이 되어있기 때문에 따로 선언하지 않아도 됩니다.

    그 시작은 @Import(​JpaRepositoriesRegistrar.class​)로서 이 클래스에 ​ImportBeanDefinitionRegistrar​가 빈으로 등록하게 해줍니다. 이 과정을 학습해보겠습니다.

    ImportBeanDefinitionRegistrar​ 구현

    Junjang 클래스

    빈으로 등록할 클래스를 생성하겠습니다.

    public class Junjang {
    
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }

     

    Principle

    name을 출력하도록 만들어줍니다.

    JunjangRegistrar 클래스 구현

    Junjang 클래스를 빈으로 등록하는 과정입니다.

    public class JunjangRegistrar implements ImportBeanDefinitionRegistrar {
        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
            beanDefinition.setBeanClass(Junjang.class);
            beanDefinition.getPropertyValues().add("name", "kimjunhyeung");
    
            beanDefinitionRegistry.registerBeanDefinition("Junjang", beanDefinition);
        }
    
    }

     

    Principle

    ImportBeanDefinitionRegistrar를 구현하여 메소드를 오버리아딩 한 후 Junjang 클래스를 가져와 클래스의 변수명과 값을 넣습니다. 그리고 beanDefinitionRegistry에 등록합니다.

    Application 클래스

    @SpringBootApplication
    @Import(JunjangRegistrar.class)
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }

     

    Principle

    빈으로 등록할 클래스를 Import 합니다.

    등록된 빈 사용

    @Component
    @Transactional
    public class JpaRunner implements ApplicationRunner {
    
        @Autowired
        Junjang junjang;
    
        @Override
        public void run(ApplicationArguments args) throws Exception {
            System.out.println("=====================");
            System.out.println(Junjang.getName());
        }
    }

     

    Principle

    의존성 주입을 통해 Junjang을 가져와서 출력합니다.

    JPA의 원리를 알아보았습니다. @Repository를 하지 않아도 빈으로 등록되는 과정을 학습하고 직접 빈으로 등록도 해보았습니다.
    어려운 부분이지만 이해하고 사용을 하면 더 빠르게 학습할 수 있을 것입니다.

    'Back-end > JPA' 카테고리의 다른 글

    JPA - Common Interface  (0) 2020.06.30
    JPA - Common Repository  (0) 2020.06.30
    JPA - Query(쿼리)  (0) 2020.06.30
    JPA - FETCH  (0) 2020.06.30
    JPA - 엔티티 상태, Cascade  (0) 2020.06.30

    댓글