! AOP 기능을 사용하기위해서는 AspectJweaver를 의존객체로 추가해야한다.


AOP

- 여러 객체에 공통으로 적용할 수 있는 기능을 구분함으로써 재사용성을 높여주는 프로그래밍 기법.

- 핵심기능을 구현하지않는 대신 여러 객체에 공통으로 적용될 수 있는 기능을 구현한다. => 여러 객체에서 사용될 수 있는 기능을 구현한다.

- 공통 기능을 Aspect라고 부른다.


AOP의 장점

- 기존 코드를 변경하지않고 원하는 작업을 추가할 수 있다.

- 일부 중복되는 작업을 별도로 분리하여 사용할 수 있기에 중복되는 코드를 줄일 수 있다.


기본 개념
- 핵심 기능에 공통 기능을 삽입하는 것.

삽입 방법
1) 컴파일 시점에 공통 기능 추가
- 컴파일 하기 전 공통 구현 코드를 소스에 삽입하는 방식으로 동작.
2) 클래스 로딩 시점에 공통 기능 추가
- 클래스를 로딩할 때 바이트 코드에 공통 기능을 클래스에 삽입하는 방식으로 동작
3) 런타임때 프록시 객체를 생성해서 공통 기능 추가
- 스프링이 제공하는 방식으로 중간에 프록시 객체를 생성하고 그 프록시 객체를 사용하여 작업을 수행한다.
- 타겟 기능 실행 전.후에 공통 기능을 삽입할 수 있다.

AOP 설정할 때 사용되는 용어들은 다음과 같다.
1) JoinPoint - Advice를 적용할 수 있는 지점을 의미하는 것으로 메소드 호출, 필드 값 변경 등이 해당된다.
2) Pointcut - JoinPoint의 부분집합, 실제로 Advice가 적용되는 JoinPoint를 의미한다. 정규표현식이나 AspectJ 문법을 사용하여 정의할 수 있다.
3) Advice - 적용 시기를 나타낸다.(핵심기능 실행 전 혹은 실행 후 등)
4) Weaving - Advice를 핵심로직코드에 적용하는 것을 의미한다.
5) Aspect - 공통 기능을 의미한다.

Advice의 종류
1) before : 공통 기능을 핵심기능 실행 전에 실행하게 한다.
2) after : 공통 기능을 핵심기능 실행 후에 실행하게 한다.
3) after-returning
4) after-throwing
5) around

스프링 AOP 구현
1) 공통 기능을 제공하는 Aspect 구현 클래스를 만든다.
2) 1에서 만든 클래스를 어디에 적용할 것인지 설정한다.(JoinPoint 설정)

방법
1) POJO 클래스 사용
- XML 파일에 공통기능을 제공할 클래스를 빈으로 등록해둔다.
- Aspect설정을 통해 어떤 pointcut에 적용할 지를 설정한다.

[Java]
class AspectClass {

public void print() {
System.out.println("print");
}
}

[xml]
<beans xmlns=" ..... "
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation=" .....
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="aspectClass" class="spring.AspectClass" /> // 공통 기능을 제공할 클래스를 빈으로 등록

<aop:config>
<aop:aspect id="aspect" ref="aspectClass">
<aop:pointcut id="method" expression="execution(...) "/> // execution 안에 적용할 대상을 입력한다. (정규식 or AspectJ 문법)
<aop:around pointcut-ref="method" method="print"/> // Advice를 적용한다. around 대신 after,before 등의 다른 것을 사용할 수 있다.
</aop:aspect>
</aop:config>

<bean id="a" class="spring.A" />
...

</beans>

2) @Aspect 어노테이션 사용
- 자바 소스 파일에 어노테이션으로 붙여서 활용한다.
- XML 파일에서 자동으로 프록시객체를 생성할 수 있도록 <aop:aspectj-autoproxy /> 태그를 입력해야한다.
- 혹은 설정클래스 앞에 @EnableAspectJAutoProxy 어노테이션을 부착한다.
[java]
@Configration
@EnableAspectJAutoProxy
class ConfigClass {
...
}

@Aspect
class AspectClass {
@Pointcut("execution(...)")
public void prePrint() {
System.out.println("----------");
}

@Before("prePrint()")
public void print() {
System.out.println("print()");
}
}

[xml]
<beans ...>
<aop:aspectj-autoproxy /> // 설정클래스에 @EnableAspectJAutoProxy 어노테이션을 적용했다면 굳이 입력하지 않아도 된다.
</beans>


Aspect가 여러개있을 때, 우선순위를 지정할 수 있다. 

지정하는 방법은 XML 파일에 설정하는 방법과 어노테이션을 적용하는 방법이 있다.

1) XML 파일에서 <aop:aspect> 태그 내에 order 속성을 사용한다.

2) 자바 소스코드에서 @Order 어노테이션을 적용한다.

[java]
@Aspect
@Order("1")
class AspectClass1 { ... }

@Aspect
@Order("0")
class AspectClass2 { ... }

[xml]
<beans xmlns=" ..... "
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation=" .....
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="aspectClass1" class="spring.AspectClass1" /> // 공통 기능을 제공할 클래스를 빈으로 등록
<bean id="aspectClass2" class="spring.AspectClass2" /> // 공통 기능을 제공할 클래스를 빈으로 등록

<aop:config>
<aop:aspect id="aspect" ref="aspectClass1" order="1">
<aop:pointcut id="method" expression="execution(...) "/> // execution 안에 적용할 대상을 입력한다. (정규식 or AspectJ 문법)
<aop:around pointcut-ref="method" method="print"/> // Advice를 적용한다. around 대신 after,before 등의 다른 것을 사용할 수 있다.
</aop:aspect>
</aop:config>

<aop:config>
<aop:aspect id="aspect" ref="aspectClass2" order="0">
<aop:pointcut id="method" expression="execution(...) "/> // execution 안에 적용할 대상을 입력한다. (정규식 or AspectJ 문법)
<aop:around pointcut-ref="method" method="print"/> // Advice를 적용한다. around 대신 after,before 등의 다른 것을 사용할 수 있다.
</aop:aspect>
</aop:config>

<bean id="a" class="spring.A" />
...

</beans>




AOP는 일종의 인터셉터라고 볼 수 있다. 

필터와 인터셉터의 차이는 적용시점의 차이다.

필터의 적용시점은 서블릿 실행 전/후(Dispatcher Servlet 진입 전/ 해당 서블릿 작업 종료 후)이고

인터셉터의 적용시점은 대상 메소드 실행 전/후(Dispatcher Servlet 진입 후 특정 메소드 실행하기 전/후)이다.

'학습 > WEB' 카테고리의 다른 글

JSP  (0) 2018.12.17
Spring) MVC  (0) 2018.10.28
spring) 객체 생성 - Java code  (0) 2018.10.24
spring) 의존 자동주입  (0) 2018.10.20
Spring) 2개 이상의 설정파일 활용  (0) 2018.10.19
Posted by Roktar