AOP注解使用详解
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
在spring AOP中业务逻辑仅仅只关注业务本身,将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。
相关注解介绍:
@Aspect:作用是把当前类标识为一个切面供容器读取 @Pointcut:Pointcut是植入Advice的触发条件。每个Pointcut的定义包括2部分,一是表达式,二是方法签名。 方法签名必须是 public及void型。可以将Pointcut中的方法看作是一个被Advice引用的助记符,因为表达式不直观,因此我们可以通过方法签名的方式为 此表达式命名。 因此Pointcut中的方法只需要方法签名,而不需要在方法体内编写实际代码。 @Around:环绕增强,相当于MethodInterceptor @AfterReturning:后置增强,相当于AfterReturningAdvice,方法正常退出时执行 @Before:标识一个前置增强方法,相当于BeforeAdvice的功能,相似功能的还有 @AfterThrowing:异常抛出增强,相当于ThrowsAdvice @After: final增强,不管是抛出异常或者正常退出都会执行
使用pointcut代码:
package com.aspectj.test.advice; 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.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect public class AdviceTest { @Around("execution(* com.abc.service.*.many*(..))") public Object process(ProceedingJoinPoint point) throws Throwable { System.out.println("@Around:执行目标方法之前..."); //访问目标方法的参数: Object[] args = point.getArgs(); if (args != null && args.length > 0 && args[0].getClass() == String.class) { args[0] = "改变后的参数1"; } //用改变后的参数执行目标方法 Object returnValue = point.proceed(args); System.out.println("@Around:执行目标方法之后..."); System.out.println("@Around:被织入的目标对象为:" + point.getTarget()); return "原返回值:" + returnValue + ",这是返回结果的后缀"; } @Before("execution(* com.abc.service.*.many*(..))") public void permissionCheck(JoinPoint point) { System.out.println("@Before:模拟权限检查..."); System.out.println("@Before:目标方法为:" + point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName()); System.out.println("@Before:参数为:" + Arrays.toString(point.getArgs())); System.out.println("@Before:被织入的目标对象为:" + point.getTarget()); } @AfterReturning(pointcut="execution(* com.abc.service.*.many*(..))", returning="returnValue") public void log(JoinPoint point, Object returnValue) { System.out.println("@AfterReturning:模拟日志记录功能..."); System.out.println("@AfterReturning:目标方法为:" + point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName()); System.out.println("@AfterReturning:参数为:" + Arrays.toString(point.getArgs())); System.out.println("@AfterReturning:返回值为:" + returnValue); System.out.println("@AfterReturning:被织入的目标对象为:" + point.getTarget()); } @After("execution(* com.abc.service.*.many*(..))") public void releaseResource(JoinPoint point) { System.out.println("@After:模拟释放资源..."); System.out.println("@After:目标方法为:" + point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName()); System.out.println("@After:参数为:" + Arrays.toString(point.getArgs())); System.out.println("@After:被织入的目标对象为:" + point.getTarget()); } }
使用annotation代码:
//注解实体类 package com.trip.demo; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.METHOD }) public @interface SMSAndMailSender { /*短信模板String格式化串*/ String value() default ""; String smsContent() default ""; String mailContent() default ""; /*是否激活发送功能*/ boolean isActive() default true; /*主题*/ String subject() default ""; } //切面类 @Aspect @Component("smsAndMailSenderMonitor") public class SMSAndMailSenderMonitor { private Logger logger = LoggerFactory.getLogger(SMSAndMailSenderMonitor.class); /** * 在所有标记了@SMSAndMailSender的方法中切入 * @param joinPoint * @param result */ @AfterReturning(value="@annotation(com.trip.demo.SMSAndMailSender)", returning="result")//有注解标记的方法,执行该后置返回 public void afterReturning(JoinPoint joinPoint , Object result//注解标注的方法返回值) { MethodSignature ms = (MethodSignature) joinPoint.getSignature(); Method method = ms.getMethod(); boolean active = method.getAnnotation(SMSAndMailSender.class).isActive(); if (!active) { return; } String smsContent = method.getAnnotation(SMSAndMailSender.class).smsContent(); String mailContent = method.getAnnotation(SMSAndMailSender.class).mailContent(); String subject = method.getAnnotation(SMSAndMailSender.class).subject(); } /** * 在抛出异常时使用 * @param joinPoint * @param ex */ @AfterThrowing(value="@annotation(com.jd.trip.hotel.ebooking.order.monitor.SMSAndMailSender)",throwing = "ex") public void afterThrowing(JoinPoint joinPoint, Throwable ex//注解标注的方法抛出的异常) { MethodSignature ms = (MethodSignature) joinPoint.getSignature(); Method method = ms.getMethod(); String subject = method.getAnnotation(SMSAndMailSender.class).subject(); } } //实体类中使用该注解标注方法 @Service("testService ") public class TestService { @Override @SMSAndMailSender(smsContent = "MODEL_SUBMIT_SMS", mailContent = "MODEL_SUPPLIER_EMAIL", subject = "MODEL_SUBJECT_EMAIL") public String test(String param) { return "success"; } }
注意,记得在配置文件中加上:
<aop:aspectj-autoproxy proxy-target-class="true"/> 文章转载至:https://blog.csdn.net/fz13768884254/article/details/83538709
AOP注解使用详解的更多相关文章
- Spring框架系列(9) - Spring AOP实现原理详解之AOP切面的实现
前文,我们分析了Spring IOC的初始化过程和Bean的生命周期等,而Spring AOP也是基于IOC的Bean加载来实现的.本文主要介绍Spring AOP原理解析的切面实现过程(将切面类的所 ...
- Spring框架系列(10) - Spring AOP实现原理详解之AOP代理的创建
上文我们介绍了Spring AOP原理解析的切面实现过程(将切面类的所有切面方法根据使用的注解生成对应Advice,并将Advice连同切入点匹配器和切面类等信息一并封装到Advisor).本文在此基 ...
- Spring框架系列(11) - Spring AOP实现原理详解之Cglib代理实现
我们在前文中已经介绍了SpringAOP的切面实现和创建动态代理的过程,那么动态代理是如何工作的呢?本文主要介绍Cglib动态代理的案例和SpringAOP实现的原理.@pdai Spring框架系列 ...
- Spring框架系列(12) - Spring AOP实现原理详解之JDK代理实现
上文我们学习了SpringAOP Cglib动态代理的实现,本文主要是SpringAOP JDK动态代理的案例和实现部分.@pdai Spring框架系列(12) - Spring AOP实现原理详解 ...
- Spring Aop底层原理详解
Spring Aop底层原理详解(来源于csdn:https://blog.csdn.net/baomw)
- 转:springmvc常用注解标签详解
Spring5:@Autowired注解.@Resource注解和@Service注解 - IT·达人 - 博客园--这篇顺序渐进,讲得超级好--此人博客很不错http://www.cnblogs.c ...
- Java 注解用法详解——@SuppressWarnings
转自: https://www.cnblogs.com/fsjohnhuang/p/4040785.html Java魔法堂:注解用法详解——@SuppressWarnings 一.前言 编码时我 ...
- @SuppressWarnings注解用法详解
@SuppressWarnings注解用法详解 今天来谈谈@SuppressWarnings注解的作用. J2SE 提供的最后一个批注是 @SuppressWarnings.该批注的作用是给编译器一条 ...
- Spring 注解@Value详解
一.spring(基础10) 注解@Value详解[1] 一 配置方式 @value需要参数,这里参数可以是两种形式: [html] view plain copy @Value("#{co ...
随机推荐
- JS 设计模式一 -- 原型模式
原型模式 概念: 原型模式 是指原型实例指向创建对象的种类,并通过拷贝这些原型创建新的对象,是一种用来创建对象的模式,也就是创建一个对象作为另一个对象的prototype属性. 实现原型模式: 方法一 ...
- 为什么重写了equals() 就要重写hashcode()
规定:1.两个对象相等,则hashcode也一定是相等的:2.两个对象相等,对两个对象分别调用equals()都返回 true:3.两个对象有相同的hashcode,但不一定相等 为什么重写了equa ...
- CGPoint、CGSize、CGRect、CGRectEdge的详细使用
http://blog.sina.com.cn/s/blog_953e22700101r7lz.html 在CGGeometry.h里的 CGPoint.CGSize.CGRect.CGRectEdg ...
- 在Linux上安装ant环境
原文链接:http://www.cnblogs.com/sell/archive/2013/07/24/3210198.html 1.从http://ant.apache.org 上下载tar.gz版 ...
- 删除a表中和b表相同的数据
删除a表中和b表相同的数据 - 冯索的专栏 - CSDN博客https://blog.csdn.net/wugouzi/article/details/9374329 oracle 查找A表存在B表不 ...
- CodeForces 280B Maximum Xor Se
题目链接:http://codeforces.com/contest/280/problem/B 题目大意: 给定一个由n个数组成的一个序列,s[l..r] (1 ≤ l < r ≤ n)代表原 ...
- wepy项目创建
全局安装wepy npm install wepy-cli -g 创建项目 wepy init standard mywepy 安装依赖 npm install 实时编译 wepy build --w ...
- Ajax提交表单初接触
<!doctype html> <html class="no-js"> <head> <meta charset="utf-8 ...
- JQuery的Ajax技术
jquery是一个优秀的js框架,自然对js原生的ajax进行了封装, 封装后的ajax的操作方法更简洁,功能更强大,与ajax操作 相关的jquery方法有如下几种: Ajax 请求 $.ajax( ...
- Super Mario HDU - 4417 (主席树)
Mario is world-famous plumber. His “burly” figure and amazing jumping ability reminded in our memory ...