天天看點

Spring AOP 三種實作方式

還是使用之前CURD的例子

配置

pom.xml

添加AOP的依賴

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.6</version>
</dependency>
           

resources資源檔案夾下添加

applicationContext.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: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 ">

</beans>
           

三種方法實作添加日志

測試類不變:

public class MyTest {
    @Test
    public void test(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        CRUD crud = (CRUD)context.getBean("crud");
        crud.add();
        crud.delete();
        crud.update();
        crud.query();
    }
}
           

CRUD

CRUDImpl

也不變

方法一:原生 Spring API

applicationContext.xml

<bean id="crud" class="com.sleepyyoung.crud.CRUDImpl"/>
<bean id="beforeLog" class="com.sleepyyoung.log.BeforeLog"/>
<aop:config>
    <!--切入點-->
    <aop:pointcut id="pointcut" expression="execution( * com.sleepyyoung.crud.CRUDImpl.* (..) )"/>
    <!--環繞-->
    <aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut"/>
</aop:config>
           

BeforeLog

import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;


public class BeforeLog implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.print("[info] " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis()) + " 調用了" + method.getName() + "()方法:");
    }
}
           
Spring AOP 三種實作方式

方法二:自定義切面類

applicationContext.xml

<bean id="crud" class="com.sleepyyoung.crud.CRUDImpl"/>
<bean id="beforeLog" class="com.sleepyyoung.log.BeforeLog"/>
<!--    <aop:config>-->
<!--        &lt;!&ndash;切入點&ndash;&gt;-->
<!--        <aop:pointcut id="pointcut" expression="execution( * com.sleepyyoung.crud.CRUDImpl.* (..) )"/>-->
<!--        &lt;!&ndash;環繞&ndash;&gt;-->
<!--        <aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut"/>-->
<!--    </aop:config>-->

<bean id="diy" class="com.sleepyyoung.log.DIYPointCut"/>
<aop:config>
    <aop:aspect ref="diy">
        <aop:pointcut id="point" expression="execution( * com.sleepyyoung.crud.CRUDImpl.* (..)))"/>
        <aop:before method="before" pointcut-ref="point"/>
    </aop:aspect>
</aop:config>
           

DIYPointCut

import java.text.SimpleDateFormat;

public class DIYPointCut {
    public void before() throws Throwable {                                                                                        // 這個method我不會擷取...
        System.out.print("[info] " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis()) + " :" /* + " 調用了" + method.getName() + "()方法:" */);
    }
}
           
Spring AOP 三種實作方式

方法三:注解

applicationContext.xml

<bean id="crud" class="com.sleepyyoung.crud.CRUDImpl"/>
<bean id="beforeLog" class="com.sleepyyoung.log.BeforeLog"/>
<!--    <aop:config>-->
<!--        &lt;!&ndash;切入點&ndash;&gt;-->
<!--        <aop:pointcut id="pointcut" expression="execution( * com.sleepyyoung.crud.CRUDImpl.* (..) )"/>-->
<!--        &lt;!&ndash;環繞&ndash;&gt;-->
<!--        <aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut"/>-->
<!--    </aop:config>-->

<bean id="diy" class="com.sleepyyoung.log.DIYPointCut"/>
<aop:config>
    <aop:aspect ref="diy">
        <aop:pointcut id="point" expression="execution( * com.sleepyyoung.crud.CRUDImpl.* (..)))"/>
        <aop:before method="before" pointcut-ref="point"/>
    </aop:aspect>
</aop:config>

<bean id="annotation" class="com.sleepyyoung.log.AnnotationPointCut"/>
<aop:aspectj-autoproxy/>
           

AnnotationPointCut

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

import java.text.SimpleDateFormat;

@Aspect
public class AnnotationPointCut {
    @Around("execution(* com.sleepyyoung.crud.CRUDImpl.* (..) )")
    public void around(ProceedingJoinPoint joinPoint) throws Throwable {
        Signature signature = joinPoint.getSignature();
        System.out.print("[info] " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis()) + " 調用了" + signature.getName() + "()方法:");
        joinPoint.proceed();
        //System.out.println("環繞後");
    }
}
           
Spring AOP 三種實作方式