● 설정파일기반 AOP 설정.
- XML 스키마 확장기법을 통해 설정파일을 작성한다.
● AOP 설정 태그
1. <aop:config> : aop설정의 root 태그, Aspect 설정들의 묶음
2. <aop:aspect> : Aspect 설정 - 하나의 Aspect 설정
Aspect가 여러 개일 경우 <aop:aspect> 태그가 여러 개 온다.
3. <aop:pointcut> : Advice에서 참조할 pointcut 설정
4. Advice 설정태그들
A. <aop:before> - 메소드 실행 전 실행될 Advice
B. <aop:after-returning> - 메소드 정상 실행 후 실행될 Advice
C. <aop:after-throwing> - 메소드에서 예외 발생시 실행될 Advice
D. <aop:after> - 메소드 정상 또는 예외 발생 간관없이 실행될 Advice - finally
E. <aop:around> - 모든 시점에서 적용시킬 수 있는 Advice 구현
★ 예제
핵심관심사항에 대한 정의만 갖고 있는 Person 인터페이스
핵심관심사항에 대해 게임을 하도록 구현된 Boy 클래스
핵심관심사항에 대해 화장을 지우도록 구현된 Girl 클래스
공통관심사항을 구현할 MyAspect클래스
Animal 인터페이스
package aop5;
public interface Animal {
public void doSomething();
}
Cat
package aop5;
public class Cat implements Animal{
public void doSomething(){
System.out.println("들어오던지 말던지 신경안쓴다");
}
}
Dog
package aop5;
public class Dog implements Animal{
public void doSomething(){
System.out.println("꼬리를 흔들며 반긴다");
}
}
MyAspect
package aop5;
public class MyAspect {
public void before(){
System.out.println("주인을 기다린다");
System.out.println("주인이 집에 들어온다");
}
public void after(){
System.out.println("밥을 맛있게 먹는다");
}
public void after_returning(){
System.out.println("밥을 준다");
}
public void after_throwing(){
System.out.println("밤새 운다");
}
}
스프링 설정 파일을 만든다. applicationContext.xml
만든후 Namespaces 에서 aop태그 클릭해서 추가해준다.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<bean id="cat" class="aop5.Cat"></bean>
<bean id="dog" class="aop5.Dog"></bean>
<bean id="myAspect" class="aop5.MyAspect"></bean>
<aop:config>
<aop:pointcut expression="execution (public void aop5.*.doSomething())" id="pt"/>
<aop:aspect ref="myAspect">
<aop:before method="before" pointcut-ref="pt"/>
<aop:after-returning method="after_returning" pointcut-ref="pt"/>
<aop:after-throwing method="after_throwing" pointcut-ref="pt"/>
<aop:after method="after" pointcut-ref="pt"/>
</aop:aspect>
</aop:config>
</beans>
위 설정파일에 대해 설명하자면..
타겟클래스랑 공통관심사항이 적용된 클래스의 객체를 빈으로 등록해준다.
<aop:config>
이 안에다가 pointcut이 어떤 함수호출인지 pointcut 전/후/정상후/에러후 에 어떤 공통관심사항을 엮을건지
advice들을 aspect로 등록 하자!
예를들자면..↓
<aop:before method="before" pointcut-ref="pt"/>
위에놈은 pointcut으로 지정된 메소드 호출 전에 before() 라는 메소드 호출!
이런식으로 after-returning ....쭉쭉 써내려 간것이다.
</aop:config>
<aop:pointcut expression="이곳에 포인트컷 표현식을 이용해서 특정메소드가 호출되는 상황을 작성" id="pt"/>
POJO 기반 AOP구현 - AspectJ 표현식
● 표현
명시자(패턴)
-패턴은 명시자 마다 다름.
예) execution(public * abc.def..*Service.set*(..)
● 패턴문자
- * : 1개의 모든 값을 표현
argument에서 쓰인 경우 : 1개의 argument
package에 쓰인 경우 : 1개의 하위 package
이름(메소드, 클래스)에 쓰일 경우 : 모든 글자들
- .. : 0개 이상
argument에서 쓰인 경우 : 0개 이상의 argument
package에 스인 경우 : 0개의 이상의 하위 package
● execution
- execution(수식어패턴? 리턴타입패턴 패키지패턴?.클래스명패턴.메소드명패턴(argument패턴))
- 수식어패턴 : public, protected, 생략
- argument에 type을 명시할 경우 객체 타입은 fullyName으로 넣어야 한다.
java.lang은 생략가능
- 위 예 설명
적용하려는 메소드들의 패턴은 public 제한자를 가지며 리턴 타입에는 모든 타입이 다 올 수 있다.
이름은 abc.def 패키지와 그 하위 패키지에 있는 모든 클래스 중 Service로 끝나는 클래스들에서
set으로 시작하는 메소드이며 argument는 0개 이상 오며 타입은 상관 없다.
어라운드 어드바이스(around advice) 사용해서도 해보자.
around를 사용하시려면 MyAspect를 조금바꿔 줘야한다.
MyAspect
package aop6;
import org.aspectj.lang.ProceedingJoinPoint;
public class MyAspect {
public void around(ProceedingJoinPoint pj){
System.out.println("주인을 기다린다");
System.out.println("주인이 집에 들어온다");
try{
pj.proceed();
System.out.println("밥을 준다");
}
catch(Throwable e)
{
System.out.println("밤새 운다");
}
System.out.println("밥을 맛있게 먹는다");
}
public void before(){
System.out.println("주인을 기다린다");
System.out.println("주인이 집에 들어온다");
}
public void after(){
System.out.println("밥을 맛있게 먹는다");
}
public void after_returning(){
System.out.println("밥을 준다");
}
public void after_throwing(){
System.out.println("밤새 운다");
}
}
around라는 함수를 만들어서 매개변수로 JoinPoint의 하위 클래스인 ProceedingJoinPoint를 지정하고,
pj.proceed() = pointcut으로 지정해준 메소드를 불러준다
설정파일에서 는
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<bean id="boy" class="aop5.Boy"></bean>
<bean id="girl" class="aop5.Girl"></bean>
<bean id="myAspect" class="aop5.MyAspect"></bean>
<aop:config>
<aop:pointcut expression="execution (public void aop5.*.doSomething())" id="pt"/>
<aop:aspect ref="myAspect">
<aop:around method="around" pointcut-ref="pt"/>
</aop:aspect>
</aop:config>
</beans>
이제 설정파일을 작성했으니 테스트를 해볼 테스트 클래스를 만들어서 불러 보자.
package aop5;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext context
= new FileSystemXmlApplicationContext("src/aop5/applicationContext.xml");
//파일시스템 경로를 통해 xml파일 찾는아이
Animal a = context.getBean("dog", Animal.class); //동적 바인딩에 의한 위빙이 일어나야 되기때 문에 부모타입으로!
a.doSomething();
}
}
출처 : 삼성SDS멀티캠퍼스
강사 : 홍승길
Email : iccack70@gmail.com
'[Spring]' 카테고리의 다른 글
[Spring]11월 13일 Spring-jdbc 스프링 설정파일을 이용해 연동 예제(JdbcTemplate) (0) | 2015.11.24 |
---|---|
[Spring]11월 11일 Spring Aop설정을 어노테이션(annotation)을 이용한 예제 (1) | 2015.11.11 |
[Spring]11월 11일 Spring AOP용어, AOP 구현 방법, AOP 설정 태그 (0) | 2015.11.11 |
[Spring]11월 10일 Spring AOP 프록시패턴(Proxy pattern) 적용 예제 (0) | 2015.11.10 |
[Spring]11월 10일 Spring AOP, 핵심 관심 사항, 공통 관심 사항 (0) | 2015.11.10 |