博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringAop通知
阅读量:5980 次
发布时间:2019-06-20

本文共 11037 字,大约阅读时间需要 36 分钟。

hot3.png

基于注解的方式实现通知

 

 

1.需要的jar包:

com.springsource.net.sf.cglib-2.2.0.jar

com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
commons-logging-1.1.1.jar
spring-aop-4.0.0.RELEASE.jar
spring-aspects-4.0.0.RELEASE.jar
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar

 

2.实现类:

注意:由于是使用注解的方式所以需要在实现类中添加注解

如下:

package com.atguigu.spring.aop;public interface ArithmeticCalculator {	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.atguigu.spring.aop;import org.springframework.stereotype.Component;@Component("arithmeticCalculator")public class ArithmeticCalculatorImpl implements ArithmeticCalculator {	@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;	}}

3.配置文件:

4.通知切面(1):

import java.util.Arrays;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.springframework.stereotype.Component;/** * AOP 的 helloWorld * 1. 加入 jar 包 * com.springsource.net.sf.cglib-2.2.0.jar * com.springsource.org.aopalliance-1.0.0.jar * com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar * spring-aspects-4.0.0.RELEASE.jar *  * 2. 在 Spring 的配置文件中加入 aop 的命名空间。  *  * 3. 基于注解的方式来使用 AOP * 3.1 在配置文件中配置自动扫描的包: 
* 3.2 加入使 AspjectJ 注解起作用的配置:
* 为匹配的类自动生成动态代理对象. * * 4. 编写切面类: * 4.1 一个一般的 Java 类 * 4.2 在其中添加要额外实现的功能. * * 5. 配置切面 * 5.1 切面必须是 IOC 中的 bean: 实际添加了 @Component 注解 * 5.2 声明是一个切面: 添加 @Aspect * 5.3 声明通知: 即额外加入功能对应的方法. * 5.3.1 前置通知: @Before("execution(public int com.atguigu.spring.aop.ArithmeticCalculator.*(int, int))") * @Before 表示在目标方法执行之前执行 @Before 标记的方法的方法体. * @Before 里面的是切入点表达式: * * 6. 在通知中访问连接细节: 可以在通知方法中添加 JoinPoint 类型的参数, 从中可以访问到方法的签名和方法的参数. * * 7. @After 表示后置通知: 在方法执行之后执行的代码. *///通过添加 @Aspect 注解声明一个 bean 是一个切面!@Aspect@Componentpublic class LoggingAspect { @Before("execution(public int com.atguigu.spring.aop.ArithmeticCalculator.*(int, int))") public void beforeMethod(JoinPoint joinPoint){ String methodName = joinPoint.getSignature().getName(); Object [] args = joinPoint.getArgs(); System.out.println("The method " + methodName + " begins with " + Arrays.asList(args)); } @After("execution(* com.atguigu.spring.aop.*.*(..))") public void afterMethod(JoinPoint joinPoint){ String methodName = joinPoint.getSignature().getName(); System.out.println("The method " + methodName + " ends"); } }

 

5.测试实现1:

 

package com.atguigu.spring.aop;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {		public static void main(String[] args) {				ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-aop.xml");		ArithmeticCalculator arithmeticCalculator = (ArithmeticCalculator) ctx.getBean("arithmeticCalculator");				System.out.println(arithmeticCalculator.getClass().getName());				int result = arithmeticCalculator.add(11, 12);		System.out.println("result:" + result);				result = arithmeticCalculator.div(21, 3);		System.out.println("result:" + result);	}	}

 

6.通知切面2及切面优先级:

package com.atguigu.spring.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;import org.springframework.core.annotation.Order;import org.springframework.stereotype.Component;/** * 可以使用 @Order 注解指定切面的优先级, 值越小优先级越高 */@Order(2)@Aspect@Componentpublic class LoggingAspect {		/**	 * 定义一个方法, 用于声明切入点表达式. 一般地, 该方法中再不需要添入其他的代码. 	 * 使用 @Pointcut 来声明切入点表达式. 	 * 后面的其他通知直接使用方法名来引用当前的切入点表达式. 	 */	@Pointcut("execution(public int com.atguigu.spring.aop.ArithmeticCalculator.*(..))")	public void declareJointPointExpression(){}		/**	 * 在 com.atguigu.spring.aop.ArithmeticCalculator 接口的每一个实现类的每一个方法开始之前执行一段代码	 */	@Before("declareJointPointExpression()")	public void beforeMethod(JoinPoint joinPoint){		String methodName = joinPoint.getSignature().getName();		Object [] args = joinPoint.getArgs();				System.out.println("The method " + methodName + " begins with " + Arrays.asList(args));	}		/**	 * 在方法执行之后执行的代码. 无论该方法是否出现异常	 */	@After("declareJointPointExpression()")	public void afterMethod(JoinPoint joinPoint){		String methodName = joinPoint.getSignature().getName();		System.out.println("The method " + methodName + " ends");	}		/**	 * 在方法法正常结束受执行的代码	 * 返回通知是可以访问到方法的返回值的!	 */	@AfterReturning(value="declareJointPointExpression()",			returning="result")	public void afterReturning(JoinPoint joinPoint, Object result){		String methodName = joinPoint.getSignature().getName();		System.out.println("The method " + methodName + " ends with " + result);	}		/**	 * 在目标方法出现异常时会执行的代码.	 * 可以访问到异常对象; 且可以指定在出现特定异常时在执行通知代码	 */	@AfterThrowing(value="declareJointPointExpression()",			throwing="e")	public void afterThrowing(JoinPoint joinPoint, Exception e){		String methodName = joinPoint.getSignature().getName();		System.out.println("The method " + methodName + " occurs excetion:" + e);	}		/**	 * 环绕通知需要携带 ProceedingJoinPoint 类型的参数. 	 * 环绕通知类似于动态代理的全过程: ProceedingJoinPoint 类型的参数可以决定是否执行目标方法.	 * 且环绕通知必须有返回值, 返回值即为目标方法的返回值	 */	/*	@Around("execution(public int com.atguigu.spring.aop.ArithmeticCalculator.*(..))")	public Object aroundMethod(ProceedingJoinPoint pjd){				Object result = null;		String methodName = pjd.getSignature().getName();				try {			//前置通知			System.out.println("The method " + methodName + " begins with " + Arrays.asList(pjd.getArgs()));			//执行目标方法			result = pjd.proceed();			//返回通知			System.out.println("The method " + methodName + " ends with " + result);		} catch (Throwable e) {			//异常通知			System.out.println("The method " + methodName + " occurs exception:" + e);			throw new RuntimeException(e);		}		//后置通知		System.out.println("The method " + methodName + " ends");				return result;	}	*/}
package com.atguigu.spring.aop;import java.util.Arrays;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.springframework.core.annotation.Order;import org.springframework.stereotype.Component;@Order(1)@Aspect@Componentpublic class VlidationAspect {	@Before("com.atguigu.spring.aop.LoggingAspect.declareJointPointExpression()")	public void validateArgs(JoinPoint joinPoint){		System.out.println("-->validate:" + Arrays.asList(joinPoint.getArgs()));	}	}

7测试2:

package com.atguigu.spring.aop;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {		public static void main(String[] args) {				ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");		ArithmeticCalculator arithmeticCalculator = (ArithmeticCalculator) ctx.getBean("arithmeticCalculator");				System.out.println(arithmeticCalculator.getClass().getName());				int result = arithmeticCalculator.add(1, 2);		System.out.println("result:" + result);				result = arithmeticCalculator.div(1000, 10);		System.out.println("result:" + result);	}	}

 

 

基于xml文件配置的方式

package com.atguigu.spring.aop.xml;public interface ArithmeticCalculator {	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.atguigu.spring.aop.xml;public class ArithmeticCalculatorImpl implements ArithmeticCalculator {	@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.atguigu.spring.aop.xml;import java.util.Arrays;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;public class LoggingAspect {		public void beforeMethod(JoinPoint joinPoint){		String methodName = joinPoint.getSignature().getName();		Object [] args = joinPoint.getArgs();				System.out.println("The method " + methodName + " begins with " + Arrays.asList(args));	}		public void afterMethod(JoinPoint joinPoint){		String methodName = joinPoint.getSignature().getName();		System.out.println("The method " + methodName + " ends");	}		public void afterReturning(JoinPoint joinPoint, Object result){		String methodName = joinPoint.getSignature().getName();		System.out.println("The method " + methodName + " ends with " + result);	}		public void afterThrowing(JoinPoint joinPoint, Exception e){		String methodName = joinPoint.getSignature().getName();		System.out.println("The method " + methodName + " occurs excetion:" + e);	}		@Around("execution(public int com.atguigu.spring.aop.ArithmeticCalculator.*(..))")	public Object aroundMethod(ProceedingJoinPoint pjd){				Object result = null;		String methodName = pjd.getSignature().getName();				try {			//前置通知			System.out.println("The method " + methodName + " begins with " + Arrays.asList(pjd.getArgs()));			//执行目标方法			result = pjd.proceed();			//返回通知			System.out.println("The method " + methodName + " ends with " + result);		} catch (Throwable e) {			//异常通知			System.out.println("The method " + methodName + " occurs exception:" + e);			throw new RuntimeException(e);		}		//后置通知		System.out.println("The method " + methodName + " ends");				return result;	}}package com.atguigu.spring.aop.xml;import java.util.Arrays;import org.aspectj.lang.JoinPoint;public class VlidationAspect {	public void validateArgs(JoinPoint joinPoint){		System.out.println("-->validate:" + Arrays.asList(joinPoint.getArgs()));	}	}package com.atguigu.spring.aop.xml;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {		public static void main(String[] args) {				ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-xml.xml");		ArithmeticCalculator arithmeticCalculator = (ArithmeticCalculator) ctx.getBean("arithmeticCalculator");				System.out.println(arithmeticCalculator.getClass().getName());				int result = arithmeticCalculator.add(1, 2);		System.out.println("result:" + result);				result = arithmeticCalculator.div(1000, 0);		System.out.println("result:" + result);	}	}

 

 

转载于:https://my.oschina.net/yabushan/blog/691503

你可能感兴趣的文章
中大型网站技术架构演变过程
查看>>
ARTS训练第三周
查看>>
vue中v-for循环如何将变量带入class的属性名中
查看>>
ceph学习笔记之七 数据平衡
查看>>
windows下的php的memcache扩展的安装及memcache最新下载地址
查看>>
YOLOv3: 训练自己的数据(绝对经典版本1)
查看>>
POJ 1150 The Last Non-zero Digit 《挑战程序设计竞赛》
查看>>
Could not find artifact com.sun:tools:jar:1.5.0 解决办法
查看>>
phpstorm xdebug remote配置
查看>>
引用与指针的区别
查看>>
pygtk笔记--2.1:布局容器,VBox、Hbox、Alignment
查看>>
dtree.js树的使用
查看>>
Springboot2.1.3 + redis 实现 cache序列化乱码问题
查看>>
python 异常处理
查看>>
线程什么时候需要同步,什么时候不需要同步?
查看>>
Struts2 自定义拦截器(方法拦截器)
查看>>
Linux服务器的那些性能参数指标
查看>>
BZOJ 2302: [HAOI2011]Problem c [DP 组合计数]
查看>>
Atitti 过程导向 vs 结果导向 attlax的策
查看>>
c++ 11开始语言本身和标准库支持并发编程
查看>>