1. 程式人生 > >spring AOP的兩種配置方式

spring AOP的兩種配置方式

can 之前 top () 就是 記錄 string -s 服務

  連接點(JoinPoint) ,就是spring允許你是通知(Advice)的地方,那可就真多了,基本每個方法的前、後(兩者都有也行),或拋出異常是時都可以是連接點,spring只支持方法連接點。其他如AspectJ還可以讓你在構造器或屬性註入時都行,不過那不是咱們關註的,只要記住,和方法有關的前前後後都是連接點。

方式一:xml方式配置

1.配置xml文件

    <bean id="dataSourceExchange" class="com.ooper.www.datasource.DataSourceExchange"/> <!--輔助功能bean
--> <aop:config> <aop:pointcut id="dataSourcePointcut" expression="execution(* com.ooper.www.service.Impl.AccountServiceImpl.*(..))"/> <!-- 指定核心業務功能 --> <aop:aspect ref="dataSourceExchange"> <!--指定輔助功能 --> <aop:before pointcut-ref
="dataSourcePointcut" method="before"/><!-- 執行核心任務之前執行 --> <aop:after pointcut-ref="dataSourcePointcut" method="after"/><!-- 執行核心任務之後執行 --> </aop:aspect> </aop:config>

2. 輔助功能java代碼

package com.ooper.www.datasource;
import org.aspectj.lang.JoinPoint;

public class DataSourceExchange { public void before(JoinPoint point) { //獲取目標對象的類類型 Class<?> aClass = point.getTarget().getClass(); String c = aClass.getName(); String[] ss = c.split("\\."); //獲取包名用於區分不同數據源 String methodName = ss[5]; if ("AccountServiceImpl".equals(methodName)) { DataSourceHolder.setDbType(DataSourceEnum.DS2.getKey()); System.out.println("數據源:"+DataSourceEnum.DS2.getKey()); } else { DataSourceHolder.setDbType(DataSourceEnum.DS1.getKey()); System.out.println("數據源:"+DataSourceEnum.DS1.getKey()); } } /** * 執行後將數據源置為空 */ public void after(JoinPoint point) { System.out.println("point:" + point); DataSourceHolder.setDbType(null); } }

方式二:註解方式

1.xml配置文件

      <!-- 註解方式實現AOP -->
  
      <!-- 激活自動代理功能   --> 
      <!-- 代理方式1:采用JDK代理 -->
        <aop:aspectj-autoproxy/> 
        <!--     代理方式2:cglib代理 -->
        <!--     <aop:aspectj-autoproxy proxy-target-class="true"/>   -->
        <!-- 找到被註解了的切面類,進行切面配置 -->
        <context:component-scan base-package="com.how2java.aspect"/>
        <context:component-scan base-package="com.how2java.controller"/>

2.註解配置切面代碼

package com.how2java.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**spring AOP
此段小代碼演示了spring aop中@Around @Before @After三個註解的區別
 * @Before是在所攔截方法執行之前執行一段邏輯。@After 是在所攔截方法執行之後執行一段邏輯。@Around是可以同時在所攔截方法的前後執行一段邏輯。
 * @author Administrator
 * 通過aop攔截後執行具體操作
 */
@Aspect
@Component
public class LogIntercept {

//    @Pointcut("execution(* com.how2java.controller..*.*(..))")
    public void recordLog(){}

    @Before("execution(* com.how2java.controller..*.*(..))")
//    @Before("recordLog()")
    public void before() {
        this.printLog("已經記錄下操作日誌@Before 方法執行前");
    }

    @Around("execution(* com.how2java.controller..*.*(..))")
//    @Around("recordLog()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable{
        this.printLog("已經記錄下操作日誌@Around 方法執行前");
        Object obj = pjp.proceed();
        this.printLog("已經記錄下操作日誌@Around 方法執行後");
        return obj;
    }

     @After("execution(* com.how2java.controller..*.*(..))")
//    @After("recordLog()")
    public void after() {
        this.printLog("已經記錄下操作日誌@After 方法執行後");
    }

    private void printLog(String str){
        System.out.println(str);
    }
}
package com.how2java.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
 
@Aspect    // 註解表示這是一個切面
@Component //表示這是一個bean,由Spring進行管理,使用註解時一定要使用@component或者@Repository、@Controller、@Service中一個去聲明,將切面類放入到spring容器中,不然就去xml中顯式寫一個bean,不然的話就會報錯,無法實現切面功能。

public class LoggerAspect { 
    @Around(value = "execution(* com.how2java.controller..*.*(..))") 
  //表示對com.how2java.controller 這個包中的所有方法進行切面操作
    /*    AOP(execution表達式)
     * 
     * execution(* com.how2java.controller..*.*(..))
        解釋如下:
        符號                                                                           含義
        execution()                        表達式的主體;
        第一個”*“符號                                  表示返回值的類型任意;
        com.how2java.controller        AOP所切的服務的包名,即,我們的業務部分
        包名後面的”..“                                               表示當前包及子包
        第二個”*“                                                         表示類名,*即所有類。此處可以自定義,下文有舉例
        .*(..)                                                         表示任何方法名,括號表示參數,兩個點表示任何參數類型
        
        */
    public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("start log:" + joinPoint.getSignature().getName());
        Object object = joinPoint.proceed();//就是將來與某個核心功能編織之後,用於執行核心功能的代碼
        System.out.println("end log:" + joinPoint.getSignature().getName());
        return object;
    }
}

spring AOP的兩種配置方式