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)

 

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