Spring AOP

Spring AOP

context-aop.xml

<?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:tx="http://www.springframework.org/schema/tx"
	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/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
    	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">

    <bean id="logAop" class="common.aop.LogAdvice" />

    <!/* AOP 설정 */>
    <aop:config>
       <aop:aspect ref="logAop">
            <aop:pointcut id="getMethods"
            expression="execution(* *..*service.impl.*Impl.select*(..))" />

            <aop:before method="beforeExecuteGetMethod"
            pointcut-ref="getMethods" />

            <aop:after-returning method="afterReturningExecuteGetMethod"
            returning="retVal" pointcut-ref="getMethods" />

            <aop:after method="afterExecuteGetMethod"
            pointcut-ref="getMethods" />

            <aop:around method="timeLog"
                        pointcut-ref="getMethods" />

	   </aop:aspect>
	</aop:config>

</beans>

LogAdvice.java

/**
 *
 */
package common.aop;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import common.service.mapper.InsertLogMapper;

/**
 * @author Park Sun Ho
 *
 */
public class LogAdvice {

    private static final Logger logger = LoggerFactory.getLogger(LogAdvice.class);

    @Resource(name="insertLogMapper")
    private InsertLogMapper insertLogMapper;

    public void beforeExecuteGetMethod(JoinPoint thisJointPoint) {

        logger.info("-------------------------------------");
        logger.info("-------------------------------------");

        Object[] parameterValues = thisJointPoint.getArgs();

        MethodSignature signature = (MethodSignature)thisJointPoint.getSignature();
        Method method = signature.getMethod();

        Class<?>[] parameterTypes = method.getParameterTypes();

        logger.info("0 AOP @Before-Execute :" + parameterTypes.length);

        //파라미터 값 Map
        Map<String, String> paramMap = new HashMap<String, String>();

        if ( parameterTypes.length != 0 ) {

            for ( int i = 0 ; i < parameterTypes.length ; i++ )
            {
                parameterTypes[i].getName();

                logger.info("parameterName   : " + parameterTypes[i].getName());
                logger.info("parameterValues : " + parameterValues[i]);

                if ("java.util.Map".equals(parameterTypes[i].getName())){
                    paramMap =(Map<String, String>)parameterValues[i];
                }
            }
        }

        /* 전달되는 모든 파라미터들을 Object의 배열로 가져온다. */
        logger.info("1 AOP @Before-Execute : " + Arrays.toString(thisJointPoint.getArgs()));

        /* 해당 Advice의 타입을 알아낸다. */
//        logger.info("2 AOP @Before-Execute: " + thisJointPoint.getKind());

        /* 실행하는 대상 객체의 메소드에 대한 정보를 알아낼 때 사용 */
//        logger.info("3 AOP @Before-Execute: " + thisJointPoint.getSignature().getName());

        /* target 객체를 알아낼 때 사용 */
//        logger.info("4 AOP @Before-Execute: " + thisJointPoint.getTarget().toString());

        /* Advice를 행하는 객체를 알아낼 때 사용 */
//        logger.info("5 AOP @Before-Execute: " + thisJointPoint.getThis().toString());
//        setSession(thisJointPoint, "AOP Msg : @Before-Execute\n");

        //실행 시간 시작
        long startTimeLog = System.currentTimeMillis();

        //로그 입력
        Map<String, Object> data = new HashMap<String, Object>();

        data.put("DOC_TYPE", paramMap.get("SYSTEM_FLAG"));
        data.put("TYPE_ID",  thisJointPoint.getSignature().getName());
        data.put("DOC_NO",   paramMap.get("TIME_STAMP"));
        data.put("MSG",      thisJointPoint.getTarget().toString());
        data.put("CLOBMSG",  Arrays.toString(thisJointPoint.getArgs()));

        try {
            insertLogMapper.insertLog(data);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        //실행 시간 종료
        long stopTimeLog = System.currentTimeMillis();

        //iflog insert 동작 시간을 출력한다.
        logger.info(thisJointPoint.getTarget().toString() + thisJointPoint.getSignature().getName() + " : " + paramMap.get("TIME_STAMP") + ", IFLOG INSERT : " + ( stopTimeLog - startTimeLog));

    }

    public void afterReturningExecuteGetMethod(JoinPoint thisJointPoint) {

        logger.info("#####################################");
        logger.info("#####################################");

        /* 전달되는 모든 파라미터들을 Object의 배열로 가져온다. */
         logger.info("1 AOP @AfterReturning-Execute :" + Arrays.toString(thisJointPoint.getArgs()));

        /* 해당 Advice의 타입을 알아낸다. */
//        logger.info("2 AOP @AfterReturning-Execute :" + thisJointPoint.getKind());

        /* 실행하는 대상 객체의 메소드에 대한 정보를 알아낼 때 사용 */
//        logger.info("3 AOP @AfterReturning-Execute :" + thisJointPoint.getSignature().getName());

        /* target 객체를 알아낼 때 사용 */
//        logger.info("4 AOP @AfterReturning-Execute :" + thisJointPoint.getTarget().toString());

        /* Advice를 행하는 객체를 알아낼 때 사용 */
//        logger.info("5 AOP @AfterReturning-Execute :" + thisJointPoint.getThis().toString());
//        setSession(thisJointPoint, "AOP Msg : @AfterReturning-Execute\n");
    }

    public void afterExecuteGetMethod(JoinPoint thisJointPoint) {

        logger.info("*************************************");
        logger.info("*************************************");

        /* 전달되는 모든 파라미터들을 Object의 배열로 가져온다. */
         logger.info("1 AOP @After-Execute :" + Arrays.toString(thisJointPoint.getArgs()));

        /* 해당 Advice의 타입을 알아낸다. */
//        logger.info("2 AOP @After-Execute :" + thisJointPoint.getKind());

        /* 실행하는 대상 객체의 메소드에 대한 정보를 알아낼 때 사용 */
//        logger.info("3 AOP @After-Execute :" + thisJointPoint.getSignature().getName());

        /* target 객체를 알아낼 때 사용 */
//        logger.info("4 AOP @After-Execute :" + thisJointPoint.getTarget().toString());

        /* Advice를 행하는 객체를 알아낼 때 사용 */
//        logger.info("5 AOP @After-Execute :" + thisJointPoint.getThis().toString());
//        setSession(thisJointPoint, "AOP Msg : @After-Execute\n");
    }

    public Object timeLog(ProceedingJoinPoint pjp) throws Throwable {
        logger.info("==============================");

        long startTime = System.currentTimeMillis();
        logger.info(Arrays.toString(pjp.getArgs()));

        //실제 타겟을 실행하는 부분이다. 이 부분이 없으면 advice가 적용된 메소드가 동작을 안할것 같다.
        Object result = pjp.proceed();  //proceed는 Exception 보다 상위 Throwable을 처리해야 한다.

        long endTime = System.currentTimeMillis(); //target 메소드의 동작 시간을 출력한다.
        logger.info("#############################################################################################################");
        logger.info("##### API "+ pjp.getTarget().toString() + pjp.getSignature().getName() + " running time is : " + (endTime - startTime));
        logger.info("#############################################################################################################");


        //Around를 사용할 경우 반드시 Object를 리턴해야 한다.
        return result;
    }

    /**
     * 세션 처리
     *
     */
    public void setSession(JoinPoint thisJointPoint, String msg) {

        HttpServletRequest request = null;

        for (Object o : thisJointPoint.getArgs()) {
            if (o instanceof HttpServletRequest) {
                request = (HttpServletRequest) o;
            }
        }

        HttpSession session = request.getSession();

        String strDes = (String)session.getAttribute("description");

        if(strDes == null || strDes.length() == 0) {
            strDes = "";
        }

        session.setAttribute("description", strDes+msg);

    }
}