@Aspect 注解使用详解
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"/>
————————————————
版权声明:本文为CSDN博主「狂丰」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/fz13768884254/article/details/83538709
@Aspect 注解使用详解的更多相关文章
- 转: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 ...
- Java注解(Annotation)详解
转: Java注解(Annotation)详解 幻海流心 2018.05.23 15:20 字数 1775 阅读 380评论 0喜欢 1 Java注解(Annotation)详解 1.Annotati ...
- springmvc常用注解标签详解
1.@Controller 在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model ...
- android注解使用详解(图文)
在使用Java的SSH框架的时候,一直在感叹注解真是方便啊,关于注解的原理,大家可以参考我的另一片文章Java注解详解.最近有时间研究了android注解的使用,今天与大家分享一下. android中 ...
- springmvc常用注解标签详解【转】
转载自:http://www.cnblogs.com/leskang/p/5445698.html 1.@Controller 在SpringMVC 中,控制器Controller 负责处理由Disp ...
- spring security 注解@EnableGlobalMethodSecurity详解
1.Spring Security默认是禁用注解的,要想开启注解,需要在继承WebSecurityConfigurerAdapter的类上加@EnableGlobalMethodSecurity注解 ...
随机推荐
- 2018ICPC 南京Problem J. Prime Game
题目: 题意:给出一个序列a1,⋯,ana1,⋯,an.fac(l,r)fac(l,r)为mul(l,r)mul(l,r)中不同质因数的个数. 请计算: ∑i=1n∑j ...
- P1308_统计单词数(JAVA语言)
题目描述 一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数. 现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给 ...
- go-ini入门教程
go-ini入门教程 go-ini简介 Package ini provides INI file read and write functionality in Go. 在实际开发时,配置信息一般不 ...
- Python | random 模块:Python 中如何生成随机数和随机抽样?
random 是平时开发过程中常用的一个模块,该模块实现了各种分布的伪随机数生成器,以及和随机数相关的各种实用函数.基本函数 random() 在区间 [0.0, 1.0) 内均匀生成随机浮点数,是模 ...
- 单链表c语言实现的形式
包括初始化,创建,查询,长度,删除,清空,销毁等操作 代码如下: #include<stdio.h> #include<stdlib.h> //定义单链表的数据类型 typed ...
- mysql 批量操作,已存在则修改,不存在则insert,同时判断空选择性写入字段
注:如果是批量插入需要在 Java 连接数据库的字串中设置 &allowMultiQueries=true 针对单行数据有则修改无则新增 本案例的建表语句是: -- auto-generate ...
- 201871010109-胡欢欢-实验一-软件工程的准备(初识github及《现代软件工程-构建之法》)
项目 内容 课程班级博客链接 2021年春软件工程课程班(2018级计算机科学与技术) 这个作业要求链接链接 实验一软件工程准备 我的课程学习目标 了解github的基本使用,学习markdown编辑 ...
- OO 第三单元
一.JML语言理论基础 JML 是用于对 Java 程序进行规格化设计的一种表示语言,为严格的程序设计提供了一套行之有效的方法. 我个人对于 JML 的几点看法: JML 的规格化设计相较于自然语言的 ...
- Java代码格式化规范实践总结
目标说明 统一良好的代码格式规范可以有效提升开发团队之间的「协作效率」,如果不同的开发团队或者开发人员采用不同的代码格式规范,那么每次Format代码都会导致大量的变化,在Code Review及Me ...
- Typescript进阶之路
TypeScript 何为TypeScript 一.编程语言类型 动态类型语言(Dynamically Typed Language) 类型的检查是在运行时才做 例子---JavaScript.Rub ...