热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

基于springAOP@Around@Before@After的区别说明

这篇文章主要介绍了基于springAOP@Around@Before@After的区别说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

此段小代码演示了spring aop中@Around @Before @After三个注解的区别

@Before是在所拦截方法执行之前执行一段逻辑。

@After 是在所拦截方法执行之后执行一段逻辑。

@Around是可以同时在所拦截方法的前后执行一段逻辑。

连接点(JoinPoint) 这个就更好解释了,就是spring允许你是通知(Advice)的地方,那可就真多了,基本每个方法的前、后(两者都有也行),或抛出异常是时都可以是连接点,spring只支持方法连接点。

其他如AspectJ还可以让你在构造器或属性注入时都行,不过那不是咱们关注的,只要记住,和方法有关的前前后后都是连接点。

package com.itsoft.action;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
/**
 * 
 * @author zxf
 * 演示aop测试类
 */
@Controller
public class UserAction {
 public void queryUsers(){
  System.out.println("查询所有用户【all users list】");
 }
 public static void main(String[] args) {
  ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("application-aop.xml");
  UserAction userAction = (UserAction)ctx.getBean("userAction");
  userAction.queryUsers();
  ctx.destroy();
 }
}
package com.itsoft;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
 * 
 * @author Administrator
 * 通过aop拦截后执行具体操作
 */
@Aspect
@Component
public class LogIntercept {
 @Pointcut("execution(public * com.itsoft.action..*.*(..))")
 public void recordLog(){}
 @Before("recordLog()")
 public void before() {
  this.printLog("已经记录下操作日志@Before 方法执行前");
 }
 @Around("recordLog()")
 public void around(ProceedingJoinPoint pjp) throws Throwable{
  this.printLog("已经记录下操作日志@Around 方法执行前");
  pjp.proceed();
  this.printLog("已经记录下操作日志@Around 方法执行后");
 }
 @After("recordLog()")
 public void after() {
  this.printLog("已经记录下操作日志@After 方法执行后");
 }
 private void printLog(String str){
  System.out.println(str);
 }
}
<&#63;xml version="1.0" encoding="UTF-8"&#63;>

 
 
 

补充:spring aop的@Before,@Around,@After,@AfterReturn,@AfterThrowing的理解

1.AOP的基本概念

切面(Aspect) :通知(advice)和切入点(pointcut)共同组成了切面(aspect),时间、地点和要发生的“故事”。

可以从注解方式来理解,代码如下。

@aspect为类上面的注解——切面

@pointcut(…)——切入点。为此类内一个空方法上面的注解。可以把拦截的地址表达式表示为方法签名,利于使用起来方便。

@before@after等——通知。为此类下面的方法上面的注解。

三者在一块组成一个切面。

@Aspect
public class ExampleAspect {
 @Pointcut("execution(* com.psjay.example.spring.aop.*.*(..))")
 public void aPointcut() {
 }
 @Before("aPointcut()")
 public void beforeAdvice() {
  System.out.println("before advice is executed!");
 }
}

连接点(Joinpoint) :程序能够应用通知的一个“时机”,这些“时机”就是连接点,例如方法被调用时、异常被抛出时等等。——可以理解为被aop拦截的类或者方法就是连接点。

通知(Advice) :通知定义了切面是什么以及何时使用。描述了切面要完成的工作和何时需要执行这个工作。——可以理解为被注解有@Before等advice注解的安全校验的方法,拦截了过来的请求要做什么逻辑的校验。

切入点(Pointcut) :通知定义了切面要发生的“故事”和时间,那么切入点就定义了“故事”发生的地点,例如某个类或方法的名称。——可以理解为切面切向哪里?是个类或者某层的包路径。

目标对象(Target Object) :即被通知的对象。

AOP代理(AOP Proxy) 在Spring AOP中有两种代理方式,JDK动态代理和CGLIB代理。默认情况下,TargetObject实现了接口时,则采用JDK动态代理;反之,采用CGLIB代理。

织入(Weaving)把切面应用到目标对象来创建新的代理对象的过程,织入一般发生在如下几个时机:

(1)编译时:当一个类文件被编译时进行织入,这需要特殊的编译器才能做到,例如AspectJ的织入编译器;

(2)类加载时:使用特殊的ClassLoader在目标类被加载到程序之前增强类的字节代码;

(3)运行时:切面在运行的某个时刻被织入,SpringAOP就是以这种方式织入切面的,原理是使用了JDK的动态代理。

2 通知(Advice)类型的说明

@Before 前置通知(Before advice) :在某连接点(JoinPoint)——核心代码(类或者方法)之前执行的通知,但这个通知不能阻止连接点前的执行。

为啥不能阻止线程进入核心代码呢?

因为@Before注解的方法入参不能传ProceedingJoinPoint,而只能传入JoinPoint。

要知道从aop走到核心代码就是通过调用ProceedingJionPoint的proceed()方法。

而JoinPoint没有这个方法。

这里牵扯区别这两个类:Proceedingjoinpoint 继承了 JoinPoint 。

是在JoinPoint的基础上暴露出 proceed 这个方法。proceed很重要,这个是aop代理链执行的方法。

暴露出这个方法,就能支持 aop:around 这种切面(而其他的几种切面只需要用到JoinPoint,这跟切面类型有关), 能决定是否走代理链还是走自己拦截的其他逻辑。

建议看一下 JdkDynamicAopProxy的invoke方法,了解一下代理链的执行原理。

这样你就能明白 proceed方法的重要性。

@After 后通知(After advice) :当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。

@AfterReturning 返回后通知(After return advice) :在某连接点正常完成后执行的通知,不包括抛出异常的情况。

@Around 环绕通知(Around advice) :包围一个连接点的通知,类似Web中Servlet规范中的Filter的doFilter方法。

可以在方法的调用前后完成自定义的行为,也可以选择不执行。

这时aop的最重要的,最常用的注解。

用这个注解的方法入参传的是ProceedingJionPoint pjp,可以决定当前线程能否进入核心方法中——通过调用pjp.proceed();

@AfterThrowing 抛出异常后通知(After throwing advice) : 在方法抛出异常退出时执行的通知。

3 advice(通知)注解的执行先后顺序

这里说下简单情况——针对一个方法只被一个aspect类拦截时,aspect类内部的 advice 将按照以下的顺序进行执行情况如下:

解释:执行到核心业务方法或者类时,会先执行AOP。在aop的逻辑内,先走@Around注解的方法。

然后是@Before注解的方法,然后这两个都通过了,走核心代码,核心代码走完,无论核心有没有返回值,都会走@After方法。

然后如果程序无异常,正常返回就走@AfterReturn,有异常就走@AfterThrowing。

复杂的同一个方法被多个Aspect类拦截请参看博文:Spring AOP @Before @Around @After 等 advice 的执行顺序。

4 在aop中校验不通过如何不让程序进入核心代码?

通过aop中注解的执行的先后顺序我们知道,校验发生在核心代码前面的只剩下两个——@Before,@Around。

@Before : 这个注解只有在异常时才不会走核心方法——连接点。正常@Before无法阻止当前线程进入连接点。

@Around : 这个注解在连接点前后执行。并且注解的方法传入的ProceedingJionPoint 类中封装的代理方法proceed()可以让当前线程从aop方法转到连接点——核心代码方法。

所以一般我们用这个注解,如果aop的安全校验不通过,则不调用proceed()方法,就永远不会进入连接点。

除此外,要注意除了Around注解的方法可以传ProceedingJionPoint 外,别的几个都不能传这个类。

但是普通的数据类型是不限制的。

注解的方法的返回值也不限制,可以自由限制。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。如有错误或未考虑完全的地方,望不吝赐教。


推荐阅读
  • 《Spring in Action 第4版:全面解析与实战指南》
    《Spring in Action 第4版:全面解析与实战指南》不仅详细介绍了Spring框架的核心优势,如简洁易测试、低耦合特性,还深入探讨了其轻量级和最小侵入性的设计原则。书中强调了声明式编程的优势,并通过基于约定的方法简化开发流程。此外,Spring的模板机制有效减少了重复代码,而依赖注入功能则由容器自动管理,确保了应用的灵活性和可维护性。 ... [详细]
  • 在更换电脑或重装系统时,用户经常需要处理诸如备份收藏夹、电子邮件、用户配置文件和常用文档等任务。尽管这些操作并不复杂,但却相当繁琐。本文介绍了一种利用Windows 7中的“轻松传送”功能,高效便捷地在两台电脑之间同步数据的方法,大大简化了这一过程。 ... [详细]
  • 在当前的软件开发领域,Lua 作为一种轻量级脚本语言,在 .NET 生态系统中的应用逐渐受到关注。本文探讨了 Lua 在 .NET 环境下的集成方法及其面临的挑战,包括性能优化、互操作性和生态支持等方面。尽管存在一定的技术障碍,但通过不断的学习和实践,开发者能够克服这些困难,拓展 Lua 在 .NET 中的应用场景。 ... [详细]
  • 深入解析C#中app.config文件的配置与修改方法
    在C#开发过程中,经常需要对系统的配置文件进行读写操作,如系统初始化参数的修改或运行时参数的更新。本文将详细介绍如何在C#中正确配置和修改app.config文件,包括其结构、常见用法以及最佳实践。此外,还将探讨exe.config文件的生成机制及其在不同环境下的应用,帮助开发者更好地管理和维护应用程序的配置信息。 ... [详细]
  • 在探讨Hibernate框架的高级特性时,缓存机制和懒加载策略是提升数据操作效率的关键要素。缓存策略能够显著减少数据库访问次数,从而提高应用性能,特别是在处理频繁访问的数据时。Hibernate提供了多层次的缓存支持,包括一级缓存和二级缓存,以满足不同场景下的需求。懒加载策略则通过按需加载关联对象,进一步优化了资源利用和响应时间。本文将深入分析这些机制的实现原理及其最佳实践。 ... [详细]
  • REST与RPC:选择哪种API架构风格?
    在探讨REST与RPC这两种API架构风格的选择时,本文首先介绍了RPC(远程过程调用)的概念。RPC允许客户端通过网络调用远程服务器上的函数或方法,从而实现分布式系统的功能调用。相比之下,REST(Representational State Transfer)则基于资源的交互模型,通过HTTP协议进行数据传输和操作。本文将详细分析两种架构风格的特点、适用场景及其优缺点,帮助开发者根据具体需求做出合适的选择。 ... [详细]
  • 在使用SSH框架进行项目开发时,经常会遇到一些常见的问题。例如,在Spring配置文件中配置AOP事务声明后,进行单元测试时可能会出现“No Hibernate Session bound to thread”的错误。本文将详细探讨这一问题的原因,并提供有效的解决方案,帮助开发者顺利解决此类问题。 ... [详细]
  • Spring框架的核心组件与架构解析 ... [详细]
  • 在前文探讨了Spring如何为特定的bean选择合适的通知器后,本文将进一步深入分析Spring AOP框架中代理对象的生成机制。具体而言,我们将详细解析如何通过代理技术将通知器(Advisor)中包含的通知(Advice)应用到目标bean上,以实现切面编程的核心功能。 ... [详细]
  • 本文详细介绍了如何安全地手动卸载Exchange Server 2003,以确保系统的稳定性和数据的完整性。根据微软官方支持文档(https://support.microsoft.com/kb833396/zh-cn),在进行卸载操作前,需要特别注意备份重要数据,并遵循一系列严格的步骤,以避免对现有网络环境造成不利影响。此外,文章还提供了详细的故障排除指南,帮助管理员在遇到问题时能够迅速解决,确保整个卸载过程顺利进行。 ... [详细]
  • 隐藏的威胁:你的供应链是否真正安全?
    在网络环境日益复杂的当下,诸如网络钓鱼、DNS欺骗、勒索软件和中间人(MITM)攻击等威胁手段已司空见惯。这些攻击手段无孔不入,对供应链的安全构成了严重挑战。企业必须加强安全意识,采取多层次的防护措施,以确保供应链的每一个环节都得到有效保护。 ... [详细]
  • 本文作为“实现简易版Spring系列”的第五篇,继前文深入探讨了Spring框架的核心技术之一——控制反转(IoC)之后,将重点转向另一个关键技术——面向切面编程(AOP)。对于使用Spring框架进行开发的开发者来说,AOP是一个不可或缺的概念。了解AOP的背景及其基本原理,对于掌握这一技术至关重要。本文将通过具体示例,详细解析AOP的实现机制,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 掌握PHP框架开发与应用的核心知识点:构建高效PHP框架所需的技术与能力综述
    掌握PHP框架开发与应用的核心知识点对于构建高效PHP框架至关重要。本文综述了开发PHP框架所需的关键技术和能力,包括但不限于对PHP语言的深入理解、设计模式的应用、数据库操作、安全性措施以及性能优化等方面。对于初学者而言,熟悉主流框架如Laravel、Symfony等的实际应用场景,有助于更好地理解和掌握自定义框架开发的精髓。 ... [详细]
  • Spring框架入门指南:专为新手打造的详细学习笔记
    Spring框架是Java Web开发中广泛应用的轻量级应用框架,以其卓越的功能和出色的性能赢得了广大开发者的青睐。本文为初学者提供了详尽的学习指南,涵盖基础概念、核心组件及实际应用案例,帮助新手快速掌握Spring框架的核心技术与实践技巧。 ... [详细]
  • PHP连接MySQL的三种方法及预处理语句防止SQL注入的技术详解
    PHP连接MySQL的三种方法及预处理语句防止SQL注入的技术详解 ... [详细]
author-avatar
我爱你可你不懂_516
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有