Spring AOP基本使用

1. 說明

AOP能夠給組件創建代理類,在目標類的方法的前後,異常等位置織入自定義代碼,到達方法增強的目的;

2.  步驟

2.1 編寫業務類;
2.2 編寫業務切面類,在目標業務類的目標方法的適當位置(方法之前、方法運行結束、方法出現異常)編寫自定義代碼;
        通知方法:
             前置通知(@Before):在目標方法運行之前運行
              後置通知(@After)::在目標方法運行結束之後運行(無論方法正常結束還是異常結束)
              返回通知(@AfterReturning):在目標方法(div)正常返回之後運行
             異常通知(@AfterThrowing):在目標方法(div)出現異常以後運行
              環繞通知(@Around):動態代理,手動推進目標方法運行(joinPoint.procced())
2.3 給切面類的目標方法標註何時何地運行(通知註解);
2.4 將切面類和業務邏輯類(目標方法所在類)都加入到容器中;
2.5 給配置類中加 @EnableAspectJAutoProxy 【開啓基於註解的aop模式】

3. 例子

  • 3.1 業務類
package com.yibai.spring.annotation.aop;

public class Calculator {

	public int div(int a, int b) {
		return a / b;
	}

}
  • 3.2 業務切面類
package com.yibai.spring.annotation.aop;

import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class CalculatorAspect {

	@Pointcut(value = "execution(public int com.yibai.spring.annotation.aop.Calculator.*(..))")
	public void pointCutCalculator() {
	}

	@Before("pointCutCalculator()")
	public void before(JoinPoint joinPoint) {
		Object[] args = joinPoint.getArgs();
		String methodName = joinPoint.getSignature().getName();
		System.out.println("@Before ... 方法名: " + methodName + ", 方法參數: " + Arrays.asList(args));
	}

	@After("pointCutCalculator()")
	public void after(JoinPoint joinPoint) {
		Object[] args = joinPoint.getArgs();
		String methodName = joinPoint.getSignature().getName();
		System.out.println("@After ... 方法名: " + methodName + ", 方法參數: " + Arrays.asList(args));
	}

	// returning: 接收返回值
	@AfterReturning(value = "pointCutCalculator()", returning = "result")
	public void afterReturning(JoinPoint joinPoint, Object result) {
		Object[] args = joinPoint.getArgs();
		String methodName = joinPoint.getSignature().getName();
		System.out.println(
				"@AfterReturning ... 方法名: " + methodName + ", 方法參數: " + Arrays.asList(args) + ", 正常返回值: " + result);
	}

	// throwing: 接收異常信息
	@AfterThrowing(value = "pointCutCalculator()", throwing = "e")
	public void afterThrowing(JoinPoint joinPoint, Exception e) {
		Object[] args = joinPoint.getArgs();
		String methodName = joinPoint.getSignature().getName();
		System.out.println("@AfterThrowing ... 方法名: " + methodName + ", 方法參數: " + Arrays.asList(args) + ", 異常信息: " + e);
	}

}
  • 3.3 主配置類
package com.yibai.spring.annotation.main.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

import com.yibai.spring.annotation.aop.Calculator;
import com.yibai.spring.annotation.aop.CalculatorAspect;

@EnableAspectJAutoProxy //開啓基於註解的aop模式
public class MainConfigForAop {

	@Bean
	public Calculator calculator() {
		return new Calculator();
	}

	@Bean
	public CalculatorAspect calculatorAspect() {
		return new CalculatorAspect();
	}

}
  • 3.4 啓動類
package com.yibai.spring.annotation.main;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.yibai.spring.annotation.aop.Calculator;
import com.yibai.spring.annotation.main.config.MainConfigForAop;

/**
 * Hello world!
 *
 */
public class MainClass {

	public static void main(String[] args) throws Exception {
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(
				MainConfigForAop.class);

		Calculator calculator = applicationContext.getBean(Calculator.class);
		System.out.println("結果: " + calculator.div(10, 2));

		applicationContext.close();

	}
}
  • 3.5 運行打印結果
@Before ... 方法名: div, 方法參數: [10, 2]
@After ... 方法名: div, 方法參數: [10, 2]
@AfterReturning ... 方法名: div, 方法參數: [10, 2], 正常返回值: 5
結果: 5

     當運行 10/0 的打印結果

@Before ... 方法名: div, 方法參數: [10, 0]
@After ... 方法名: div, 方法參數: [10, 0]
@AfterThrowing ... 方法名: div, 方法參數: [10, 0], 異常信息: java.lang.ArithmeticException: / by zero
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at com.yibai.spring.annotation.aop.Calculator.div(Calculator.java:6)
	at com.yibai.spring.annotation.aop.Calculator$$FastClassBySpringCGLIB$$ef7d340d.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
	at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:52)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.aspectj.AspectJAfterAdvice.invoke(AspectJAfterAdvice.java:47)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:52)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
	at com.yibai.spring.annotation.aop.Calculator$$EnhancerBySpringCGLIB$$bcd84541.div(<generated>)
	at com.yibai.spring.annotation.main.MainClass.main(MainClass.java:57)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章