AOP란?
AOP란 관점 지향 프로그래밍의 약자로 흩어진 관심사를 하나로 모듈화 한 것이다. OOP의 개념에서 더 확장된 개념이다.
AOP를 구현하는 방법
1. AspectJ
2. Spring AOP
AspectJ는 자바에서 제공하는 AOP 기술이다. 3가지 바이트 코드 위빙을 사용한다.
위빙이란?
Aspect 를 대상 객체(Target)에 연결시켜 AOP 객체로 만드는 바이트 코드 및 객체 조작과정
1. Compile-time weaving: 소스 코드를 입력하고 클래스 파일을 생성한다.
2. Post-compile weaving: 컴파일 후 위빙, JAR와 클래스 파일을 위빙하는데 사용한다.
3. Load-time weaving: 클래스 로더가 클래스 파일을 JVM에 로드할 때까지 위빙이 연기된다.
컴파일 또는 클래스 로드 시점 조작을 제공한다. 런타임 시점에는 영향을 미치지 않는다. 내부 구조가 복잡하고 방법이 다양하다.
Spring AOP은 런타임 위빙을 사용한다.
스프링에서는 프록시 패턴으로 AOP가 동작한다. 프록시 패턴은 객체 사용 시, 객체에 직접 접근하지 않고 해당 객체를 대리하는 프록시 객체를 통해 해당 객체에 접근하는 패턴이다.
AspectJ와 스프링 AOP 비교표
왜 프록시 패턴을 사용할까?
스프링에서 객체를 직접 접근하지 않고, 프록시 객체에 접근하는 이유는 무엇일까?
이유는 해당 객체에 대한 접근 제어나 부가 기능을 추가하고 싶을때 사용한다.
JDK Proxy와 CGLib Proxy
스프링에서는 자동으로 프록시 객체를 생성해주는데, 이에 두 가지 방식이 있다. 타겟의 어떤 부분을 상속받아 구현하느냐의 차이를 둔다.
JDK는 타겟의 상위 인터페이스를 상속 받아 프록시를 만든다. 인터페이스를 구현한 클래스가 아니면 의존할 수 가 없다. 타겟이 다른 구현 클래스에 의존한다면 런타임 에러가 발생할 수 있다.
CGLib은 타겟 클래스를 상속 받아 프록시를 만든다. 인터페이스 구현이 필요 없고, 스프링 부트부턴 기본 방식으로 사용되고 있다.
@Transactional 또한 AOP의 한 종류이다.
- target에 호출이 오면 AOP Proxy가 가져온다.
- AOP Proxy의 Transaction Advisor가 적절한 처리를 수행한다.
- Custom Advisor에서 추가 기능을 수행한다.
- 처리가 끝나면 Target 메서드를 실행한다.
- 클라이언트에게 결과를 전달한다.
JDBC 트랜잭션
@Transactional에 대한 이해를 위해선 JDBC 트랜잭션에 대한 이해가 필요하다.
- datasource로부터 연결을 수행한다.
- true 설정하면 자동 커밋 또는 롤백을 수행한다.
- commit을 통해 DB에 쿼리를 수행한다.
- 예외가 발생하면 롤백을 수행한다.
import java.sql.Connection;
Connection connection = dataSource.getConnection(); // (1)
try (connection) {
connection.setAutoCommit(false); // (2)
// execute some SQL statements...
connection.commit(); // (3)
} catch (SQLException e) {
connection.rollback(); // (4)
}
스프링에서 Transaction을 수행하는 방법
스프링에서 제공하는 Ioc Container로 CGLIB 라이브러리를 통해 해당 메서드와 메서드의 트랜잭션 또한 인스턴스화한다.
트랜잭션 매니저는 프록시 객체를 통해 트랜잭션을 연결하고 닫는 과정을 거친다. 매니저는 JDBC 방식으로 코드를 개발자 대신 수행해준다.
결론
AOP는 본래 로직에 집중하기 위해 부가 기능의 관점을 분리한 것이다. 트랜잭션 과정 또한 AOP의 일부분으로서 타겟 객체와 타겟 객체의 프록시 객체까지 인스턴스화하여 수행한다. JPA의 트랜잭션의 코어 과정은 JDBC 트랜잭션을 따라 수행한다. AOP가 이 과정을 대신 수행해준다.
추가로 공부해볼 내용
@Transactional Propagtion Level
@Transactional Isolation Level
JpaTransactionManager, HibernateTransactionManager
'스프링 부트 > JPA' 카테고리의 다른 글
[스프링] Hibernate란 (0) | 2022.10.08 |
---|---|
[스프링] DATA JPA In절로 파라미터 넣기 (0) | 2022.08.25 |
[스프링] @Query에 ENUM 타입 쓰는 법 (0) | 2022.08.25 |
@NotNull, @NotEmpty, @NotBlank 차이 (0) | 2022.02.19 |
스프링 부분 수정 쿼리 @DynamicUpdate (1) | 2022.02.18 |
댓글