Spring

[Spring]AOP 예제__개발공부 88일차

하체는 스쿼트 2022. 7. 13. 02:57

스프링에서 AOP를 구현하는 3가지 방법 중에 XML 스키마 기반 AOP 구현을 해보려고 한다.

 

 

[ XML 스키마 기반 AOP 구현 ]

 

1단계 :  스프링 AOP를 사용하기 위해 jar 의존파일 추가

           com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

 

2단계 : aop.advice 패키지에 있는              
                 ㄴ before,after,around advice  3가지   --      삭제
                

=> before,after,around advice를 대신할 공통 기능을 구현할 클래스(LogPrintProfiler)를 만든다.
   

      aop.LogPrintProfiler.java 
                      ㄴ trace() 구현 - Around Advice
         
3)    xml 설정 파일 
    ㄴ aop 설정하는 태그
        => Aspect(공통기능)를 설정
        => Advice를 어떤 Pointcut(적용하는 지점)에 적용할지를 설정(지정)

 

p209

 

 

프록시를 사용하여
advice적용해 보기

 

5가지 종류

logPrintBeforeAdvice      ogPrintAroundAdvice      AfterReturningAdvice

 

 

xml 작성하기

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
            xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd" >


<bean id="calc" class="aop.CalculatorImpl"></bean>
<bean id="logPrintAroundAdvice" class="aop.advice.LogPrintAroundAdvice"></bean>
<bean id="logPrintBeforeAdvice" class="aop.advice.LogPrintBeforeAdvice"></bean>
<bean id="logPrintAfterReturningAdvice" class="aop.advice.LogPrintAfterReturningAdvice"></bean>

<bean id="calcProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target" ref="calc"></property>

        <property name="proxyInterfaces">
            <list> 
                 <value>aop.Calculator</value>   
            </list>
        </property>

        <property name="interceptorNames">
            <list>
                <value>logPrintBeforeAdvice</value>
                <value>logPrintAroundAdvice</value>
                <value>logPrintAfterReturningAdvice</value>
            </list>
        </property>

</bean>

</beans>

 


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
            xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd" >

//객체 생성하는 부분
<bean id="calc" class="aop.CalculatorImpl"></bean>
<bean id="logPrintAroundAdvice" class="aop.advice.LogPrintAroundAdvice"></bean>
<bean id="logPrintBeforeAdvice" class="aop.advice.LogPrintBeforeAdvice"></bean>
<bean id="logPrintAfterReturningAdvice" class="aop.advice.LogPrintAfterReturningAdvice"></bean>

//calc.add(),sub() 등등 메서드 pointcut 설정 + adroundadvice 등록
//스프링 AOP : 프록시(proxy) 기반 : 핵심기능+공통기능


<bean id="calcProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
- 핵심기능 설정
<property name="target" ref="calc"></property>

//pointcut 설정
//ProxyFactoryBean 클래스 안에 setProxyInterface여기 부분에 
//setProxyInterface(Class[] proxyInterfaces);
<property name="proxyInterfaces">
        <list>                                                     // String배열 형태라 list가 들어가는거임 -->
                <value>aop.Calculator</value>   // 포인트 컷 지정       aop.Calculator를 호출할때 밑에 advice를 호출하겠다. 
        </list>
</property>

//advice 등록(5가지 종류)
<!-- setInterceptorNames(String[] interceptorNames);-->
<property name="interceptorNames">
        <list>
                <value>logPrintBeforeAdvice</value>
                <value>logPrintAroundAdvice</value>
                <value>logPrintAfterReturningAdvice</value>
        </list>
</property>

</bean>


보조기능으로 만들었다면 보조기능을 장착시키기 위해 포인트 컷을 지정해 줘야 한다.
포인트 컷을 사용하기 위해서는  프록시(가짜) 객체를 만들어서 사용한다.
</beans>

 


컴포넌트 스캔을 사용해서
AOP 코딩하기

 

applicationContext.xml 파일에서 "컴포넌트 스캔"을 사용해서 코딩을 수정해 보자.

 

xml작성하기

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
            xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd" >

<context:component-scan base-package="aop"></context:component-scan>

<bean id="calcProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="calc"></property>
<property name="proxyInterfaces">
        <list>
                 <value>aop.Calculator</value>   
        </list>
</property>

<property name="interceptorNames">
            <list>
                <value>logPrintBeforeAdvice</value>
                <value>logPrintAroundAdvice</value>
                <value>logPrintAfterReturningAdvice</value>
            </list>
</property>

</bean>

</beans>

 

 

 


컴포넌트 스캔을 활용해서 객체 생성하려면 @Component를 붙이면 된다.

 

@Component("calc")
public class CalculatorImpl implements Calculator{

}

 


 aspectJ 문법 사용해서
AOP 코딩하기

 

 

XML 작성하기

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
                                                                 xmlns:context="http://www.springframework.org/schema/context"
                                                                 xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                                                  http://www.springframework.org/schema/context
                                                  http://www.springframework.org/schema/context/spring-context.xsd
                                                  http://www.springframework.org/schema/aop
                                                       http://www.springframework.org/schema/aop/spring-aop.xsd">

<context:component-scan base-package="aop"></context:component-scan>

<aop:config>
    <aop:aspect id="traceAspect" ref="logPrintProfiler">
        <aop:around method="trace" pointcut="execution(public * aop..*.*(*,*))" />
    </aop:aspect>
</aop:config>


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
                                                                 xmlns:context="http://www.springframework.org/schema/context"
                                                                 xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                                                  http://www.springframework.org/schema/context
                                                  http://www.springframework.org/schema/context/spring-context.xsd
                                                  http://www.springframework.org/schema/aop
                                                       http://www.springframework.org/schema/aop/spring-aop.xsd">

<context:component-scan base-package="aop"></context:component-scan>

 

//p250 AspectJ 문법 

 

//얘만 주석처리하면 보조기능 장착하지 않겠다는 의미이다.
<aop:config>
    <aop:aspect id="traceAspect" ref="logPrintProfiler">
        // pointcut="exexcution(수식어패턴? 리턴타입패턴 클래스이름패턴?메서드이름패턴(파라미터패턴))"
        <aop:around method="trace" pointcut="execution(public * aop..*.*(*,*))" />
    </aop:aspect>
</aop:config>

//logPrintProfiler 클래스 안에 있는 trace메서드를 지칭하겠다.
</beans>
</beans>