티스토리 뷰

안녕하세요, 교수님!ㅎㅎ  저 현주입니다.
spring aspect 공부하다가 궁금한게 있어서 메일 보냅니다.
질문의 핵심은 노란색배경으로 강조해두었습니다!


*) aspect의 포인트 컷 대상은 인터페이스여야만 한다? (보다 정확히는 인터페이스로 접근해야만한다?)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?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.xsd
     http://www.springframework.org/schema/aop
     http://www.springframework.org/schema/aop/spring-aop.xsd">
 
    <!-- bean 선언 -->
    <bean id="kenny" class="com.springinaction.aspect.school.MathTeacher">
        <constructor-arg name="name" value="kenny" />
        <constructor-arg name="subject" value="수학" />
    </bean>
 
    <bean id="hyunju" class="com.springinaction.aspect.school.ClassPresident">
        <constructor-arg value="hyunju" />
        <constructor-arg value="반장" />
        <constructor-arg value="3.8" />
    </bean>
 
    <bean id="jinsu" class="com.springinaction.aspect.school.ClassMember">
        <constructor-arg value="jinsu" />
        <constructor-arg value="수포자" />
        <constructor-arg value="2.0" />
    </bean>
 
    <bean id="schoolaudio" class="com.springinaction.aspect.school.SchoolAudio" />
 
    <!-- aspect 선언 -->
    <aop:config>
        <aop:aspect ref="schoolaudio">
            <aop:before method="startBell"
                pointcut="execution(* com.springinaction.aspect.school.MathTeacher.intoClassroom(..))" />
        </aop:aspect>
        <aop:aspect ref="hyunju">
            <aop:after method="bowToTheTeacher" pointcut-ref="intoClassroom" />
            <aop:pointcut
                ="execution(* com.springinaction.aspect.school.Teacher.intoClassroom(..))"
                id="intoClassroom" />
            <aop:after method="bowToTheTeacher" pointcut-ref="intoClassroom" />
        </aop:aspect>
    </aop:config>
</beans>
cs


위처럼 애스펙트를 정의하고, java코드에서


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.springinaction.aspect.school;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class Test {
 
    public static void main(String[] args) {
        ApplicationContext context = 
            new ClassPathXmlApplicationContext("com/springinaction/aspect/school/spring-aspect.xml");
        MathTeacher kenny = (MathTeacher) context.getBean("kenny");
        kenny.intoClassroom(); 
    }
}
 
cs

line11을 보시면 저렇게 Teacher를 구현한 MathTeacher 클래스 객체로 생성해서 intoClassroom()을 호출할 경우 다음의 에러가 발생합니다.


포인트컷 정의시 Teacher는 인터페이스고 이를 구현한 클래스가 MathTeacher입니다.

포인트컷 정의시 Teacher 자리에 MathTeacher가 들어가도 문제가 없지만
java코드에서 반드시 Teacher로만 (=인터페이스로만) 꺼내서 사용해야하는 이유가 무엇인가요??
kenny는 포인트컷 대상이고, 이제 MathTeacher로는 아예 꺼낼 수 없습니다. (kenny.intoClassroom()를 호출하지 않아도 위와같은 에러가 난다는 뜻입니당)



답변

애스펙트는 해당 객체를 감싸는(래퍼) 형태를 취한다. 즉, 여기서 kenny는 MathTeacher 타입의 객체가 아니라, 

Teacher타입으로 만들어진 인터페이스를 구현한 객체라고 봐야 한다. 

(왜 Teahcer타입이냐면, 포인트컷을 Teacher로 했기 때문에 이걸 따르는 것이다.) 

따라서 kenny를 사용하려면 Teacher로 꺼내야만한다.









*) <aop:pointcut>은 위치에 따라 공유 범위와 정의 위치가 달라진다.

-> 왜 그런것인지 모르겠습니다. config내부도 아무 위치에 pointcut을 선언해도 가능해야 한다고 생각했는데 에러가 발생합니다. 


 <aop:aspect> 내부

 해당 aspect 내에서만 공유

 aspect내 모든 위치에 선언 가능

 <aop:config> 내부

 해당 config 내에서만 공유. 

 config 내부의 aspect간 pointcut을 공유할 수 있다. 

 config내 맨 처음에 정의해야만 함


<aop:config> 내부에 선언시 아래 경우만 조심하자. pointcut은 반드시 맨 처음에 정의해야만 함. 




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<aop:config>
        <aop:pointcut
            ="execution(* com.springinaction.aspect.school.Student.solveQuestion(..))"
            id="solveQuestion" />
 
        <aop:aspect>
            ...
        </aop:aspect>
 
        <aop:pointcut
            ="execution(* com.springinaction.aspect.school.Teacher.intoClassroom(..))"
            id="intoClassroom" />
 
        <aop:aspect>
            ...
        </aop:aspect>
</aop:config>
cs





답변

스프링에서 그렇게 정의한 것이므로 정해진 규칙대로 사용하면 된다.






*) aspect로 선언된 bean에 다른 aspect를 적용시킬 수 없다. 

즉, 포인트컷 대상 중 aspect로 선언된 대상은 aspect가 적용되지 않는다. 

(xml상의 설정순서와 상관없이 aspect로 선언됬다면 포인트컷이 적용되지 않음)


제가 실습했던 프로젝트 소스를 첨부했습니다. 

com.springinaction.aspect.school안에 Test.java와 spring-aspect.xml을 보시면


제가 의도한 결과는


♪~ ~ ~ ~♪~ ~ 수업시작 ~ ~♪~ ~ ~ ~♪

kenny(수학)      : 자~ 수업시작하자! 자리에 앉아.

hyunju(반장)     : 선생님께 경례~!

100 * 100 = ?

jinsu(수포자)     : 못풀겠습니다..

kenny(수학)      : 틀렸네요~ 더 노력하세요!

hyunju(반장)     : 문제를 풀었습니다!



인데 실제 결과는


kenny(수학)      : 자~ 수업시작하자! 자리에 앉아.

100 * 100 = ?

jinsu(수포자)     : 못풀겠습니다..

kenny(수학)      : 틀렸네요~ 더 노력하세요!

hyunju(반장)     : 문제를 풀었습니다!


입니다.


제 생각에는, kenny가 교실에 들어오기전 종이 울리고, 반장이 인사하는 애스펙트가

kenny가 애스펙트로 선언되었기 때문에 제외된 것 같습니다. 왜냐하면 다른 MathTeacher인 sally에는 애스펙트가 적용되기때문에..

aspect로 선언된 bean에 다른 aspect를 적용시킬 수 없는 건가요??






답변

앞에서 말했다 시피, 이미 kenny는 MathTeacher타입의 객체가 아니라 Teahcer 인터페이스를 구현한 또 다른 인터페이스 타입의 객체라고 봐야한다.

그래서 포인트컷 대상이 안된것이다..?

 


공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함