spring学习(5)
【摘要】 切面对组件类(@component) 添加 @Aspect 注解,表示该类为切面类。增强类型前置通知切面方法注解 @Before 表示目标方法调用前,执行该切面方法。@Before("execution(* com.company.project.service.Meal.eat(..))")public void cook() { System.out.println("cook")...
切面
对组件类(@component) 添加 @Aspect
注解,表示该类为切面类。
增强类型
前置通知
切面方法注解 @Before
表示目标方法调用前,执行该切面方法。
@Before("execution(* com.company.project.service.Meal.eat(..))")
public void cook() {
System.out.println("cook");
}Copy to clipboardErrorCopied
后置通知
- 切面方法注解
@After
表示目标方法返回或抛出异常后,执行该切面方法。 - 切面方法注解
@AfterReturning
只在目标方法返回后,执行该切面方法。 - 切面方法注解
@AfterThrowing
只在目标方法抛出异常后,执行该切面方法。
@AfterReturning("execution(* com.company.project.service.Meal.eat(..))")
public void clean() {
System.out.println("clean");
}Copy to clipboardErrorCopied
环绕通知
切面方法注解 @Around
表示切面方法执行过程中,执行目标方法。
传入参数为 ProceedingJoinPoint 类对象,表示目标方法。在切面方法中调用其 proceed 方法来执行。
@Around("execution(* com.company.project.service.Meal.eat(..))")
public void party(ProceedingJoinPoint pj) {
try {
System.out.println("cook");
pj.proceed();
System.out.println("clean");
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}Copy to clipboardErrorCopied
切点声明
在切面方法中需要声明切面方法要切入的目标方法,execution 指示器是我们定义切点时最主要使用的指示器。
格式为: execution(返回数据类型 路径.类.方法(传入参数类型))
参数 | 功能 |
---|---|
execution(* com.company.project.service.Meal.eat(..)) |
执行 Meal 类的 eat 方法时切入 |
execution(* com.company.project.service.Meal.eat(int,String)) |
执行 Meal 类的 eat(int,String) 方法时切入 |
execution(* com.company.project.service.Meal.*(..)) |
执行 Meal 类的所有方法时切入 |
execution(* com.company.project.service.*.*(..)) |
执行 service 包内的任意方法时切入(不包含子包) |
execution(* com.company.project.service..*.*(..)) |
执行 service 包内的任意方法时切入(包含子包) |
execution(public * *(..)) |
执行所有目标类的所有 public 方法时切入 |
execution(* pre*(...)) |
执行所有目标类所有以 pre 为前缀的方法时切入 |
还有一些其他指示器:
参数 | 功能 |
---|---|
within(com.company.project.service.*) |
执行 service 包内的任意方法时切入 |
this(com.company.project.service.AccountService) |
执行实现 AccountService 接口的代理对象的任意方法时切入 |
target(com.company.project.service.AccountService) |
执行实现 AccountService 接口的目标对象的任意方法时切入 |
args(java.io.Serializable) |
任何一个只接受一个参数,并且运行时所传入的参数是 Serializable 接口的方法 |
- 多个匹配条件之间使用链接符连接:
&&
、||
、!
。 - within 指示器表示可以选择的包,bean 指示器可以在切点中选择 bean 。
如参数 execution(String com.company.project.service.test1.IBuy.buy(double)) && args(price) && bean(girl)
要求返回类型为 String ;参数类型为 double ;参数名为 price ;调用目标方法的 bean 名称为 girl 。
简化代码
对于类中要频繁要切入的目标方法,我们可以使用 @Pointcut
注解声明切点表达式,简化代码。
@Aspect
@Component
public class EatPlus {
@Pointcut("execution(* com.company.project.service.Meal.eat(..))")
public void point(){}
@Before("point()")
public void cook() {
System.out.println("cook");
}
@Around("point()")
public void party(ProceedingJoinPoint pj) {
try {
System.out.println("cook");
pj.proceed();
System.out.println("clean");
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
@Pointcut("execution(String com.company.project.service.Meal.eat(double)) && args(price) && bean(people)")
public void point2(double price) {
}
@Around("point2(price)")
public String pay(ProceedingJoinPoint pj, double price){
try {
pj.proceed();
if (price > 100) {
System.out.println("can not afford");
return "没有购买";
}
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return "购买";
}
}Copy to clipboardErrorCopied
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)