Spring AOP應用

1、Spring AOP框架

  AOP(Aspect Orient Programming),其實也就是面向切面編程。面向對象編程(OOP)是從靜態角度考慮程序結構。面向切面編程(AOP)是從動態角度考慮程序運行過程。java

  根據我的的理解,AOP執行圖大體以下:spring

2、Spring AOP相關概念

  1. 切面(Aspect):業務流程運行的某個特定步驟,也就是應用運行過程當中的關注點,關注點能夠橫切多個對象,也稱爲橫切關注點。如示例中的AspectService。apache

  2. 鏈接點(Joinpoint):是切面類和業務類的鏈接點。編程

  3. 通知(Advice):在切面類中,聲明對業務方法執行額外加強處理。框架

    3.1 前置通知(Before Advice):切入前執行測試

    3.2 後置通知(After Advice):切入後執行【無論程序在運行過程當中是否發生異常】spa

    3.3 返回後通知(AfterReturning Advice):切入後執行【程序成功運行後】代理

    3.4 環繞通知(Around Advice):近似等於Before Advice與AfterReturning Advice總和,Around Advice 既可在執行目標方法以前,也可在執行目標方法後,既然如此的不肯定爲何不用Before Advice + After Advice代替呢?我的以爲仍是省着點用吧日誌

    3.5 異常通知(AfterThrowing Advice):在切入點發生異常時執行    code

  4. 切入點(Pointcut):能夠插入加強處理的鏈接點,說白了就是當基本個鏈接點符合要求時,這個鏈接點就會添加額外加強處理,這個點也就成了切入點了。

  5. 目標(Target):被代理的對象。

3、Spring AOP示例【以日誌管理爲例】

  1. 切面定義

package com.swyma.spring.service;

import java.util.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Service;

import com.swyma.spring.core.DateUtils;

/**
 * AOP切面
 * @author yemaoan
 *
 */
@Aspect
@Service
public class AspectService {

    Log log = LogFactory.getLog(AspectService.class);
    
    @Pointcut("execution(* *.create(..))")
    public void createPointCut() {
        
    }
    
    @Around(value = "createPointCut()")
    public void weaveCreatePointCut(JoinPoint join) {
        Object obj = join.getTarget().getClass().getSimpleName();
        log.info("用戶 " + "  " +" 在 " + DateUtils.getDate2String(new Date(),"yyyy-MM-dd HH:mm:ss") + " 調用了 " + obj + " 並執行了 create 操做");
    }
    
    @Pointcut("execution(* *.modify(..))")
    public void modifyPointCut() {
        
    }
    
    @After(value = "modifyPointCut()")
    public void weaveModifyPointCut(JoinPoint join) {
        log.info("用戶 " + "  " +" 在 " + DateUtils.getDate2String(new Date(),"yyyy-MM-dd HH:mm:ss") + " 執行了 modify 操做");
    }
    
    @Pointcut("execution(* *.delete(..))")
    public void deletePointCut() {
        
    }

    @After(value = "deletePointCut()")
    public void weaveDeletePointCut(JoinPoint join) {
        log.info("用戶 " + "  " +" 在 " + DateUtils.getDate2String(new Date(),"yyyy-MM-dd HH:mm:ss") + " 執行了 delete 操做");
    }
}

  2. 目標【target】

    2.1 UserService【用戶服務】

package com.swyma.spring.service;

import org.springframework.stereotype.Service;

import com.swyma.spring.entity.User;

@Service
public class UserService extends BasicService {

    
    public void create(User user) {
        
    }
    
    public void modify(User user) {
        
    }
    
    public void delete(User user) {
        
    }
    
}

    2.2 RegisteService【註冊服務】

package com.swyma.spring.service;

import org.springframework.stereotype.Service;

@Service
public class RegisterService extends BasicService {

    public void create() {
        
    }
    
}

  3. 測試類

package com.swyma.spring.test;

import org.junit.Test;

import com.swyma.spring.core.ISpringContext;
import com.swyma.spring.entity.User;
import com.swyma.spring.service.BasicSpringContext;
import com.swyma.spring.service.LoginService;
import com.swyma.spring.service.RegisterService;
import com.swyma.spring.service.UserService;


/**
 * JUintTest
 * @author yemaoan
 *
 */
public class TestSpringEnv {

    @Test
    public void testLookup() {
        ISpringContext context = new BasicSpringContext();
        LoginService loginService = context.lookup(LoginService.class);
        loginService.handle();
    }
    
    @Test
    public void testAspect() {
        ISpringContext context = new BasicSpringContext();
        UserService userService = context.lookup(UserService.class);
        RegisterService registerService = context.lookup(RegisterService.class);
        userService.create(new User());
        registerService.create();
    }
    
}

  4. 運行結果【cosole】

21:26:30,741  INFO com.swyma.spring.service.AspectService:35 - 用戶    在 2013-10-03 21:26:30 調用了 UserService 並執行了 create 操做
21:26:30,742  INFO com.swyma.spring.service.AspectService:35 - 用戶    在 2013-10-03 21:26:30 調用了 RegisterService 並執行了 create 操做

4、總結

  1. 以上均是我的的對Spring AOP的理解,若有錯誤之處,望各位網友批評批評,共同探討,在些先謝過!

  2. Spring AOP核心思想實際上是個動態代理的機制,動態代理【DynamicProxy】尋找【JointPoint】鏈接點,當找到符合要求時就會執行通知【Advice】。

相關文章
相關標籤/搜索