AOP 웹공학
태그 :
- 개념
- -핵심 관심사(Core Concerns)에 대한 관점과 횡단 관심사(Cross-cutting Concerns)에 대한 관점들로 프로그램을 분해해 Weaving 을 통해 프로그램을 구현하는 기법.
1. OOP를 OOP답게 사용하는 새로운 패러다임 AOP의 개요
가. 관점지향 프로그래밍(AOP: Aspect Oriented Programming)의 정의
-핵심 관심사(Core Concerns)에 대한 관점과 횡단 관심사(Cross-cutting Concerns)에 대한 관점들로 프로그램을 분해해 Weaving 을 통해 프로그램을 구현하는 기법.
나. AOP의 특징
구분 |
내용 |
모듈화 |
- 횡단 관심사를 포괄적이고 체계적으로 모듈화 |
캡슐화 |
- 횡단 관심사는 Aspect라는 새로운 단위로 캡슐화하여 모듈화가 이루어짐 |
단순화 |
- 핵심 모듈은 더 이상 횡단 관심사의 모듈을 직접 포함하지 않으며 횡단 관심사의 모든 복잡성은 Aspect로 분리 |
2. AOP의 구성도 와 구성요소
가. AOP의 구성도
나. AOP의 구성요소
구성요소 |
내용 |
핵심관심 |
- 시스템의 핵심 가치와 목적이 그대로 드러난 관심 영역 |
횡단관심 |
- 쉽게 분리된 모듈로 작성하기 힘든 요구사항, 공토모듈 |
Joint Point |
- 횡단 관심의 기능이 삽입되어 실행될 수 있는 특정 위치 |
Point-Cut |
- 어느 Joint Point를 사용할 것인지를 결정하는 선택 기능 |
Advice |
- Joint Point에 삽입되어 동작되는 모듈 |
Aspect |
- Point-cut 과 Advice를 합쳐 놓은 코드 |
Weaving |
- Joint Point 에 해당하는 Advice를 삽입하는 과정 |
3. AOP의 실행절차도 및 절차
가. AOP의 실행절차도
나. AOP의 절차
순서 |
내용 |
1 |
- 클라이언트는 직접 타겟 객체를 참조하지 않고 프락시를 통해서 호출 |
2 |
- 프락시는 클라이언트의 호출을 받으면 3번 처럼 Aspect 모듈을 호출 |
3 |
- Cross Concerns에서는 타겟 객체의 메소드를 호출전에 advice의 내용을 수행 |
4 |
- 타겟 객체의 전에 Aspect 모듈을 호출해서 마무리 작업을 할 수 있고 그 후 최종적으로 클라이언트에 반환값을 넘겨준다 |
4. AOP와 OOP의 비교
가. AOP와 OOP의 일반비교
구분 |
AOP |
OOP |
소스 코드 구성 |
- 핵심관심과 횡단관심의 분리 |
- 핵심관심과 횡단관심이 산재함 |
목적 |
- 부문별 조립으로 생산성 제고 |
- 상속 및 재사용 통한 효율 제고 |
관심사 |
- 공통로직 |
- 업무로직 |
장점 |
- 환경 독립성, 횡단관심 공통 적용 |
- 객체 재사용 |
단점 |
- 구현과 이해에 시간이 소요 |
- 객체별 독립성 유지 어려움 |
나. AOP와 OOP의 소스비교
-계정 관리를 기능의 AccountManager 인터페이스가 있고 요구사항은 AccountManager 내에서 Exception이 발생할 때마다 담당자에게 메일을 발송하는 것.
구분 |
Source |
Description |
OOP |
import org.springframework.dao.DataAccessException; public interface AccountManager { public Account getAccount(String accountId) throws AccountNotFoundException, DataAccessException;
public void createAccount(Account account) throws DataAccessException; } |
인터페이스 |
public class AccountManagerImpl implements AccountManager { private MailSender mailSender; private SimpleMailMessage message; private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } public void setMailSender(MailSender mailSender) { this.mailSender = mailSender; } public void setMessage(SimpleMailMessage message) { this.message = message; } private void sendMail(Exception ex) { SimpleMailMessage msg = new SimpleMailMessage(this.message); msg.setText("Encountered exception " + ex.getMessage()); this.mailSender.send(msg); } public Account getAccount(String accountId) throws AccountNotFoundException, DataAccessException { try { return this.accountDao.findAccount(accountId); } catch( AccountNotFoundException ex) { sendMail(ex); throw ex; } catch (DataAccessException ex) { sendMail(ex); throw ex; } }
public void createAccount(Account account) throws DataAccessException { try { if( isInvalid(account)) { throw new InvalidAccountException(account); } this.accountDao.saveAccount(account); } catch (IOException ex) { sendMail(ex); throw ex; } catch (DataAccessException ex) { sendMail(ex); throw ex; } } } |
- AccountManagerImpl 클래스를 보면 Exception이 발생할 때마다 Mail을 보내는 코드가 추가
- try/catch block과 메일을 보내기 위한 중복코드가 발생 |
|
AOP |
public class EmailNotificationThrowsAdvice implements ThrowsAdvice { private MailSender mailSender; private SimpleMailMessage message;
public void setMailSender(MailSender mailSender) { this.mailSender = mailSender; }
public void setMessage(SimpleMailMessage message) { this.message = message; } public void afterThrow(Excepton ex) throws Throwable { SimpleMailMessage msg = new SimpleMailMessage(this.message); msg.setText ("Encountered exception " + ex.getMessage()); this.mailSender.send(msg); } } |
- Exception이 발생했을 때 메일을 보내는 작업을 실행하는 하나의 Advice |
<bean id="emailNotificationThrowsAdvice" class="com.mycompany.EmailNotificationThrowsAdvice"> <property name="mailSender"> <ref bean="mailSender"/></property> <property name="message"><ref bean="mailMessage"/> </property> </bean>
<bean id="accountManagerBeanNameProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="beanNames"> <value>accountManagerTarget</value> </property> <property name="interceptorNames"> <list> <value>emailNotificationThrowsAdvice</value> </list> </property> </bean> |
- 생성된 Advice는 Spring AOP config 정의
- EmailNotificationThrowsAdvice를 accountManagerTarget의 메써드가 호출될 때 적용 |
|
|
public class AccountManagerImpl implements AccountManager { private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; }
public Account getAccount(String accountId) throws AccountNotFoundException, DataAccessException { return this.accountDao.findAccount(accountId); }
public void createAccount(Account account) throws DataAccessException { this.accountDao.saveAccount(account); } } |
- Spring AOP를 적용 후의 AccoungManagerImpl 클래스로서 단지 계정 관리를 위한 비지니스 로직만 있음 |