SpringAOP的三種實現方式總結

SpringAOP的實現方式

1.使用原生SpringApi接口實現AOP:

  • 首先咱們寫個UserService接口和它的實現類java

    public interface UserService {
        public void add();
    }
    
    public class UserServiceImpl implements UserService {
        @Override
        public void add() {
            System.out.println("add user");
        }
    }
  • 在applicationConte.xml導入命名空間。先搞切入點,再在切入點把Log.java切入進去。spring

<bean id="userService" class="com.zhou.service.UserServiceImpl"/>
    <bean id="log" class="com.zhou.log.Log"/>
    <bean id="afterLog" class="com.zhou.log.AfterLog"/>
<!--    方式一:執行原生SpringApi接口-->
    <aop:config>
<!--        切入點 execution(第一個「*」表示返回值的類型任意 「com.zhou.service.UserServiceImpl」要執行的位置  「.*」 表明這個類下的全部方法  「..」表明能夠有任意參數) -->
        <aop:pointcut id="pointcut" expression="execution(* com.zhou.service.UserServiceImpl.*(..))"/>

<!--        執行環繞!  把log這個類切入到「* com.zhou.service.UserServiceImpl.*(..)」方法上面-->
        <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
        <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
    </aop:config>
  • 前置和後置的Log
Log.java:
public class Log implements MethodBeforeAdvice {
    // method:方法
    //objects:參數
    //o:對象
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println(o.getClass().getName()+"的"+method.getName()+"被執行了");//某某對象的方法被執行了
    }
}


AfterLog.java:    
package com.zhou.log;

public class AfterLog implements AfterReturningAdvice {
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] objects, Object target) throws Throwable {
        System.out.println("執行了"+method.getName()+"返回的結果爲"+returnValue);
    }
}
  • 測試代碼以下
public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //PS:動態代理的是接口
        UserService userService = (UserService) context.getBean("userService");
        userService.add();
    }
    //報錯了 由於沒導入aspect依賴
}
  • 輸出結果

com.zhou.service.UserServiceImpl的add被執行了
add user
執行了add返回的結果爲nullexpress

2.自定義類實現AOP

  • 先寫一個簡單MyPointCut類api

    public class MyPointCut {
    
        public void before(){
            System.out.println("我在方法執行前面");
        }
    
        public void after(){
            System.out.println("我在方法執行後面");
        }
    }
  • 另外一種方式配置applicationConte.xmlapp

    <!--方式二:自定義類-->
        <bean id="diyPointCut" class="com.zhou.own.MyPointCut"/>
        <aop:config>
    <!--自定義切面 -->
            <aop:aspect ref="diyPointCut">
    <!--切入點-->
            <aop:pointcut id="pointcut" expression="execution(* com.zhou.service.UserServiceImpl.*(..))"/>
    <!-- 通知-->
                <aop:before method="before" pointcut-ref="pointcut"/>
                <aop:after method="after" pointcut-ref="pointcut"/>
            </aop:aspect>
        </aop:config>
  • 測試一下ide

    public class MyTest {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            UserService userService = (UserService) context.getBean("userService");
            userService.add();
    
        }
    }

    輸出結果:測試

    ​ 我在方法執行前面
    ​ add user
    ​ 我在方法執行後面代理

  • execution表達式:code

    <aop:pointcut id="pointcut" expression="execution(* com.zhou.service.UserServiceImpl.*(..))"/>
    * 表示返回值的類型任意
    com.zhou.service.UserServiceImpl 橫切的業務類路徑
    .* 表明這個類下的全部方法
    (..) ()表明參數,兩個點表明能夠有任意參數

    3.使用註解實現AOP

  • MyPointCut.javaxml

    @Aspect
    public class AnnotationPointCut {
        @Before("execution(* com.zhou.service.UserServiceImpl.*(..))")
        public void before() {
            System.out.println("我在方法執行前面");
        }
    
        @After("execution(* com.zhou.service.UserServiceImpl.*(..))")
        public void after() {
            System.out.println("我在方法執行後面");
        }
  • 關於環繞(@Around)

    //在環繞加強中 咱們能夠給定一個參數 表明咱們要處理切入的點 JointPoint:與切入點匹配的執行點
        @Around("execution(* com.zhou.service.UserServiceImpl.*(..))")
        public void around(ProceedingJoinPoint joinPoint) throws Throwable {
            System.out.println("環繞前");
            Object proceed = joinPoint.proceed();//執行方法
            System.out.println("環繞後");
    
            //Signature signature = joinPoint.getSignature();
            //System.out.println("signature:" + signature.toString());
        }
    }
  • 配置文件

    <!--    方式三-->
        <bean id="annotationPointCut" class="com.zhou.own.AnnotationPointCut"/>
    <!--    開啓註解支持-->
        <aop:aspectj-autoproxy/>
  • 輸出結果:看看順序= =

    環繞前 我在方法執行前面 add user 我在方法執行後面 環繞後

相關文章
相關標籤/搜索