1. 程式人生 > >spring-aop-01

spring-aop-01

aop實現初步

applicationContext.xml配置內容

    <context:annotation-config />
    <context:component-scan base-package="cn.mldn" />

    <!-- 如果要想讓切面控制有效,那麼必須將此類的物件交由Spring進行管理 -->    
    <bean id="serviceProxy" class="cn.mldn.aop.ServiceProxy"/>
    <aop:aspectj-autoproxy  proxy-target-class
="true"/> <!-- 要求進入AOP的配置,重點配置切入點,以及確定切入的處理方法 --> <aop:config> <!-- execution(修飾符匹配? 返回值型別匹配 操作型別匹配? 名稱匹配(引數匹配) 丟擲異常匹配 ) : 主要是用於定義切入點的執行語法 --> <!-- 本次操作裡面沒有編寫修飾符 ,如果要編寫可以使用 public private編寫,可以出現0次或一次 如:"execution(public * cn.mldn..*.*(..))"-->
<!-- "*" : 表示返回值,即支援所有型別的返回值 --> <!-- cn.mldn.. : 描述的是包名稱的匹配 ,如果是 “..” 表示任意的子包下控制 --> <!-- *.* : 描述的是“類.方法” ,*。* 表示所有的類與所有的方法 --> <!-- .. : 描述的是引數 , “..” 表示任意的引數 --> <aop:pointcut expression="execution(* cn.mldn.service..*.*(..))"
id="pointCut"/> <!-- 設定切入點 --> <aop:aspect ref="serviceProxy"> <!-- 進行切面的配置 , 如果是切面控制應該有一個控制的類 --> <!-- 不同的切面處理操作可以使用同一個切入點,或者每一個操作來定義屬於自己的切入點 --> <aop:before method="beforeMethod" pointcut-ref="pointCut"/> <aop:after method="afterMethod" pointcut-ref="pointCut"/> </aop:aspect> </aop:config>

Service

package cn.mldn.service.impl;

import org.springframework.stereotype.Service;
import cn.mldn.service.IMemberService;

@Service
public class MemberServiceImpl implements IMemberService {

    @Override
    public boolean delete(String mid) throws Exception {
        System.out.println("[MemberService] 資料刪除處理");
        return false;
    }
}

package cn.mldn.service;

public interface IMemberService {
   public boolean delete(String mid) throws Exception ;
}

proxy

package cn.mldn.aop;

public class ServiceProxy {
    public void beforeMethod() {
        System.out.println("###### [ServiceProxy] public void beforeMethod(){}");
    }
    public void afterMethod() {
        System.out.println("###### [ServiceProxy] public void afterMethod(){}");
    }
}

test

        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        IMemberService ms = ctx.getBean("memberServiceImpl" ,MemberServiceImpl.class) ;
        ms.delete("123");

result

###### [ServiceProxy] public void beforeMethod(){}
[MemberService] 資料刪除處理
###### [ServiceProxy] public void afterMethod(){}

 

切面函式配置引數

public class ServiceProxy {
    public void beforeMethod(Object obj) {
        System.out.println("###### [ServiceProxy] public void beforeMethod(){} ,引數內容:"+obj);
    }
    public void afterMethod() {
        System.out.println("###### [ServiceProxy] public void afterMethod(){}");
    }
}
<aop:pointcut expression="execution(* cn.mldn.service..*.*(..)) and args(id)" id="pointCut"/>

        <aop:aspect ref="serviceProxy"> 
            <!-- 上面的args裡面的id與arg-names的id是一至的 -->
            <aop:before method="beforeMethod" pointcut-ref="pointCut" arg-names="id"/>
            <aop:after method="afterMethod" pointcut="execution(* cn.mldn.service..*.*(..))"/>
        </aop:aspect>

其他配置

        <aop:aspect ref="serviceProxy"> <!-- 進行切面的配置 , 如果是切面控制應該有一個控制的類  -->
            <!-- 不同的切面處理操作可以使用同一個切入點,或者每一個操作來定義屬於自己的切入點 -->
            <aop:before method="beforeMethod" pointcut-ref="pointCut" arg-names="id"/>
            <aop:after method="afterMethod" pointcut="execution(* cn.mldn.service..*.*(..))"/>
            <!-- 返回值切面   v 只是個標記,隨便寫  ,只是接收,不能更改-->
            <aop:after-returning method="returnMethod" pointcut="execution(* cn.mldn.service..*.*(..))" returning="v" arg-names="v"/>
            <!-- 針對異常進行處理, -->
            <aop:after-throwing method="throwMethod" pointcut="execution(* cn.mldn.service..*.*(..))" throwing="e" arg-names="e"/>

<!-- 環繞通知的配置 -->

              <aop:around method="aroundMethod" pointcut="execution(* cn.mldn.service..*.*(..))"/>

        </aop:aspect>
package cn.mldn.aop;

public class ServiceProxy {
    public void beforeMethod(Object obj) {
        System.out.println("###### [ServiceProxy] public void beforeMethod(){} ,引數內容:"+obj);
    }
    public void afterMethod() {
        System.out.println("###### [ServiceProxy] public void afterMethod(){}");
    }
    
    public void returnMethod(Object val) { //處理返回值
        System.out.println("###### [ServiceProxy] public void returnMethod(){} ,返回值:" + val);
    }
    
    public void throwMethod(Exception e) { // 對異常進行處理
        System.out.println("###### [ServiceProxy] public void throwMethod(){} 異常資訊:" + e );
    }

      public Object aroundMethod(ProceedingJoinPoint point) throws Throwable { //呼叫具體的執行方法
           System.out.println("@@@@@@ aroundMethod() - before 引數:" + new Arrays().toString(point.getArgs()));
           //此時可以正對於引數接收後處理後再傳遞的操作
           Object obj = point.proceed(new Object [] {"abc"});
           System.out.println("@@@@@@ aroundMethod() - after 返回結果:" + obj);
           return true ; //還可以不按照結果返回資料
      }

}

aop annotation

package cn.mldn.aop;

import org.apache.catalina.tribes.util.Arrays;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class ServiceProxy {
    @Before(value="execution(* cn.mldn.service..*.*(..)) and args(id)",argNames="id")
    public void beforeMethod(Object obj) {
        System.out.println("###### [ServiceProxy] public void beforeMethod(){} ,引數內容:"+obj);
    }
    
    @After(value="execution(* cn.mldn.service..*.*(..))")
    public void afterMethod() {
        System.out.println("###### [ServiceProxy] public void afterMethod(){}");
    }
    
    @AfterReturning(value="execution(* cn.mldn.service..*.*(..))",returning="v",argNames="v")
    public void returnMethod(Object val) { //處理返回值
        System.out.println("###### [ServiceProxy] public void returnMethod(){} ,返回值:" + val);
    }
    
    @AfterThrowing(value="execution(* cn.mldn.service..*.*(..))",throwing="e",argNames="e")
    public void throwMethod(Exception e) { // 對異常進行處理
        System.out.println("###### [ServiceProxy] public void throwMethod(){} 異常資訊:" + e );
    }
    
    @Around(value="execution(* cn.mldn.service..*.*(..))")
    public Object aroundMethod(ProceedingJoinPoint point) throws Throwable { //呼叫具體的執行方法
        System.out.println("@@@@@@ aroundMethod() - before 引數:" + new Arrays().toString(point.getArgs()));
        //此時可以正對於引數接收後處理後再傳遞的操作
        Object obj = point.proceed(new Object [] {"abc"});
        System.out.println("@@@@@@ aroundMethod() - after 返回結果:" + obj);
        return true ; //還可以不按照結果返回資料
    }
}