<?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">

    <description>spring 基于AOP的日志处理</description>

    <bean id="logHelper" class="com.zw.platform.util.spring.SpringAopLogHelper" />
    <aop:config expose-proxy="true" proxy-target-class="true">
        <!--切入点 使用了自定义的MethodLog的注解 -->
        <aop:pointcut expression="@annotation(com.zw.common.annotation.MethodLog)" id="logPointcut" />
        <!-- 切面： 将哪个对象中的哪个方法，织入到哪个切入点 -->
        <aop:aspect id="logAspect" ref="logHelper">
            <!-- 前置通知 -->
            <aop:before method="log" pointcut-ref="logPointcut" />
            <aop:after method="logArg" pointcut-ref="logPointcut" />
            <aop:after-returning method="logArgAndReturn"
                returning="returnObj" pointcut-ref="logPointcut" />
        </aop:aspect>
    </aop:config>

    <!-- 接口耗时统计AOP -->
    <bean id="globalRtLogger" class="com.zw.platform.util.spring.GlobalRtLogger" />
    <aop:config expose-proxy="true" proxy-target-class="true">
        <aop:pointcut id="apiRtPointcut" expression=
                "execution(* com.zw..controller..*.*(..)) and @annotation(org.springframework.web.bind.annotation.RequestMapping)"/>
        <aop:pointcut id="serviceRtPointcut" expression=
                "execution(* com.zw..service..*.*(..)) or execution(* com.zw..handler..*.*(..))"/>
        <aop:pointcut id="webClientRtPointcut" expression=
                "execution(* com.zw.platform.push.common.WebClientHandleCom.*(..))"/>
        <aop:aspect id="globalRtAspect" ref="globalRtLogger">
            <aop:around method="apiRtRecorder" pointcut-ref="apiRtPointcut" />
            <aop:around method="serviceRtRecorder" pointcut-ref="serviceRtPointcut" />
            <aop:around method="serviceRtRecorder" pointcut-ref="webClientRtPointcut" />
        </aop:aspect>
    </aop:config>

    <bean id="importLockHelper" class="com.zw.platform.util.imports.lock.ImportLockHelper"/>
    <aop:config expose-proxy="true" proxy-target-class="true">
        <aop:pointcut id="locks" expression="@annotation(importLock)"/>
        <aop:aspect id="importLockAspect" ref="importLockHelper">
            <aop:around method="doLock" pointcut-ref="locks"/>
        </aop:aspect>
    </aop:config>

    <!--方法1: 增加一个拦截器-->
    <!--<bean id="importLockDaoInterceptor" class="com.zw.platform.util.imports.lock.interceptor.ImportLockDaoInterceptor"/>
    <aop:config expose-proxy="true">
        &lt;!&ndash;
            1.这里不能使用注解进行拦截, 原因: https://cloud.tencent.com/developer/article/1170397
            2.这里不能使用cglib动态代理
        &ndash;&gt;
        <aop:pointcut id="lockDao" expression="execution(* com.zw.platform.repository..*.*(..))"/>
        &lt;!&ndash;增加自定义拦截器&ndash;&gt;
        <aop:advisor pointcut-ref="lockDao" advice-ref="importLockDaoInterceptor"/>
    </aop:config>-->

    <!--
        方法2: 单纯的aop前置校验
        拦截: com.zw.platform.repository的包及其子包.
    -->
    <aop:config expose-proxy="true">
        <aop:pointcut id="lockDao" expression="execution(* com.zw.platform.repository..*.*(..))"/>
        <aop:aspect id="importLockDaoAspect" ref="importLockHelper">
            <aop:before method="checkTableLock" pointcut-ref="lockDao"/>
        </aop:aspect>
    </aop:config>
</beans> 