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
'[정리] 기능별 개념 정리 > 스프링 부트' 카테고리의 다른 글
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 |