Spring学习笔记-AOP(注解)

AOP配置 

myAdvice的bean在注解中用 @Component

将AopAdvice类配置成切面,就将@Aspect放在AopAdvice类上

关于切入点的配置使用注解@Pointcut("表达式") ,写一个空方法pt(),用来标记切入点!

再使用@Before("pt()")注解,标记相应的方法。

问:为什么要使用一个空方法呢?不能标记变量来表示切入点吗?

如果使用变量来标记切入点,存在内存空间的浪费,而使用空的方法,综合考虑对于内存的开销是最小的

最后,在XML使用<aop:aspectj-autoproxy>开启注解驱动的支持,换而言之,就是在XML中写了这句话,@Aspect、@Pointcut、@Before才可以正常使用。

所以到最后就变成了下图:

注解开发AOP制作步骤

在XML格式基础上

  • 导入坐标(伴随spring-context坐标导入已经依赖导入完成)

  • 开启AOP注解支持(容易忘记)

  • 配置切面@Aspect

  • 定义专用的切入点方法,并配置切入点@Pointcut

  • 为通知方法配置通知类型及对应切入点@Before

案例代码

applicationContext.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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.Harmony"/>
    <!-- 开启AOP注解支持-->
    <aop:aspectj-autoproxy/>

</beans>

UserServiceImpl实现类

@Service("userService")
public class UserServiceImpl implements UserService {

    public int save(int i, int m) {
        System.out.println("user service running..." + " " + i + " " + m);
        return 100;
    }
}

UserApp

public class UserApp {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) ctx.getBean("userService");
        int ret = userService.save(666,888);
        System.out.println("应用程序调用执行结果..." + ret);
    }
}

 AOPAdvice

@Component
@Aspect
public class AOPAdvice {

    @Pointcut("execution(* *(..))")
    public void pt() {}

    @Before("pt()")
    public void before() {
        System.out.println("before");
    }

    @After("pt()")
    public void after() {
        System.out.println("after");
    }

    @AfterReturning("pt()")
    public void afterReturning() {
        System.out.println("afterReturning");
    }

    @AfterThrowing("pt()")
    public void afterThrowing() {
        System.out.println("afterThrowing");
    }

    @Around("pt()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("around before");
        //对原始方法的调用
        Object ret = pjp.proceed();
        System.out.println("around after");
        return ret;
    }
}

注解开发AOP注意事项

1.切入点最终体现为一个方法,无参无返回值,无实 际方法体内容,但不能是抽象方法

2.引用切入点时必须使用方法调用名称,方法后面的()不能省略

3.切面类中定义的切入点只能在当前类中使用,如果想引用其他类中定义的切入点使用“类名.方法名()”引用  (可以抽出一个类来配置所有的切入点

4.可以在通知类型注解后添加参数,实现XML配置中的属性,例如after-returning后的returning属性

AOP注解开发通知执行顺序控制

1.AOP使用XML配置情况下,通知的执行顺序由配置顺序决定,在注解情况下由于不存在配置顺序的概念的概念,参照通知所配置的方法名字符串对应的编码值顺序,可以简单理解为字母排序

  • 同一个通知类中,相同通知类型以方法名排序为准

  • 不同通知类中,以类名排序为准

  • 使用@Order注解通过变更bean的加载顺序改变通知的加载顺序

2.企业开发经验

  • 通知方法名由3部分组成,分别是前缀、顺序编码、功能描述

  • 前缀为固定字符串,例如baidu、itheima等,无实际意义

  • 顺序编码为6位以内的整数,通常3位即可,不足位补0

  • 功能描述为该方法对应的实际通知功能,例如exception、strLenCheck

    • 制通知执行顺序使用顺序编码控制,使用时做一定空间预留

    • 003使用,006使用,预留001、002、004、005、007、008

    • 使用时从中段开始使用,方便后期做前置追加或后置追加

    • 最终顺序以运行顺序为准,以测试结果为准,不以设定规则为准

AOP注解驱动

  • 名称:@EnableAspectJAutoProxy

  • 类型:注解

  • 位置:Spring注解配置类定义上方

  • 作用:设置当前类开启AOP注解驱动的支持,加载AOP注解

  • 格式:

@Configuration
@ComponentScan("com.itheima")
@EnableAspectJAutoProxy
public class SpringConfig {
}

posted @   金鳞踏雨  阅读(42)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示