欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring学习 之 AOP

程序员文章站 2022-03-03 12:41:30
...

1.lib包的引入

  • commons-logging-1.2.jar
  • spring-aop-5.2.3.RELEASE.jar
  • spring-aspects-5.2.3.RELEASE.jar
  • spring-beans-5.2.3.RELEASE.jar
  • spring-context-5.2.3.RELEASE.jar
  • spring-core-5.2.3.RELEASE.jar
  • spring-expression-5.2.3.RELEASE.jar

 Aspectj下載地址

  • aspectjrt.jar
  • aspectjtools.jar
  • aspectjweaver.jar
  • org.aspectj.matcher.jar

2.xml的作成

    命名空间 aop bean contect 的引入

3.切面代码的作成 LoggingAspect

  •     前置通知
  •     后置通知
  •     返回通知
  •     异常通知

4.测试类的作成

  •     正常测试
  •     异常测试

5.代码分享

接口

package com.spring.apo;

public interface ArtthemticCalculator {
	int add(int i ,int j); 
	int sub(int i ,int j); 
	int mul(int i ,int j); 
	int div(int i ,int j); 
}

实现类

package com.spring.apo;

import org.springframework.stereotype.Component;

@Component("artthemticCalculator")
public class ArtthemticCalculatorImpl implements ArtthemticCalculator {

	@Override
	public int add(int i, int j) {

		int result = i + j;
		return result;
	}

	@Override
	public int sub(int i, int j) {

		int result = i - j;
		return result;
	}

	@Override
	public int mul(int i, int j) {

		int result = i * j;
		return result;
	}

	@Override
	public int div(int i, int j) {

		int result = i / j;
		return result;
	}
}

日志切面

package com.spring.apo;

import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {
	
	/**
	 * 在com.spring.apo.ArtthemticCalculator
	 * 的每一個方法執行之前 執行的處理
	 */
	@Before("execution(public int com.spring.apo.ArtthemticCalculator.*(..))")
	public void beforeMethod(JoinPoint joinPoint){
		
		String methodName = joinPoint.getSignature().getName();
		Object[] args = joinPoint.getArgs();
		System.out.println("前置通知方法名: " + methodName + "  方法參數為:" + Arrays.asList(args));
	}

	/**
	 * 在com.spring.apo.ArtthemticCalculator
	 * 的每一個方法執行之后 執行的處理
	 * 无论正常还是异常终了
	 * 不能接受到返回值
	 */
	@After("execution(public int com.spring.apo.ArtthemticCalculator.*(..))")
	public void afterMethod(JoinPoint joinPoint){
		
		String methodName = joinPoint.getSignature().getName();
		System.out.println("后置通知方法名: " + methodName + "  方法返回值不能取得。");
	}
	
	/**
	 * 在com.spring.apo.ArtthemticCalculator
	 * 的每一個方法執行之后 執行的處理
	 * 仅仅是正常终了
	 * 可以接受到返回值
	 * @param joinPoint
	 */
	@AfterReturning(value = "execution(public int com.spring.apo.ArtthemticCalculator.*(..))",
			 	returning="result")
	public void afterReturning(JoinPoint joinPoint,Object result){
		
		String methodName = joinPoint.getSignature().getName();
		System.out.println("返回通知方法名: " + methodName + "  方法返回值可以取得,且返回值为:" + result);
	}
	
	/**
	 * 在com.spring.apo.ArtthemticCalculator
	 * 的每一個方法執行之后 執行的處理
	 * 仅仅是異常终了
	 * 可以接受到返回值
	 * @param joinPoint
	 */
	@AfterThrowing(value = "execution(public int com.spring.apo.ArtthemticCalculator.*(..))",
			 	throwing="ex")
	public void afterThrowing(JoinPoint joinPoint,Exception ex){
		
		String methodName = joinPoint.getSignature().getName();
		System.out.println("異常通知方法名: " + methodName + "  方法異常終了,且異常为:" + ex);
	}
	/**
	 * 环绕通知
	 * 相当于动态代理
	 */
	@Around("execution(public int com.spring.apo.ArtthemticCalculator.*(..))")
	public Object aroundMethod(ProceedingJoinPoint pjp){
		
		Object result = null;
		String methodName = pjp.getSignature().getName();
		Object[] args = pjp.getArgs();
		
		try {
			
			System.out.println("【环绕通知】前置通知方法名: " + methodName + "  方法參數為:" + Arrays.asList(args));
			result = pjp.proceed();
			System.out.println("【环绕通知】返回通知方法名: " + methodName + "  方法返回值可以取得,且返回值为:" + result);
			
		} catch (Throwable e) {
			
			System.out.println("【环绕通知】異常通知方法名: " + methodName + "  方法異常終了,且異常为:" + e);
			e.printStackTrace();
		}finally{
			System.out.println("【环绕通知】后置通知方法名: " + methodName + "  方法返回值不能取得。");
		}
		
		return result;
	}
}

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	       http://www.springframework.org/schema/beans/spring-beans.xsd
		   http://www.springframework.org/schema/aop 
		   http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
		   http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-4.0.xsd">
	
	<!-- 配置自动扫描的包 -->
	<context:component-scan base-package="com.spring.apo"></context:component-scan>
	
<!-- 	<aop:aspect-autoproxy></aop:aspect-autoproxy> -->
<!-- 	<aop:aspectj-autoproxy /> -->
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

</beans>

测试类

package com.spring.apo;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Mainaop3 {

	public static void main(String[] args) {

		ApplicationContext atx = new ClassPathXmlApplicationContext("applicationContext.xml");
		ArtthemticCalculator target = (ArtthemticCalculator) atx.getBean("artthemticCalculator");
		
		System.out.println(target.getClass().getName());
		
		int result = target.add(3, 8);
//		System.out.println(result);
		System.out.println();
		
		result = target.sub(16, 8);
//		System.out.println(result);
		System.out.println();
		
		result = target.mul(16, 8);
//		System.out.println(result);
		System.out.println();
		
		result = target.div(72, 8);
//		System.out.println(result);
		System.out.println();
		
		// 異常測試
//		result = target.div(72, 0);
//		System.out.println();
	}
}

 

相关标签: spring 基础