Spring 使用AspectJ 实现 AOP(基于xml文件)

开发配置:Eclipse + jdk 1.8 + Tomcat 7.0

Spring AOP自身也有一个实现aop的框架,但这里使用的是AspectJ来实现aop。

使用AspectJ来实现aop有两种方法,一种是注解的方式,另一种是xml的方式,这里说的是基于xml的方式。

知道了基于注解的aop后,理解xml配置会更容易,Spring 使用AspectJ 实现 AOP(基于注解)

AOP有五种通知,分别是

@Befor:前置通知,在方法执行之前执行  
@After:后置通知,在方法执行之后执行  
@AfterRunning:返回通知,在方法返回结果之后执行  
@AfterThrowing:异常通知,在方法抛出异常之后执行  
@Around:环绕通知,围绕着方法执行  

项目结构:


一、需要的jar包:

这三个是AspectJ的jar包:
aopalliance-1.0.jar
aspectjweaver-1.9.0.jar
spring-aspects-4.3.8.RELEASE.jar

这些事spring的核心包:
commons-logging-1.2.jar
spring-aop-4.3.8.RELEASE.jar
spring-beans-4.3.8.RELEASE.jar
spring-context-4.3.8.RELEASE.jar
spring-core-4.3.8.RELEASE.jar

spring-expression-4.3.8.RELEASE.jar

二、bean-xml.xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop.xsd 
    http://www.springframework.org/schema/tx       
    http://www.springframework.org/schema/tx/spring-tx.xsd ">
    
    <!-- 扫描com.qw.apo.impl包及其子包下面的所有的类的注解 -->
	<context:component-scan base-package="com.qw.aop.xml"/>
    
	<!-- 配置AOP -->
	<aop:config>
		<!-- 配置切点表达式,可以定义多个,只要id不同就可以 -->
		<aop:pointcut expression="execution(* com.qw.aop.xml.AtithmeticCalculator.*(int, int))" id="pointcut"/>
		
		<!-- 配置切面及通知,可以定义多个切面 -->
		<aop:aspect ref="loggingAspect" order="2"><!-- ref:指向切面     order:切面的优先级,越小优先级又高 -->
			<!-- 前置通知 method:切面里面的方法 pointcut-ref:使用的切点表达式-->
			<aop:before method="beforeMethod" pointcut-ref="pointcut"/>
			<!-- 后置通知 -->
			<aop:after method="afterMethod" pointcut-ref="pointcut"/>
			<!-- 返回通知 returning:返回的值,与方法中的返回值一样-->
			<aop:after-returning method="afterRunning" pointcut-ref="pointcut" returning="result"/>
			<!-- 异常通知 throwing:抛出异常,与方法中一样-->
			<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="ex"/>
			
			<!-- 环绕通知,很少用 -->
			<aop:around method="around" pointcut-ref="pointcut"/>
		</aop:aspect>
	</aop:config>
	
</beans>

三、接口类、接口实现类、切面类、测试类

接口类:AtithmeticCalculator

package com.qw.aop.xml;

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

接口实现类:AtithmeticCalculatorImpl

package com.qw.aop.xml;

import org.springframework.stereotype.Component;

@Component
public class AtithmeticCalculatorImpl implements AtithmeticCalculator {

	@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 div(int i, int j) {
		int result = i / j;
		return result;
	}

}

切面类:LoggingAspect

package com.qw.aop.xml;

import java.util.Arrays;
import java.util.List;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.stereotype.Component;

@Component
public class LoggingAspect {
	
	
	public void beforeMethod(JoinPoint joinPoint){
		//执行的方法名
		String methodName = joinPoint.getSignature().getName();
		//执行的方法的参数
		List<Object> args = Arrays.asList(joinPoint.getArgs());
		
		//执行的方法所在的类的名称
		String className = joinPoint.getTarget().getClass().getName();
		
		System.out.println("前置通知,执行的方法名:"+ methodName + ",方法的参数:"+ args + ",方法所在的类名:" + className);
	}
	
	
	public void afterMethod(JoinPoint joinPoint){
		//执行的方法名
		String methodName = joinPoint.getSignature().getName();
		//执行的方法的参数
		List<Object> args = Arrays.asList(joinPoint.getArgs());
		
		System.out.println("后置通知,执行的方法名:"+ methodName + ",方法的参数:"+ args);
	}
	
	public void afterRunning(JoinPoint joinPoint,Object result){
		//执行的方法名
		String methodName = joinPoint.getSignature().getName();
		//执行的方法的参数
		List<Object> args = Arrays.asList(joinPoint.getArgs());
		
		System.out.println("返回通知,执行的方法名:"+ methodName + ",方法的参数:"+ args +",返回值是:"+result);
	}
	
	public void afterThrowing(JoinPoint joinPoint,Exception ex){
		//执行的方法名
		String methodName = joinPoint.getSignature().getName();
		//执行的方法的参数
		List<Object> args = Arrays.asList(joinPoint.getArgs());
		
		System.out.println("异常通知,执行的方法名:"+ methodName + ",方法的参数:"+ args + ",异常:"+ex);
	}
	
	public Object around(ProceedingJoinPoint pjd){
		Object result = null;
		
		try {
			//前置通知
			System.out.println("前置通知:"+pjd.getSignature().getName());
			//执行目标方法
			result = pjd.proceed();
			//返回通知
			System.out.println("返回通知:"+pjd.getSignature().getName());
		} catch (Throwable e) {
			//异常通知
			System.out.println("异常通知:"+pjd.getSignature().getName() + ",异常:" + e);
			throw new RuntimeException(e);
		}
		//后置通知
		System.out.println("后置通知:"+pjd.getSignature().getName());
		
		return result;
	}
}

测试类:Main

package com.qw.aop.xml;

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

public class Main {
	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("bean-xml.xml");
		AtithmeticCalculator calculator = context.getBean(AtithmeticCalculator.class);
		int result = calculator.add(1, 4);
		System.out.println("result:"+result);
		result = calculator.sub(1, 4);
		System.out.println("result:"+result);

		result = calculator.div(1, 1);
		System.out.println("result:"+result);
	}
}

源码,关于Spring 使用AspectJ实现AOP的基于注解和基于xml文件的,都在

https://download.csdn.net/download/java_xuetu/10358660


猜你喜欢

转载自blog.csdn.net/java_xuetu/article/details/79997491