데브코스 W5D5

코끼릭·2022년 4월 18일
0

TIL

목록 보기
19/36

AoP(Aspect Orient Programming)

관점 지향 프로그래밍이라는 뜻으로 계층 안에서가 아닌 계층마다 가지고 있는 공통 관심사의 분리를 허용함으로써 모듈성을 증가시키는 것이 목적인 프로그래밍 패러다임이다. 특히 로깅이나 트랙잭션 관리, 보안과 같이 특정 계층 내에서만 실행되지 않고 반복되어 수행되는 관심사를 추상화시켜서 분리시키면 개발자는 핵심 비즈니스 로직에 집중할 수 있게 하는 장점을 가지고 있다.

//1. 타겟(실제 비지니스 로직을 담당하는 메소드)
public class A {  
	public void m(){
    	System.out.println("actual business logic");
    }  
}  

//2. 어드바이서(단일 메소드 인터페이스 구현체)
public class BeforeAdvisor implements MethodBeforeAdvice{  
    @Override  
    public void before(Method method, Object[] args, Object target)throws Throwable {  
        System.out.println("additional concern before actual logic");  
    }  
}  

//3. 프록시 팩토리
public class ProxyFactory {  
  private Object target; //타겟인 클래스 A에 의존하는 팩토리  
  private List interceptorNames;  
}  

public class Test {  
  public static void main(String[] args) {  
      ApplicationContext appConext r= new ApplicationContext(AppConfig.class);  
      
      A a = appContext.getBean("proxyFactory", A.class);  
      //타겟 메소드 호출 전/후로 프록시가 어드바이서 명령 수행 
      a.m();  
  }  
}  

>> result
additional concern before actual logic
actual business logic

+ Proxy

동작 수행에 대한 지시를 대신 수행해주는 객체를 의미해서 사용자가 직접 동작에 대한 지시가 어려운 경우 주로 사용된다. 스프링의 AoP에서는 클라이언트와 타깃 사이에 투명하게 존재해서 타깃의 메소드 전후로 부가기능을 제공하기 위해 프록시 구조를 활용하고 있다.

@AspectJ

Spring에서 제공되는 아노테이션 기반 서비스로 횡단 관심사를 가진 모듈에 아노테이션을 붙여 사용하면 자동으로 AoP 환경을 구축해주는 것이 특징이다.

Target
핵심 기능을 담고 있는 모듈로서 부가기능을 부여할 대상

Join Point
어드바이스가 적용될 수 있는 위치
타겟 객체가 구현한 인터페이스의 모든 메서드

Aspect
애스펙트 = 어드바이스 + 포인트컷
Spring에서는 Aspect를 빈으로 사용

Pointcut
어드바이스를 적용할 타겟의 메서드를 선별하는 정규표현식이다. 포인트컷 표현식은 execution으로 시작하고 메서드의 Signature를 비교하는 방법을 주로 이용한다.

execution([접근제어자] 반환타입 패키지명.클래스명(매개변수타입))

App클래스의 public 메소드 String을 반환하는 것에만 주입
>> execution(public String com.spring.App.*(..))

App클래스의 모든 메소드 중 첫번째 매개변수가 long인 것에만 중비
>> execution(* com.spring.App.*(long, ..))

어드바이스(Advice)
타겟의 특정 조인 포인트에 제공할 부가기능(@Before, @After, @Around, @AfterReturning, @AfterThrowing)

Spring AoP를 사용한 예시

@Aspect
@Component
public class LoggingAspect {
	private static final Logger log = LoggerFactory.getLogger(LoggingAspect.class);
    
    @Pointcut(execution(public String com.spring.App.*(..))")
    public void servicePointcut() {
    
    };
    
   	@Around("servicePointcut()")
    public Object log(ProceedingJoinPoint joinPoint) {
    	log.info("Before Method");
        var result = joinPoint.proceed();
        log.info("After Method");
    }
}

@Transactional

트랜잭션 관리를 지원해주는 것으로 원자성을 가진 트랙잭션 작업이 실패할 경우 롤백을 해주고 개발자는 롤백의 과정을 고려하지 않고 비즈니스 로직만 작성하게 되면 스프링의 AoP를 통해 내가 작성한 비즈니스 로직을 프록시처럼 사용하여 트랙잭션 관리를 지원하는 기능을 제공하고 있다.

@ComponentScan
@Configuration
public class Config {
	@Bean
    public DataSource dataSource() {
    	return new DataSource();
    }
    
    @Bean
    public PlatformTransactionManager platformTransactionManager(DataSource dataSource) {
    	return DatasourceTransactionManager(dataSource);
    }
    
    @Bean
    public TransactionTemplate transactionTemplate(PlatformTransactionManager platformTransactionManager) {
    	return new TransactionTemplate(platformTransactionManager);
    }
}
....

@Component
public class TransactionTest {
	@Autowired
    private TransactionTemplate transactionTemplate;
    
    public void method() {
    	//템플릿 콜백을 사용한 트랙잭션 콜백 관리
        //단일 메소드 인터페이스를 익명 클래스로 전달
        transactionTemplate.execute(
        	@Override
            protected void doInTransactionWithoutResult(Transaction status) {
            	//하나의 트랙잭션으로 정의할 sql문 
            }
        );
    }
}

Transaction Propagation

@Transactional이 있는 메서드를 하나의 트랜잭션 안에서 진행하는 역할을 수행하는 중 내부에 호출되는 트랜잭션 표기가 되어있는 메서드가 있을 때 스프링에서 처리할 수 있는 전략을 개발자가 지정할 수 있는데 이걸 트랜잭션의 전파 설정이라고 한다. 전파 설정 옵션은 크게 다음과 같다.

REQUIRED (default)
부모 트랜잭션이 존재하는 경우 부모 트랙잭션으로 합류하고 부모의 트랜잭션이 존재하지 않는 경우 새로운 트랜잭션을 생성해서 하나의 트랜잭션으로 롤백이 적용된다.

REQUIRES_NEW
무조건 트랜잭션을 새로 생성하는 경우로 각각의 트랜잭션이 있는 경우여도 서로 영향을 주지 않는다.

MANDATORY
부모 트랜잭션에 합류하는 것으로 부모 트랜잭션이 없으면 예외를 발생시키는 옵션이다.

NESTED
트랜잭션을 새로 생성하는 경우로 부모 트랜잭션이 존재하는 경우 내부 트랜잭션에서 롤백이 발생하는 것은 부모 트랜잭션에서 영향을 주지 않지만 부모 트랜잭션에서 롤백이 발생하면 자신의 트랜잭션에서도 롤백이 일어난다.

NEVER
트랜잭션을 생성하지 않고 부모 트랜잭션이 있는 경우에는 예외를 발생시킨다.

SUPPORTS
부모 트랜잭션이 있는 경우 합류시키고 없으면 따로 트랜잭션을 생성하지 않는다.

NOT SUPPORTS
부모 트랜잭션이 있다면 보류 시키고 없으면 따로 트랜잭션을 생성하지 않는다.

Transaction Isolation

각 트랜잭션 간의 일관성 있는 데이터를 얼마나 허용할 것인지 정해놓은 수준을 트랜잭션 고립 수준이라고 해서 다른 트랜잭션이 자신의 트랜잭션에서 일어나는 데이터 변화를 어느 정도까지 조회가 가능한지를 결정해 놓은 것이다.

Dirty reads
어떤 트랜잭션에서 아직 실행이 끝나지 않은 트랜잭션에 의한 변경사항을 보게 되는 경우

Non-repeatable reads
어떤 트랜잭션이 같은 쿼리를 2번 실행하는 데 그 사이에 다른 트랜잭션이 수정이나 삭제를 하는 경우

Phantom reads
어떤 트랜잭션이 같은 쿼리를 2번 하는데 그 사이에 없던 레코드가 추가된 경우


AoP
트랜잭션 전파
트랜잭션 고립 수준

profile
ㅇㅅㅇ

0개의 댓글