AOP란?

  • AOP는 공통의 관심사를 추상화해 잘 보관하고 있다가 필요한 곳에 동적으로 삽입하며 적용해주는 기술이다. 이로 인해 핵심 로직과 부가 기능을 분리할 수 있고 각각의 기능은 단일 책임을 가진 코드를 유지할 수 있다.

핵심 로직과 부가 기능이 같이 있다면

  • 두 가지 책임을 가지므로 하나의 책임에 인한 코드 수정은 다른 코드에 side effect가 발생할 수 있다.
  • 두 가지 기능이 접목되어 있어 테스트 코드를 작성하려 할 때도 두가지 기능을 다 고려 해야한다.
  • 비즈니스 로직이 복잡하거나 부가 기능이 추가될수록 유지보수 하기가 어려워진다.
  • 유지보수와 비슷한 맥락으로 기능을 확장하거나 다른 전략으로 기능을 변경하기도 어려워 진다.

AOP를 적용한다면?

  • 코드에는 핵심 로직만 남기고 부가 기능은 별도로 추상화하여 주입 받는 방식으로 리팩토링 할 수 있을 것이다.
  • //대표적인 AOP 방식이 @Transactional 적용 @Transactional public void upgradeLevels() throws Exception { List<User> users = userDao.getAll(); for (User user : users) { if (canUpgradeLevel(user)) { upgradeLevel(user); } } this.transactionManager.commit(status); }

코드를 분리하면 어떤 점이 좋을까?

  • 메서드 또는 클래스는 한 책임을 가질 수 있는 코드를 작성할 수 있고 응집도 높은 코드를 작성할 수 있다.
  • 테스트 코드 또한 비즈니스 로직에 대한 테스트 케이스만 작성하면 된다.
  • 유지보수 측면에서도 비즈니스 로직 수정시에 부가 기능에 대한 side effect는 찾아 볼 수 없게 된다.

프록시란?

  • 자신의 클라이언트가 사용하려고 하는 실제 대상인 것처럼 위장해서 클라이언트의 요청을 받아주는 것(대리인 ,대리자)
  • 사용 목적에 따라
    • 클라이언트가 타깃에 접근하는 방법을 제어하기 위해
      • 프록시 패턴
    • 타깃에 부가적인 기능을 부여 해주기 위
      • 데코레이터 패턴

AOP 용어 정리

  • Target Object
    • 부가 기능을 부여할 대상
  • Aspect
    • AOP의 기본 모듈. 그 자체로 애플리케이션의 핵심 기능을 담고있진 않지만 애플리케이션을 구성하는 중요한 한가지 요소, 부가될 기능을 정의한 Advice와 어드바이스를 어디에 적용할지 결정하는 Pointcut을 함께 가짐
  • Advice
    • 타깃에게 제공할 부가 기능을 담은 모듈. 타깃이 필요없는 순수한 부가 기능. Aspect가 무엇을 언제 할지를 정의하고 있음
  • Join point
    • 프로그램의 실행 내부에서 Advice가 적용될 수 있는 위치
  • Pointcut
    • Advice에 적용할 Joinpoint를 선별하는 작업 또는 그 기능을 정의한 모듈

AOP를 구현하는 방법

  • 컴파일 시점에 코드에 공통 기능 삽입
  • 클래스 로딩 시점에 바이트 코드에 공통 기능 삽입
  • 런타임 시점에 프록시 객체를 생성하여 공통 기능 삽입
    • Spring에서 사용하는 방법

'Computer science > Spring' 카테고리의 다른 글

Stereo Type  (0) 2023.06.22
Spring Security  (0) 2023.06.21
@Controlleradvice,@ExceptionHandler  (0) 2023.06.21
@Transactional  (0) 2023.06.15
영속성 컨텍스트  (0) 2023.06.15

Stereo Type이란?

  • 스프링 컨테이너가 스프링 관리 컴포넌트로 식별하게 해주는 단순한 마커다. 즉 scan-auto-detection과 dependency injection을 사용하기 위해서 사용되는 가장 기본 어노테이션이다.
  • Stereo Type이 범용적으로 많이 사용하게 된 시기는 Spring 2.5부터였다. 그 이전까지는 xml파일에 bean을 등록하여 관리하였다.

그러나 모든 bean들을 xml 파일로 관리하다보니 다른 보일러플레이트 코드와 함께 xml 파일만 비대해지게 될 뿐이었다.

그래서 Spring 2.0에서는 @Repository가 등작하였고, Spring 2.5부터는 @Component, @Controller, @Service, @Configuration등이 등작하면서 Stereo type에 대한 정의가 범용적으로 사용하게 되었다.

@Component

  • 빈으로 간주되어 DI 컨테이너에서 사용할 수 있게 하는 기본 어노테이션이다,.

@Bean과 @Component는 어떤 차이가 있는가?

  • @Component는 클래스 상단에 적으며 그 default로 클래스 이름이 bean의 이름이 된다. 또한 spring에서 자동으로 찾고(@ComponentScan) 관리해주는 bean이다.
  • @Bean은 @Configuration으로 선언된 클래스 내에 있는 메서드를 정의할 때 사용한다. 이 메서드가 반환하는 객체가 bean이 되며 default로 메서드 이름이 bean의 이름이 된다.

@RestController와 @Controller의 차이는?

  • @RestController는 Spring 3.0 에서 추가된 어노테이션으로 RESTful web service를 제공하기 위해 @Controller를 확장한 개념이다. 기능적인 측면에서 보았을 땐 @Controller에 @ResponseBody 어노테이션을 추가된 기능이라고 보면 된다.
  • @ResponseBody 어노테이션의 기능은 결과값을 View를 통해서 출력되지 않고 HTTP Response Body에 직접 쓰여지게 되며 이때 리턴되는 데이터 타입에 따라 MessageConverter 에서 변환이 이뤄진 후 쓰여지게 된다.

@Service

  • Service annotation은 단순히 서비스 레이어에서 사용하는 bean이라는 것을 구분하기 위한 용도로 정의한다. 그러므로 @Component로 대체해도 무방하지만 권장하지는 않는다.

@Repository

  • 검사 되지 않은 예외(DAO 메소드에서 발생)를 Spring DataAccessException으로 변환 할 수 있게 해준다.

@Configuration

  • 한 개 이상의 @Bean 어노테이션으로 정의한 bean 들을 생성하려 할 때 클래스에 정의하는 어노테이션이다.

'Computer science > Spring' 카테고리의 다른 글

AOP  (0) 2023.06.22
Spring Security  (0) 2023.06.21
@Controlleradvice,@ExceptionHandler  (0) 2023.06.21
@Transactional  (0) 2023.06.15
영속성 컨텍스트  (0) 2023.06.15

Spring Security Process

  1. 사용자가 로그인 정보와 함께 인증 요청(Http Request) 한다.
  2. AuthenticationFilter가 이 요청을 가로채서 UsernamePasswordAuthenticationToken이라는 인증용 객체를 생성한다.
  3. AuthenticationManager의 구현체인 ProviderManager에게 UsernamePasswdAuthenticationToken 객체를 전달한다.
  4. AuthenticationManager에 등록된 AuthenticationProvider에 UsernamePasswordAuthenticationToekn 객체를 전달한다.
  5. 실제 데이어베이스에서 사용자 인증정보를 가져오는 UserDetailService에 사용자 정보를 넘겨주게 된다.
  6. 넘겨받은 사용자 정보를 통해 DB에서 찾은 사용자 정보인 UserDetails 객체를 생성한다. 이 때 UserDetails는 인증용 객체와 도메인용 객체를 분리하지 않고 인증용 객체에 상속해서 사용하기도 한다.
  7. AuthenticationProvider는 UserDetails를 넘겨받고 사용자 정보를 비교한다.
  8. 인증이 완료되면 권한 등의 사용자 정보를 담은 Authentication 객체를 반환한다.
  9. 다시 최초의 AuthenticationFilter에 Authentication 객체가 반환된다.
  10. Authentication 객체를 SecurityContext에 저장한다.
  11. 최종적으로 SecurityContextHolder는 세션 영역에 있는 SecurityContext에 Authentication 객체를 저장한다. 세션에 사용자 정보를 저장한다는 것은 스프링 시큐리티가 전통적인 세션-쿠키 기반의 인증 방식을 사용한다는 것을 의미한다.

모든 절차는 동일한가?

  • 모든 절차는 동일하지 않다. Filter를 구현하지 않고 RequestMatcher를 통해 바로 AuthenticationManager에게 요청값을 그대로 전달할 수 도 있다. 또는, UserDetailsService의 역할을 ProviderManager가 직접 수행하는 경우도 있다.

AuthenticationManager는 왜 필요하나?

  • 프로세스를 살펴보면 실제로 AuthenticationManager는 직접 수행하는 로직은 없고 등록된 ProviderManager를 통해서 직접적인 인증 처리를 구현하고 있다. 그러므로 AuthenticationManager를 거치지 않고 Provider Manager를 직접 수행해도 문제가 되지는 않는다.
  • 하지만 AuthenticationManager를 거치게 되면 요청값에 따라 다양한 ProviderManager를 분기처리가 가능하다. 또한 한 종류의 ProviderManager를 사용한다고 하더라도 애플리케이션이 추후에 인증 절차가 변경된다고 하더라도 ProviderManager만 교체 하게되면 별도의 코드 수정은 필요하지 않게 된다.

'Computer science > Spring' 카테고리의 다른 글

AOP  (0) 2023.06.22
Stereo Type  (0) 2023.06.22
@Controlleradvice,@ExceptionHandler  (0) 2023.06.21
@Transactional  (0) 2023.06.15
영속성 컨텍스트  (0) 2023.06.15

에외처리

예외 처리의 방법

  • 예외 복구
    • 예외가 발생하면 예외 상황에 대해 알맞게 처리하여 복구한다.(try catch)
  • 예외 회피
    • 예외를 직접 처리하지 않고 예외를 상위 메서드에 위임한다.(throw)
  • 예외 전환
    • 예외를 위임하되 발생한 예외를 그대로 위임하는 것이 아닌 적절한 예외로 전환하여 위임한다.(restTemplate.doExcute)

예외 복구 범위

  • 메서드 영역
    • 메서드 영역은 종속된 복구 기능으로 단순히 try catch 사용하면 된다.
  • 클래스 영역
    • 클래스 내 공통 예외 복구는 @ExceptionHandler 사용할 수 있다.
  • 전역 영역
    • @ControllerAdvice 사용할 수 있다.

컨트롤러 내 예외처리

  • 특정 컨트롤러 내부에서 예외를 처리하고 싶을 경우 @ExceptionHandler를 사용하여 해결하자 이는 @Controller 나 @RestController 빈 내에서 발생하는 특정 예외를 처리해주는 기능을 지원한다.
@ExceptionHandler({NullPointerException.class, ClassCastException.class})
    public String handle(Exception ex){
        return "Exception Handle!!!";
    }

글로벌 예외처리

  • 특정 컨트롤러가 아닌 여러 컨트롤러로 공통된 로직을 구현하기 위해서 @ControllerAdvice를 사용할 수 있다.
  • @ControllerAdvice
    • @ControllerAdvice는 컨트롤러를 보조해주는 기능을 제공한다는 것을 명시한다.
    • @RestControllerAdvice public class ControllerSupport { @ExceptionHandler({NullPointerException.class, ClassCastException.class}) public String handle(Exception ex) { return "Exception Handle!!!"; } }
  • 컨트롤러 내부에 Exception을 처리하는 로직을 따로 작성하지 않아도 된다.

@RestControllerAdvice와 @ControllerAdvice의 차이는?

  • @ResponseBody의 유무 차이만 있을 뿐이다.

status code에도 어떤 에러인지 명시적으로 내어주고 싶은 경우에 @ResponseStatus를 사용할 수 있다.

@RestControllerAdvice
public class ControllerSupport {

    @ExceptionHandler({NullPointerException.class, ClassCastException.class})
    @ResponseStatus(code = HttpStatus.BAD_REQUEST)
    public String handle(Exception ex) {
        return "Exception Handle!!!";
    }
}

'Computer science > Spring' 카테고리의 다른 글

Stereo Type  (0) 2023.06.22
Spring Security  (0) 2023.06.21
@Transactional  (0) 2023.06.15
영속성 컨텍스트  (0) 2023.06.15
Filter 와 Interceptor  (0) 2023.06.15

Transactional

  • 스프링에서 트랜잭션 처리는 보통 @Transactional 어노테이션을 많이 사용하게 된다.
  • @Transactional은 클래스 또는 메서드에 사용할 수 있으며 @Transactional이 포함된 메서드가 호출될 경우, 프록시 객체가 생성된다.
  • 프록시 객체는 해당 메서드 실행 이전에 PlatformTransactionManager를 사용하여 트랜잭션을 시작하고 결과에 따라 Commit 또는 Rollback한다.

Commit과 Rollback은 어느 경우에 발생하는가?

  • CheckedException or 예외가 없을 때는 Commit
  • UncheckedException이 발생하면 Rollback

@Transactional 우선순위는 어떻게 되는가?

  1. 클래스 메서드
  2. 클래스
  3. 인터페이스 메서드
  4. 인터페이스

주의할 점

@Transactional 어노테이션 같은 경우 Spring AOP를 이용하게 되는데 이 AOP는 기본적으로 DynamicProxy를 이용한다. Dynamic Proxy는 인터페이스 기반으로 동작하기 때문에 인터페이스가 없을 경우 트랜잭션이 동작하지 않는다.

  • 인터페이스 없이 트랜잭션 동작하게 하려면 CGLib Proxy를 이용하면 된다. CGLib Proxy는 클래스에 대한 Proxy가 가능하기 때문에 인터페이스가 없어도 된다.
  • Spring 의 코드 삽입 방법은 크게 2가지 방법이 있습니다.
    • 바이트 코드 생성 (CGLIB 사용)
    • 프록시 객체 사용
  • 2가지 방법중 Spring 은 기본적으로 프록시 객체 사용 이 선택됩니다. 그렇기에 interface 가 반드시 필요합니다.SpringBoot 는 기본적으로 바이트 코드 생성 이 선택됩니다. 그렇기에, 굳이 interface 가 필요없습니다.
  • 만약 개발환경이 SpringBoot 라면 Books 인터페이스 없이 봐도 무방합니다.

@Transactinal은 public method에만 적용된다.

  • @Transactional은 프록시 기반으로 동작하기 때문에 public method가 아니면 동작하지 않는다.

동일한 클래스 내의 호출은 @Transactional이 동작하지 않는다.

  • 프록시 기반으로 동작하기 때문에 외부에서 접근할 때 AOP를 통해서 프록시 객체를 접근할 수 있다. 그러나 클래스 내부에서 다른 메서드를 호출하게 되면 프록시로 접근하지 않고 직접 접근하기 때문에 메서드에 선언해 놓은 @Transactional이 정상적으로 동작하지 않는다.
    • 클래스 내부 메서드를 호출하여 @Transactinal을 동작하게 하고 싶다면?
      • 가장 간단한 방법은 새로운 클래스를 생성하여 메서드를 위임하는 것
      • 클래스 생성이 어렵다면 aspectj를 사

'Computer science > Spring' 카테고리의 다른 글

Spring Security  (0) 2023.06.21
@Controlleradvice,@ExceptionHandler  (0) 2023.06.21
영속성 컨텍스트  (0) 2023.06.15
Filter 와 Interceptor  (0) 2023.06.15
OSIV  (0) 2023.06.08

영속성 컨텍스트란?

  • Server side와 Database 사이에 엔티티를 저장하는 논리적인 영역이라고 할 수 있다. 엔티티 매니저로 엔티티를 저장하거나 조회하면 엔티티 매니저는 영속성 컨텍스트에 보관하고 관리한다.
  • 영속성 컨텍스트는 엔티티 매니저를 생성할 때 하나 만들어진다. 그리고 엔티티 매니저를 통해서 영속성 컨텍스트에 접근할 수 있고 영속성 컨텍스트를 관리할 수 있다.

영속성 컨텍스트가 엔티티를 관리하면 얻게되는 장점

1차 캐시

  • Map 객체로 저장
    • 엔티티를 식별자 값(@Id 매핑)으로 구분한다. Key-value로 관리하는데 이때 key 값이 @Id 값이 된다.
  • 식별자 값 필요
    • 영속상태의 엔티티는 반드시 식별자 값이 있어야 한다.
  • 1차 캐시를 사용하면 한 가지 기능을 두개의 트랜잭션으로 처리할 경우?
    • OSIV를 사용하여 영속성 컨텍스트의 데이터를 공유한다.
  • 2차 캐시는 언제 사용하나?
    • 하이버 네이트가 지원하는 캐시는 크게 3가지가 있음
      • 엔티티 캐시
        • 엔티티 단위로 캐시한다. 식별자로 엔티티를 조회하거나 컬렉션이 아닌 연관된 엔티티를 로딩할 때 사용한다.
      • 쿼리 캐시
        • 쿼리와 파라미터 정보를 키로 사용해서 캐시한다.
      • 컬렉션 캐시
        • 엔티티와 연관된 컬렉션을 캐시한다. 컬렉션이 엔티티를 담고 있으면 식별자 값만 캐시한다.
        • 문제는 쿼리 캐시나 컬렉션 캐시만 사용하고 대상 엔티티에 엔티티 캐시를 적용하지 않으면 성능상 심각한 문제가 발생할 수 있다.

동일성 보장

  • 동일한 객체 반환
    • Collection에서 객체를 빼오듯이 같은 객체를 반환하게 되면 새로운 객체가 나오는 것이 아니라 동일한 객체가 반환된다.
  • JPQL을 사용하게 되면 기존 영속성 컨텍스트의 데이터는 갱신되나?
    • 변경감지
      • 자동 Update
        • 영속성 상태의 객체는 객체의 데이터가 변경이 되면, 자동 update 된다.
        • EntityManager에서 flush가 되고, commit이 된다.
          • flush가 되는 시점
            • 강제 flush 호출
            • 트랜잭션 종료시
            • JPQL 쿼리 실행
              • JPQL은 실제 DB side에서 데이터를 가져오기 때문에 동기화를 위하 JPQL 쿼리가 실행 전에 flush가 된다.

트랜잭션으로 인한 쓰기 지연

  • 쓰기 지연
    • 영속성 컨텍스트는 트랜잭션 범위 안에서 동작한다. 그래서 트랜잭션이 끝나야 commit이 이뤄지고 반영된다.

Lazy 로딩

  • 엔티티와 관계가 맺어진 엔티티의 데이터를 실제로 접근하여 자식 객체가 필요한 시점에 로딩합니다. 이를 통해 불필요한 데이터베이스 쿼리를 줄이고, 성능을 최적화할 수 있습니다.

Checked Exception과 트랜잭션은 아무 상관 없다

  • @Transactional은 기본적으로 unchecked exception에 대해서만 rollback을 수행한다고 알고있었다. 하지만 엄밀히 말하자면 그것은 오해라고 할 수 있다.
  • 트랜잭션이, 메세지 트랜잭션을 말하는 건지, 데이터베이스 트랜잭션을 말하는 건지 데이터베이스의 트랜잭션을 말하는 것이라도 checked exceptoin이든 unchecked exceptoin이든 에 따라 롤백을 할지 안할지는 전적으로 개발자에게 달려 있다.
    • 즉, 자바 프로그래밍 언어에서는 위와 같은 규칙은 없다.
  • Exception 종류에 따라 롤백 유무가 다르다고 정리된 이유는, 자바의 유명한 프레임워크 Spring Framework 의 트랜잭션 처리에서 비롯 됐기 때문
  • 스프링에서는 기본적으로는 런타임 예외 같은경우 바로 롤백을 한다.
  • 그러나 이 상황도 개발자가 옵션을 어떻게 설정하느냐에 따라 충분히 바꿀 수 있는 요소이다. 예를들어 런타임 자식 예외클래스 중에 몇몇을 골라서 롤백을 하지 않도록 설정이 가능하다.
  • 따라서 정리하자면, 자바를 스프링과 동일시 한다면 위의 정리는 맞지만, 자바 프로그래밍에서만 생각한다면 checked exceptoin과 unchecked exceptoin과 트랜잭션 롤백 유무는 연관이 없는 것이다. 그리고 예외발생이 트랜잭션 처리에 대해서는 checked 든 unchecked 든 전적으로 개발자 마음에 달려있다고 볼 수 있다.

'Computer science > Spring' 카테고리의 다른 글

@Controlleradvice,@ExceptionHandler  (0) 2023.06.21
@Transactional  (0) 2023.06.15
Filter 와 Interceptor  (0) 2023.06.15
OSIV  (0) 2023.06.08
N + 1 문제  (0) 2023.06.08

Filter

  • DispatcherServlet 이전에 실행된다.
  • 모든 요청을 처리하는 DispatcherServlet 앞단에 실행되기 때문에 모든 일괄적인 요청에 대해 변경하거나 유효성 검사를 한곳에서 처리할 수 있다.
  • 스프링 빈이 아니므로 web.xml에 등록한다.
  • Filter는 빈으로 등록되지 않아서 주입을 받을 수는 없지만 애플리케이션 컨텍스트의 생성된 빈들로 주입 받을 수는 있다.(SpringSecurity Filter)

Interceptor

  • Interceptor는 DispatcherServlet 다음에 실행되는 스프링 내부 영역으로 Application Context 내에서 관리되므로 Bean으로 등록할 수 있다.
  • Interceptor는 특정 HandlerMapping에 종속되어 다양한 전략의 Interceptor를 생성할 수 있다.
  • Interceptor는 @ControllerAdvice @ExceptionHandler를 이용하여 예외 처리가 가능하다.

'Computer science > Spring' 카테고리의 다른 글

@Transactional  (0) 2023.06.15
영속성 컨텍스트  (0) 2023.06.15
OSIV  (0) 2023.06.08
N + 1 문제  (0) 2023.06.08
스프링 프레임워크 특징  (0) 2023.06.08

OSIV

  • open session in view
  • view 영역까지 session 영역이 열어둔다는 의미

Open Session? View 영역?

  • Open Session은 세션 영역을 연다는 의미
  • 정확히는 영속성 컨텍스트의 영역을 의미한다.
  • View 영역은 일반적으로 생각하는 Controller 영역이나 뷰 영역(jsp, thymeleaf) 영역을 의미한다.
  • Controller나 뷰 영역에도 영속성 컨텍스트를 유지한다는 것

영속성 컨텍스트의 범위는?

  • 영속성 컨텍스트는 엔티티 매니저와 연관이 깊다.
  • 엔티티 매니저가 생성되는 시점에 생성되고 엔티티 매니저가 종료되는 시점에 소멸한다. 트랜잭션 매니저를 별도로 구현하지 않고 @Transactional 애너테이션을 사용한다면 애너테이션이 붙어있는 메서드 영역 내에서 영속성 컨텍스트가 생성되고 소멸되는 것으로 이해할 수 있다.

영속성 컨텍스트의 범위를 확장해야 하는 이유?

  • @Transactional 애너테이션은 보통 Service 레이어에서 많이 사용하는데 Service 레이어가 아닌 컨트롤러나 뷰 영역에서도 영속성 컨텍스트가 필요한 경우가 있을 수 있지만 많이 경험하지 못하였을 것이다.
    • 대부분 DTO를 사용하기 때문
  • 컨트롤러 영역에서 필요한 DTO 모델을 생성하여 Dao에서 내려받은 결과값을 DTO에 바인딩 해주기 때문에 OSIV를 고려해야하는 경우가 많지 않았을 것이다.
  • 하지만 몇년 전까지만 하더라도 JPA를 사용하면 엔티티를 그대로 모델로 사용하는 경우가 많았고 컨트롤러, 뷰 영역에서도 엔티티를 조작하는 경우가 발생

뷰 영역에서 엔티티를 수정할 경우 DB반영이 될 까?

  • 트랜잭션을 사용하는 서비스 계층이 끝날 때 트랜잭션이 커밋되면서 이미 플러시를 했기 때문에 스프링이 제공하는 OSIV 서블릿 필터나 OSIV 스프링 인터셉터는 요청이 끝나면 플러시를 호출하지 않고 em.close()로 영속성 컨텍스트만 종료해 버리므로 플러시가 일어나지 않는다. 만약 뷰 영역에서 em.plush()를 강제로 호출해도 트랜잭션 범위 밖이라는 예외가 발생하게 될 것이다.

OSIV On

  • 최초 데이터베이스 커넥션 시작 시점부터 api 응답이 끝날 때까지 영속성 컨텍스트와 데이터베이스 커넥션을 유지한다.
    • api컨트롤러에서 지연 로딩이 가능
  • 지연로딩은 영속성 컨텍스트가 살아있어야 가능하고, 영속성 컨텍스트는 기본적으로 데이터베이스 커넥션을 유지한다. 이것이 큰 장점
  • 너무 오랜시간 데이터베이스 커넥션 리소스를 사용하기 때문에 실시간 트랙픽이 중요한 애플리케이션에서는 커넥션이 모자랄 수 있다.

OSIV Off

  • 트랜잭션을 종료하는 시점에서 영속성 컨텍스트를 닫고, 데이터 베이스 커넥션도 반환한다. 따라서 커넥션 리소스를 낭비하지 않는다.
  • 지연로딩을 트랜잭션 내부에서 처리해야 한다.
  • 트랜잭션이 끝나기 전에 모든 지연로딩을 강제로 호출해 두어야 한다.

'Computer science > Spring' 카테고리의 다른 글

@Transactional  (0) 2023.06.15
영속성 컨텍스트  (0) 2023.06.15
Filter 와 Interceptor  (0) 2023.06.15
N + 1 문제  (0) 2023.06.08
스프링 프레임워크 특징  (0) 2023.06.08

N + 1 문제란?

  • 연관 관계에서 발생하는 이슈로 연관 관계가 설정된 엔티티를 조회할 경우 조회된 데이터 갯수(n) 만큼 연관관계의 조회 쿼리가 추가로 발생하여 데이터를 읽어오게 되는 문제.

왜 발생하는 것인가?

  • jpaRepository에 정의한 인터페이스 메서드를 실행하면 JPA는 메서드 이름을 분석하여 JPQL을 생성하여 실행하게된다.
  • JPQL은 SQL을 추상화한 객체지향 쿼리 언어로서 특정 SQL에 종속되지 않고 엔티티 객체와 필드 이름을 가지고 쿼리를 한다.
  • 그렇기 때문에 JPQL은 findAll()이란 메서드를 수행하였을 때 해당 엔티티를 조회하는 select * from table 쿼리만 실행하게 된다.
  • JPQL 입장에서는 연관관계 데이터를 무시하고 해당 엔티티 기준으로 쿼리를 조회
  • 그렇기 때문에 연관된 엔티티 데이터가 필요한 경우, FetchType으로 지정한 시점에 별도로 호출하게 된다.

해결방안

Fetch join

  • 사용자가 원하는것은 join 코드 일 것
  • 최적화된 쿼리를 우리가 직접 사용할 수 있음 → Fetch join
  • JpaRepository에서 제공해주는 것은 아니고 JPQL로 작성해야 한다.
  • ex)
@Query("select o from Owner o join fetch o.cats")
List<Owner> findAllJoinFetch();
  • 연관관계의 연관관계가 있을 경우에도 하나의 쿼리 문으로 표현할 수 있으므로 유리하다.
  • 데이터 호출 시점에 모든 연관 관계의 데이터를 가져오기 때문에 FetchType을 Lazy로 해놓는 것이 무의미해짐

EntityGraph

  • @EntityGraph의 attributePaths에 쿼리 수행시 바로 가져올 필드명을 지정하면 Lazy가 아닌 Eager 조회로 가져오게 된다.
  • Fetch join과 동일하게 JPQL을 사용하여 query문을 작성하고 필요한 연관관계를 EntityGraph에 설정하면 된다.
  • Fetch join과는 다르게 join문이 outer join으로 실행된다. ( Fetch join == inner join)
  • ex
@EntityGraph(attributePaths = "cats")
@Query("select o from Owner o")
List<Owner> findAllEntityGraph();

컬렉션 Fetch join

  • 컬렉션 fetch join은 일대다 관계에서 사용할 수 있으며 데이터가 많아질 수 있다.
    • DISTINCT로 중복 제거가 가능
    • SQL의 DISTINCT
      • ROW가 완벽히 일치해야 중복 제거
    • JPQL의 DISTINCT
      • SQL의 DISTINCT 기능 뿐만 아니라 동일한 엔티티면 중복 제거
        • application단에서 엔티티 중복을 제거한다.

Fetch join의 한계와 극복

  • 컬렉션을 fetch join 하면 페이징 API를 사용할 수 없다.
    • 일대일, 다대일 같은 단일 값 연관 필드들은 페치 조인을 해도 페이징이 가능하다.
    • HIbernate는 경고로그를 남기며 메모리에서 페이징을 한다.
    • 전체 데이터를 가져와 메모리에 올려놓고, 메모리에서 N개씩 데이터를 결과로 보여준다. 자칫 OutOfMemory가 발생할 수 있고, 성능에 영향을 줌

xxxToOne 관계를 모두 페치조인 한다.

  • toOne관계는 row수를 증가시키지 않기 때문
  • 컬렉션은 지연로딩으로 조회

@컬렉션은 지연로딩으로 설정 → Batch_fecth_size를 사용

  • hibernate.default.batch_fetch_size(글로벌 설정)
  • @BatchSize(디테일 설정)
  • 프록시 객체를 설정한 size만큼 in 쿼리로 조

'Computer science > Spring' 카테고리의 다른 글

@Transactional  (0) 2023.06.15
영속성 컨텍스트  (0) 2023.06.15
Filter 와 Interceptor  (0) 2023.06.15
OSIV  (0) 2023.06.08
스프링 프레임워크 특징  (0) 2023.06.08

스프링 프레임워크란?

객체지향적으로 설계한 POJO 유지하며 애플리케이션을 쉽고 효과적으로 개발할 수 있도록 지원하는 프레임워크

  • 스프링을 사용하면 개발자는 비즈니스 로직에만 집중할 수 있다

POJO

  • Plain Old Java Object
  • 특정 기술과 환경에 종속적이지 않은 순수한 자바 객체

PSA

  • Portable Service Abstraction
  • 추상화 계층을 사용하여 어떤 기술을 내부에 숨기고 사용자에게 편의성을 제공하며, 이 기술을 다른 기술 스택으로 간편하게 바꿀 수 있는 확장성을 가진 서비스를 의미한다.
  • ex) Jpa 인터페이스를 이용하여 orm기술을 사용

IoC

  • Inversion of Control - 제어의 역전
  • 스프링에서는 일반적인 자바 객체를 new로 생성하여 개발자가 관리하는 것인 아닌 Spring Container에서 객체를 관리하고 제어한다.
  • 개발자 → 프레임워크로 제어권한이 넘어감

DI

  • Dependency injection - 의존성 주입
  • 각각의 계층이나 서비스들 간에 의존성이 존재할 경우 프레임워크가 서로 연결시켜 준다.
  • 장점
    • 유지보수가 쉬우며 테스트가 용이함
    • 객체간 결합도가 낮아진다.
    • 코드의 재사용성과 유연성이 높아진다.

AOP

  • 관점 지향 프로그래밍
  • 관점 지향
    • 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어서 보고 그 관점을 기준으로 각각 모듈화
  • AOP를 사용하여, logging, transaction관리, security에서의 적용 등 AspectJ와 같이 완벽하게 구현된 AOP와 통합하여 사용이 가능

'Computer science > Spring' 카테고리의 다른 글

@Transactional  (0) 2023.06.15
영속성 컨텍스트  (0) 2023.06.15
Filter 와 Interceptor  (0) 2023.06.15
OSIV  (0) 2023.06.08
N + 1 문제  (0) 2023.06.08

+ Recent posts