Spring/Spring AOP

다이나믹 프록시 (3)

레알윙 2020. 2. 26. 23:16
반응형

다이내믹 프록시를 이용한 트랜잭션 부가기능

public class TransactionHandler implements InvocationHandler {
    private Object target; // 부가기능을 제공할 타깃오브젝트, 어떤타입의 오브젝트에도 적용가능
    private PlatformTransactionManager transactionManager; //트랜잭션 기능을 제공하는데 필요한 트랜잭션 매니저
    private String pattern;//트랜잭션을 적용할 메소드 이름 패턴
    
    public void setTarget(Object target) {
        this.target = target;
    }
    
	public void setTransactionManager(PlatformTransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }
    
    public void setPattern(String pattern) {
        this.pattern = pattern;
    }
    
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    	//시작
        if (method.getName().startsWith(pattern)) {
            return invokeInTransaction(method, args);
        } else {
            return method.invoke(target, args);
        }
        //끝
        //-> 트랜잭션 적용대상 메소드를 선별해서 트랜잭션 경계설정 기능을 부여 
    }
    
    private Object invokeTransaction(Method method, Object[] args) throws Throwable {
        TransactionStatus = this.transactionManager.getTransaction(new DefaultTransactionDefinition());
        try {
            Object ret = method.invoke(target, args);
            this.transactionManager.commit(status);
            return ret;
        } catch (InvocationTargetException e) {
            this.transactionManager.rollback(status);
            throw e.getTargetException();
        }
    }
}

INvocationHandler의ㅏ invoke() 메소드를 구현하는 방법은 UppercaseHandler에 적용했던 것과 동일하다. 타깃 오브젝트의 모든 메소드에 트랜잭션을 적용`1하는게 아니라 선별적으로 적용할 것이므로 적용할 대상을 선별하는 작업을 먼저 진행한다.

 

트랜잭션이 필요한 클래스와 메소드가 증가하면 UserServiceTx처럼 프록시 클래스를 일일이 구현하는 것은 큰 부담이기 때문에 트랜잭션 부가기능을 제공하는 다이내믹 프록시를 만들어 방법이 효율적이다.

 

 

TranscationHandler와 다이내믹 프록시를 이용하는 테스트

@Test
public void upgradeAllOrNothing() throws Exception {
    ...
    TransactionHandler txHandler = new TransactionHandler();
    //시작
    txHandler.setTarget(testUserService);
    txHandler.setTransactionManager(transactionManager);
    txHandler.setPattern("upgradeLevels");
    //끝
    //-> 트랜잭션 핸들러가 필요한 정보아 오브젝트를 ID 해줌
    
    
    UserService txUSerService = (UserService)Proxy.newProxyInstance(
    			getClass().getClassLoader(), new Class[] {UserService.class }, txHandler);
    //-> UserSErvice 인터페이스 타입의 다이내믹 프록시 생성
    ...
}

UserSErviceTx 오브젝트 대신 TransactionHandler를 만들고 타깃 오브젝트와 트랜잭션 매니저, 메소드 패턴을 주입을 하면 다이내믹 프록시를 이용한 트랜잭션 프록시가 적용이 되었다.

 

 

 

 

 

 

 

팀회식 때문에 아웃백을 가서 5명이서 34만원을 먹다니.. 좀 과식한거같다.

 

어제도 빈 글만 올리고 하라는 공부를 안하고... 유튜브만 봤는데.. 오늘까지 안하면 나와의 약속은 깨는거같아서..

 

30분이라도 공부를 했다..

 

역시 쉬는 공간, 일하는 공간, 공부하는 공간이 분리되야지 나는 잘되는거같다.

 

쉬는 공간에서 공부하는 시간을 조금씩 늘려야겠다..

반응형