欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > Spring的AOP

Spring的AOP

2025/3/25 15:51:07 来源:https://blog.csdn.net/Runner__Binger/article/details/146447929  浏览:    关键词:Spring的AOP

如下图,展示了Spring的大体框架。本文将详细介绍Spring框架中的AOP(面向切面编程)机制及其应用。

依赖注入就是给对象赋值,依赖注入是通过容器为对象动态赋值的一种设计模式

IOC(控制反转)将对象的创建与管理交由Spring框架处理,其底层机制依赖于反射技术。

AOP(面向切面编程)无需改动原有代码即可增强功能,提升系统的模块化和可维护性,其底层机制依赖于代理技术

AOP核心概念

AOP(面向切面编程)的核心概念包括以下几个关键术语:

1.Joinpoint(连接点):在类中,所有可以被增强的方法都称为连接点。这些方法是AOP能够拦截和增强的目标。

2.Pointcut(切入点):切入点是用于定义哪些连接点需要被拦截的规则。通过表达式或配置,指定具体哪些方法需要被增强。

3.Advice(通知/增强):通知是指在拦截到连接点后执行的具体操作。通知分为以下几种类型:

  • 前置通知(Before):在目标方法执行之前执行。
  • 后置通知(AfterReturning):在目标方法成功执行后执行。
  • 异常通知(AfterThrowing):在目标方法抛出异常时执行。
  • 最终通知(After):在目标方法执行完成后执行,无论是否抛出异常。
  • 环绕通知(Around):在目标方法执行前后都执行,可以控制目标方法的执行过程。

4.Aspect(切面):切面是切入点和通知的结合体,定义了在何处(切入点)以及如何(通知)增强目标方法。切面是开发者编写和配置的核心部分,用于实现横切关注点的模块化。

下面介绍AOP的通知,有XML和注解两种实现方式

利用XML的方式

前置通知

前置通知(Before Advice)在目标方法执行之前执行,通常用于权限检查、日志记录等。

例子(希望在登录前做权限认证):

Spring.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"><bean id="login" class="com.qcby.Login"/><bean id="auth" class="com.qcby.Authorization"/><!--配置切面--><aop:config><!--配置切面 = 切入点 + 通知组成--><aop:aspect ref="auth"><!--前置通知:UserServiceImpl的save方法执行前,会增强--><!--pointcut:后边是切入点表达式,作用是知道对对面的那个方法进行增强--><aop:before method="authorization" pointcut="execution(public void com.qcby.Login.login())"/><!--pointcut有简写格式,不过一般不简写--></aop:aspect></aop:config></beans>

Login:

package com.qcby;public class Login {public void login(){System.out.println("登录成功");}
}

Authorization:

package com.qcby;public class Authorization {public void authorization(){System.out.println("进行权限认证");}
}

LoginTest:

public class LoginTest {@Testpublic void test(){ApplicationContext ac=new ClassPathXmlApplicationContext("Spring.xml");Login log=(Login) ac.getBean("login");log.login();}
}

结果:

最终通知和后置通知

最终通知(After (Finally) Advice),在目标方法执行结束后执行,无论是否抛出异常,通常用于资源清理、日志记录等。

后置通知(After Returning Advice)在目标方法成功执行并返回结果后执行,通常用于日志记录、结果处理等。

Login:

package com.qcby;public class Login {public void login(String name,String password){int n=10/0;//这样login运行出错System.out.println("登录成功");}
}

spring.xml:

<!--配置切面--><aop:config><!--配置切面 = 切入点 + 通知组成--><aop:aspect ref="auth"><!--最终通知--><!--pointcut:后边是切入点表达式,作用是知道对对面的那个方法进行增强--><aop:after method="authorization" pointcut="execution(public void com.qcby.Login.login(..))"/></aop:aspect></aop:config>

结果:

after是最终通知,after-returning是后置通知(切入点执行成功后才会执行),after-returning如果配置出错不会运行,而after在前面代码出错的情况下依然会进行通知

异常通知

只有在切入点异常的情况下才会通知

异常通知(After Throwing Advice)在目标方法抛出异常后执行,通常用于异常处理、日志记录等。

环绕通知

环绕通知(Around Advice)在目标方法执行前后都执行,可以控制目标方法的执行,通常用于事务管理、性能监控等。

Authorization:

package com.qcby;import org.aspectj.lang.ProceedingJoinPoint;public class Authorization {public void authorization(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println("在方法执行之前进行权限认证");proceedingJoinPoint.proceed();System.out.println("在方法执行之后进行权限认证");}
}

结果:

利用注释的方式

Spring.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!--开启注解扫描--><context:component-scan base-package="com.qcby"/><!--开启Aspect生成代理对象--><aop:aspectj-autoproxy/>
</beans>

Authorization:

package com.qcby;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;@Component
@Aspect
public class Authorization {
//    @Before(value = "execution(public void com.qcby.Login.login(..))")
//    public void authorization(){
//        System.out.println("进行权限认证");
//    }
//    @AfterReturning(value = "execution(public void com.qcby.Login.login(..))")
//    public void authorization(){
//        System.out.println("进行权限认证");
//    }@Around(value = "execution(public void com.qcby.Login.login(..))")public void authorization(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println("在方法执行之前进行权限认证");proceedingJoinPoint.proceed();System.out.println("在方法执行之后进行权限认证");}
}

Login:

package com.qcby;import org.springframework.stereotype.Component;@Component
public class Login {public void login(String name,String password){
//        int n=10/0;//这样login运行出错System.out.println("登录成功");}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词