springaop(SpringAOP的介绍和使用方法)

发布时间:2025-12-10 23:01:53 浏览次数:1

一、AOP介绍

AOP ,面向切面编程,在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程。其实就是在代码运行,进行一定的包装,如在方法执行前、方法返回后、方法抛出异常后等地方进行一定的拦截处理或者叫增强处理

先讲一下AspectJ和Spring AOP关系,网上很多文章对AspectJ存在错误说法

AspectJ:

  • AspectJ 来自于 Eclipse 基金会,是Eclipse托管给Apache基金会的一个开源项目

  • 属于静态织入,它是通过修改代码来实现的,它的织入时机可以是:

    • Compile-time weaving:编译期织入

    • Post-compile weaving:也就是已经生成了 .class 文件,就要用到编译后织入

    • Load-time weaving:指的是在加载类的时候进行织入

  • AspectJ框架非常强大,它是 AOP 编程的完全解决方案。Spring AOP 致力于解决的是企业级开发中最普遍的 AOP 需求(方法织入)

  • AspectJ 在实际代码运行前完成了织入,所以大家会说它生成的类是没有额外运行时开销的

SpringAOP:

  • 基于动态代理来实现。默认地,如果使用接口的,用 JDK 提供的动态代理实现,如果没有接口,使用 CGLIB 实现

  • Spring AOP 和AspectJ并没有什么太多的关系,仅仅是Spring 延用了 AspectJ 中的概念,包括使用了 AspectJ 提供的 jar 包中的注解,但是不依赖于其实现功能

  • Spring AOP 需要依赖于 IOC 容器来管理,只能作用于 Spring 容器中的 Bean,它是使用纯粹的 Java 代码实现的,只能作用于 bean 的方法

  • Spring AOP 比 AspectJ 的性能稍差

二、Spring AOP术语解释

Joinpoint(连接点)
所谓连接点是指能够被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点(任何一个方法都可以称为连接点)

Pointcut(切入点)
切入点是指我们要对哪些Joinpoint进行拦截的定义(对哪个方法进行增强)

Advice(通知/增强)
通知是指拦截到Joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)(要给它增加什么功能)

Target(目标对象)
代理的目标对象

Weaving(织入)
是指把增强应用到目标对象来创建新的代理对象的过程(怎样得到代理对象)

Proxy(代理)
一个类被AOP织入增强后,就产生一个结果代理类

Aspect(切面)
是切入点和通知的结合,构成切面,我们可以使用注解或者xml进行配置

三、Spring AOP注解使用

1. 在 xml 中配置
开启 @AspectJ 的注解,还有其它方式,这里不介绍

<aop:aspectj-autoproxy/>

2. 使用@Aspect注解
定义实现AOP的配置类
@Aspect 注解要作用在 bean 上面

@Component@AspectpublicclassLogAspect{}

3. 配置 Pointcut
用于定义哪些方法需要被增强或者说需要被拦截

@Pointcut(""execution(*com.ljj.service(..))"")privatevoidcontrollerAspect(){//TODOAuto-generatedmethodstub}@Pointcut("@annotation(com.ljj.annotation.Log)")privatevoidcontrollerAspect1(){//TODOAuto-generatedmethodstub}@Pointcut(""within(com.ljj.service..*)"")privatevoidcontrollerAspect2(){//TODOAuto-generatedmethodstub}@Pointcut("bean(*Service)")privatevoidcontrollerAspect3(){//TODOAuto-generatedmethodstub}
  • execution ,正则匹配方法签名

  • @annotation。匹配对应注解的方法

  • within,指定所在类或所在包下面的方法

  • bean(idOrNameOfBean), 匹配 bean 的名字

4. 配置 Advice

@AspectpublicclassAdviceExample{//下面方法就是写拦截"dao层实现"@Before("com.ljj.aop.dataAccessOperation()")publicvoiddoAccessCheck(){//...实现代码}@Before("execution(*com.ljj.dao.*.*(..))")publicvoiddoAccessCheck(){//...实现代码}@AfterReturning("com.ljj.aop.dataAccessOperation()")publicvoiddoAccessCheck(){//...}@AfterReturning(pointcut="com.ljj.aop.dataAccessOperation()",returning="retVal")publicvoiddoAccessCheck(ObjectretVal){//这样,进来这个方法的处理时候,retVal就是相应方法的返回值,是不是非常方便//...实现代码}//异常返回@AfterThrowing("com.ljj.aop.dataAccessOperation()")publicvoiddoRecoveryActions(){//...实现代码}@AfterThrowing(pointcut="com.ljj.aop.dataAccessOperation()",throwing="ex")publicvoiddoRecoveryActions(DataAccessExceptionex){//...实现代码}//注意理解它和@AfterReturning之间的区别,这里会拦截正常返回和异常的情况@After("com.ljj.aop.dataAccessOperation()")publicvoiddoReleaseLock(){//通常就像finally块一样使用,用来释放资源。//无论正常返回还是异常退出,都会被拦截到}//既能做@Before的事情,也可以做@AfterReturning的事情@Around("com.ljj.businessService()")publicObjectdoBasicProfiling(ProceedingJoinPointpjp)throwsThrowable{//startstopwatchObjectretVal=pjp.proceed();//stopstopwatchreturnretVal;}}

上面Advice都已经匹配了对应的PointCut,这样定义可以不用再定义PointCut了。也可以使用下面这种PointCut + Advice

//定义日志注解@Target({ElementType.PARAMETER,ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic@interfaceLog{//操作名StringoptName();//操作类型OperateTypeoptType();//操作表名StringoptTable();//操作编码StringoptCode();}@Pointcut("@annotation(com.ljj.annotation.Log)")privatevoidcontrollerAspect(){//TODOAuto-generatedmethodstub}//日志切面@Around("controllerAspect()")publicObjectaround(ProceedingJoinPointpjp)throwsThrowable{try{//方法执行前操作result=point.proceed();//方法执行后操作}catch(Exceptione){e.printStackTrace();}}

到此,关于“SpringAOP的介绍和使用方法”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注本站网站,小编会继续努力为大家带来更多实用的文章!

springaop
需要做网站?需要网络推广?欢迎咨询客户经理 13272073477