kok202
스프링 AOP, Transaction

2019. 4. 21. 21:42[정리] 기능별 개념 정리/스프링 부트

AOP를 구현하는 방법

방법 1. AspectJ 의 컴파일러 이용하기
MyClass.java -> (AOP) -> MyClass.class
MyClass.class 는 원하는 코드가 주입되서 변형된 파일이다.

 

방법 2. AspectJ 의 바이트 코드를 조작 할 수 있는 class loader 사용하기
MyClass.java -> MyClass.class
MyClass.class -> (클래스로더) -> Memory
MyClass.class를 메모리에 올려서 실행할때 자바 클래스 로더가 사용될 것이다. 
이때 AspectJ 를 이용하면 MyClass.class에 바이트코드를 조작해서 원하는 코드를 주입하고 메모리에 올릴수있다.

 

방법 3. 프록시 패턴 이용하기

 

 

 

 

 

@Transactional은 스프링 AOP를 이용해서 만든 대표적인 Annotation 이다.

@Transactional(readOnly=true) : 프록시 패턴에의해 실행되는 SQL 문 앞뒤에 SQL문이 추가된다. 

아래는 @Transactional 을 사용하지 않았을 경우 low level에서 트랜잭션을 구현하는 예시다.

String insertTableSQL = "INSERT INTO DBUSER (USER_ID, USERNAME, CREATED_BY, CREATED_DATE) VALUES (?,?,?,?)";
String updateTableSQL = "UPDATE DBUSER SET USERNAME =? WHERE USER_ID = ?";

Connection dbConnection = null;
PreparedStatement preparedStatementInsert = null;
PreparedStatement preparedStatementUpdate = null;
try {
	dbConnection = getDBConnection();
	dbConnection.setAutoCommit(false);

	preparedStatementInsert = dbConnection.prepareStatement(insertTableSQL);
	preparedStatementInsert.setInt(1, 999);
	preparedStatementInsert.setString(2, "mkyong101");
	preparedStatementInsert.setString(3, "system");
	preparedStatementInsert.setTimestamp(4, getCurrentTimeStamp());
	preparedStatementInsert.executeUpdate();

	preparedStatementUpdate = dbConnection.prepareStatement(updateTableSQL);
	preparedStatementUpdate.setString(1, "new string");
	preparedStatementUpdate.setInt(2, 999);
	preparedStatementUpdate.executeUpdate();

	dbConnection.commit();
} catch (SQLException e) {
	dbConnection.rollback();
} finally {
	if (preparedStatementInsert != null)
		preparedStatementInsert.close();
	if (preparedStatementUpdate != null)
		preparedStatementUpdate.close();
	if (dbConnection != null) 
		dbConnection.close();
}

1. dbConnection.setAutoCommit(false);

2. 수행하려는 쿼리들을 실행

3. SQL Exception 이 발생할 경우 dbConnection.rollback();

4. 무사히 완료될 경우 dbConnection.commit();

코드 출처 : https://www.mkyong.com/jdbc/jdbc-transaction-example/

 

 

 

 

@AOP 사용하기

커스텀 Annotation MyPrintAnnotation.java 구현

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyPrintAnnotation{
    
}

커스텀 Annotation MyPrintAnnotation 이 적용된 곳에 어떤 일을 하겠다고 명시

@Aspect
@Component
public class MyAspect{
    @Around("@annotation(MyPrintAnnotation)")
    public Object myPrintAnnotation(ProceedingJoinPoint joinPoint) throws Throwable{
        System.out.println("before method");
        Object proceed = joinPoint.proceed();
        System.out.println("after method");
        return proceed;
    }
}

커스텀 Annotation MyPrintAnnotation 을 메소드에 사용

...
@MyPrintAnnotation
public void myMethod(){
    System.out.println("myMethod was called");
}
...

 

좋은 문서 : http://www.egovframe.go.kr/wiki/doku.php?id=egovframework:rte:fdl:aop:aspectj

 

egovframework:rte:fdl:aop:aspectj [eGovFrame]

@AspectJ는 Java 5 어노테이션을 사용한 일반 Java 클래스로 관점(Aspect)를 정의하는 방식이다. @AspectJ 방식은 AspectJ 5 버전에서 소개되었으며, Spring은 2.0 버전부터 AspectJ 5 어노테이션을 지원한다. Spring AOP 실행환경은 AspectJ 컴파일러나 직조기(Weaver)에 대한 의존성이 없이 @AspectJ 어노테이션을 지원한다. @AspectJ를 사용하기 위해서 다음 코드를 Spring 설정에 추가

www.egovframe.go.kr

 

 

 

 

'[정리] 기능별 개념 정리 > 스프링 부트' 카테고리의 다른 글

PSA (추상화 계층)  (0) 2019.05.01
스프링 부트의 Mock  (0) 2019.04.28
Spring boot's NoSQL  (0) 2019.04.21
Spring boot's RestTemplate, WebClient  (0) 2019.04.21
Bean Singleton or Prototype  (0) 2019.04.18