본문 바로가기

Programming/SpringFramework

Spring AOP

처음에 AOP라는 기능을 보았을 때 놀랐다. 개발하는 방향에 있어서 좋은 기능이라는 것 !

나름 쉽게 적어 놓았는데 어떨지 모르겠다. 


AOP 란

- 비즈니스 로직에 영향을 주지 않고 사이사이에 공통 모듈을 효과적으로 잘 끼워 넣도록 하는 개발방법이다.

- 관점을 옆으로(?) 주고 공통 모듈을 끼워 넣도록 하는 개발 방법이다.


AOP 주요 구성요소

1. JoinPoint

- 모듈이 삽입되어 실행될 수 있는 특정 위치

- 제어 흐름중의 한 시점

2. PointCut

- 어떤 클래스의 어느 조인포인트를 사용할 지 선택하는 기능

3. Advice 

- JointPoint에 삽입되어 동작할 수 있는 코드

- 동작시점

  before : Matching 된 JoinPoint 이전에 동작하는 Advice 

  after returning : Matching 된 JoinPoint 이전에 동작하는 Advice

  after throwing : Matching 된 JoinPoint Exception이 발생하여 종료된 후 동작하는 Advice

  after : Matching 된 JoinPoint가 종료된후 동작하는 Advice

  around : Matcing 된 JointPoint가 종료된 후 동작하는 Advice

4. Weaving 

 - Core Concerns 모듈에 Crosscutting Concerns 모듈 엮어서 동작수행

5. Aspect

 - 어디에서 무엇을 할 것인지를 합쳐놓은것을 말함    


예제)

 - 인터셉터와 AOP를 이용한 Request 바인딩 코드

 
@Aspect
public class BindingAspect extends HandlerInterceptorAdapter {
	protected Log log = LogFactory.getLog(BindingAspect.class);
	static HttpServletRequest request;
	
	@Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        this.request = request;
        System.out.println(request);
        return super.preHandle(request, response, handler);
    }
	
		
	@Before("execution(* com.highluck.Service.*Service.*(..))")
	public void binding(JoinPoint joinPoint) throws Throwable{
		Object target = joinPoint.getTarget(); 		
		//HttpServletRequest requests =  (HttpServletRequest)joinPoint.getArgs();
	    Field[] arrField = target.getClass().getFields();
	    if(request.getParameterNames() != null){
	     
		 		for (int i = 0; i < arrField.length; i++) {
        			Field field = arrField[i];
        			System.out.println(field.getType()+ " == " +int.class);
				try {						
					if(field.getType() == int.class){
						System.out.println("asdasd :" +request.getParameter(field.getName()));
						field.set(joinPoint.getThis(), Integer.parseInt(request.getParameter(field.getName()))); 
					} else if(field.getType() == double.class){
						field.set(Target.class, Double.parseDouble(request.getParameter(field.getName())));
					} else{
						field.set(Target.class, request.getParameter(field.getName()));
					}
					log.debug(field);
					
				} catch (IllegalArgumentException | IllegalAccessException e) {
					e.printStackTrace();
				} catch (NullPointerException e) {
					continue;
				}
        	}	  
		}
		 request = null;
	 }
}



앞전에 리플렉션을 이용해서 만든 바인딩 코드를 AOP를 이용해서 만들었다.


여기서 사용 되었던 포인트컷 지시자에 대한 설명을 퍼온 내용이다.

AspectJ에서는 다섯 가지 종류의 Advice를 이용할 수 있는데 각각 @Before, @AfterReturning, @AfterThrowing, @After, @Around 어노테이션으로 표현된다.
이 코드는 @Around로 시작하기 때문에, Around Advice임을 알수 있다.

그 다음으로 "execution"은 포인트컷 표현식 부분이다. 
포인트컷 표현식은 위에서 사용된 execution()을 포함하여 여러가지 포인트컷 지시자(PointCut Designator)를 사용할 수 있다. 
그 종류는 다음과 같다.
execution() : 가장 대표적이고 강력한 지시자로, 접근제어자, 리턴 타입, 타입 패턴, 메서드, 파라미터 타입, 예외 타입 등을 조합해서 메서드까지 선택가능한 가장 정교한 포인트컷을 만들수 있다.
within() : 타입 패턴만을 이용하여 조인포인트를 정의한다.
this : 빈 오브텍트의 타입의 조인토인트를 정의한다.
target : 대상객체의 타입 비교를 이용한 조인포인트를 정의한다.
args : 메서드의 파라미터 타입만을 이용하여 조인포인트를 정의한다.
@target : 특정 어노테이션이 정의된 객체를 찾는 조인포인트를 정의한다.
@args : 특정 어노테이션을 파라미터로 받는 오브젝트를 찾는 조인포인트를 정의한다. 
@within : @target과 유사하게 특정 어노테이션이 정의된 객체를 찾는데, 선택될 조인포인트 메서드는 타겟 클래스에서 선언이 되어있어야 한다.
@annotation : 조인 포인트 메서드에 특정 어노테이션을 찾는 조인포인트를 정의한다.
참고 : http://addio3305.tistory.com/32


'Programming > SpringFramework' 카테고리의 다른 글

나의 프레임워크 설계 ref 스프링 - 0 -  (0) 2016.04.29
bean scope 명시  (0) 2016.04.24
HTTP 에러정리  (0) 2016.04.09
Spring DI & IOC  (0) 2016.04.01
Reflect API - 나만의 라이브러리 만들기 -  (0) 2016.02.10