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 ...
随机推荐
- Office开发必备知识----为什么要释放非托管Com资源
https://www.cnblogs.com/Charltsing/p/RealeaseComObject.html QQ:564955427 目前,国内Office插件开发的风头正盛,很多VBAe ...
- 用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建四:配置springmvc
在用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建三:配置spring并测试的基础上 继续进行springmvc的配置 一:配置完善web.xml文件
- request对象的方法及其参数的传递
先设计一个简单的登录界面index.htm: <html><head><title>request的使用</title></head>< ...
- POJ 1015 Jury Compromise(双塔dp)
Jury Compromise Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 33737 Accepted: 9109 ...
- Redis知识整理
Redis知识整理 转自:https://www.cnblogs.com/rjzheng/p/9096228.html 1.单线程模型 Redis客户端对服务端的每次调用都经历了发送命令,执行命令,返 ...
- VMWare的host-only/bridged/NAT连接图文介绍
1 VMware简介 VMWare虚拟机软件是一个“虚拟PC”软件,它使我们可以在一台机器上同时运行二个或更多Windows.Linux等系统. 如果我们需要使用多个系统的话,传统的方式有两种: .使 ...
- MySQL高可用——PXC简介
序言 Percona XtraDB Cluster(简称PXC集群)提供了MySQL高可用的一种实现方法. PXC属于一套近乎完美的mysql高可用集群解决方案,相比那些比较传统的基于主从复制模式的集 ...
- [再寄小读者之数学篇](2014-06-21 Beal-Kaot-Majda type logarithmic Sobolev inequality)
For $f\in H^s(\bbR^3)$ with $s>\cfrac{3}{2}$, we have $$\bex \sen{f}_{L^\infty}\leq C\sex{1+\sen{ ...
- [物理学与PDEs]第2章第2节 粘性流体力学方程组 2.5 粘性热传导流体动力学方程组的数学结构
1. 粘性热传导流体动力学方程组可化为 $$\beex \bea \cfrac{\p \rho}{\p t}&+({\bf u}\cdot\n)\rho=-\rho \Div{\bf u}, ...
- 滚动锚定(Scroll Anchoring)- 让视口内容不再因视口上方 DOM 元素的高度变化而产生跳动
不知道你有没有经历过这样的场景:当你打开一张“多图杀猫”的页面后,正一张图一张图边滚边看,在你刚准备定睛看某一张图的时候,这张图突然被它上面的内容挤到了视口下方,然后你赶紧把滚动条往下拉,试图追赶这张 ...