SpringAOP的運用方式——註解方式和XML配置方式

SpringAOP的運用方式——註解方式和XML配置方式java

AOP(Aspect Oriented Programming):面向切面編程,經過預編譯方式和運行期動態代理實現程序功能的統一維護的一種技術。web

主要功能

日誌記錄,性能統計,安全控制,事務處理, 異常處理等等。

主要意圖

將日誌記錄,性能統計,安全控制,事務處理, 異常處理等代碼從業務邏輯代碼中劃分出來,經過對這些行爲的分離,咱們但願能夠將它們獨立到非指導業務邏輯的方法中,進而改變這些行爲的時候不影響業務邏輯的代碼。
 
AOP在運用中,大致能夠經過兩種處理方式: 註解方式XML配置方式
(一)、註解方式
  a.controller
package controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping
public class ProjectController {
    @RequestMapping("/success/{param}")
    public String goContent(@PathVariable String param, Model model){
        System.out.println(param + "調用了 Controller");
        model.addAttribute("userName",param);
        return "/success";
    }
}
須要經過AOP自動添加日誌的controller
  b.切面處理的邏輯
package north;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

import java.io.IOException;

@Configuration
@EnableAspectJAutoProxy
@ComponentScan(basePackages = "controller")
@Aspect
public class AspectStyleNorth {
    @Pointcut("execution(* controller.*.*(..))")
    public void pointcut() {
        System.out.println("定義切點.....");
    }

    @Before(value="pointcut()")
    public void before() {
        System.out.println("AspectStyleNorth.before()方法執行前執行.....");
    }

    @After("pointcut()")
    public void after(JoinPoint joinPoint) throws IOException {
        System.out.println("AspectStyleNorth.after()方法執行後執行.....");
    }

    @Around(value="pointcut()")
    public Object around(ProceedingJoinPoint pjp){
        System.out.println("AspectStyleNorth.around()方法環繞start.....");
        Object rs = new Object();
        try {
            rs = pjp.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        System.out.println("AspectStyleNorth.around()方法環繞end.....");
        return rs;
    }

    @AfterThrowing(value="pointcut()", throwing="e")
    public void exception(Exception e) {
        //記錄異常
        System.out.println("exception ["+e+"]");
    }

}
註解AOP處理的編寫

  c.springmvc.xml中須要配置對 註解類的掃描spring

<context:component-scan base-package="north"></context:component-scan>

  d.效果express

【說明】:around()與before() 開始執行的前後不肯定,但before() 一定在around()中 proceedingJoinPoint.proceed()以前執行。編程

(二)、XML配置方式
  a.controller
package controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping
public class ProjectController {
    @RequestMapping("/success/{param}")
    public String goContent(@PathVariable String param, Model model){
        System.out.println(param + "調用了 Controller");
        model.addAttribute("userName",param);
        return "/success";
    }
}
須要經過AOP自動添加日誌的controller
  b.springmvc.xml 的配置,添加運用到註解的類(bean)的掃描
    <!-- 掃描下方切面配置的各個切點所在的包 -->
    <context:component-scan base-package="controller"></context:component-scan>
    
    <!-- 切面配置 -->
    <aop:config>
        <aop:pointcut id="pointcut" expression="execution(* controller.*.*(..))"/>
        <aop:aspect ref="aspectStyleSouth">
            <aop:before pointcut-ref="pointcut" method="before"/>
            <aop:after pointcut-ref="pointcut" method="after"/>
            <aop:around pointcut-ref="pointcut" method="around"/>
            <aop:after-throwing pointcut-ref="pointcut" method="exception" throwing="e"/>
        </aop:aspect>
    </aop:config>

    <bean id="aspectStyleSouth" class="south.AspectStyleSouth"/>

【注】:須要同時掃描兩個地方的包:①AOP附加處理邏輯所在的包;②運用到 AOP 的業務邏輯所在的包。安全

  c.切面處理的邏輯
package south;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

import java.io.IOException;

@Aspect
public class AspectStyleSouth {

    public void before() {
        System.out.println("before方法執行前執行.....");
    }

    @Pointcut("execution(* server.*.*(..))")
    public void pointcutA() {
        System.out.println("定義切點.....");
    }

    @Before(value="pointcutA()")
    public void beforeA() {
        System.out.println("AspectStyleNorth.before()方法執行前執行.....");
    }


    /**
     *
     * @Title:doAfterInServiceLayer
     * @Description: 方法調用後觸發
     *  記錄結束時間
     * @author shaojian.yu
     * @date 2014年11月2日 下午4:46:21
     * @param joinPoint
     */
    public void after(JoinPoint joinPoint) throws IOException {
        Object[] args = joinPoint.getArgs() == null ? new String[]{""} : joinPoint.getArgs();
        System.out.println("after方法執行後執行....."+args[0]);
    }

    public Object around(ProceedingJoinPoint pjp){
        System.out.println("around方法環繞start.....");
        Object rs = new Object();
        try {
            rs = pjp.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        System.out.println("around方法環繞end.....");
        return rs;
    }

    public void exception(Exception e) {
        //記錄異常
        System.out.println("exception ["+e+"]");
    }
}
XML配置方式中,對於的AOP須要添加的處理邏輯

  d.效果mvc

 

項目的目錄:app

 

延伸:ide

1.在AOP中,須要用到傳參的時,可參考:【第六章】 AOP 之 6.3 基於Schema的AOP ——跟我學spring3性能

2.AOP中,方法、路徑、參數等匹配的表達式,可參考:Aspectj execution表達式

相關文章
相關標籤/搜索